Skip to content

Commit 4f023d1

Browse files
committed
Implement simplified metacom client
Refs: #152 PR-URL: #161
1 parent 5013337 commit 4f023d1

File tree

4 files changed

+71
-38
lines changed

4 files changed

+71
-38
lines changed

static/.eslintrc.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"parserOptions": {
3+
"sourceType": "module"
4+
}
5+
}

static/console.js

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,8 @@
1-
'use strict';
1+
import { Metacom } from './metacom.js';
22

3-
// API Builder
4-
5-
const socket = new WebSocket('wss://' + location.host);
6-
7-
const buildAPI = (methods, socket = null) => {
8-
const api = {};
9-
for (const method of methods) {
10-
api[method] = (args = {}) => new Promise((resolve, reject) => {
11-
if (socket) {
12-
socket.send(JSON.stringify({ method, args }));
13-
socket.onmessage = event => {
14-
const obj = JSON.parse(event.data);
15-
if (obj.result !== 'error') resolve(obj);
16-
else reject(new Error(`Status Code: ${obj.reason}`));
17-
};
18-
} else {
19-
fetch(`/api/${method}`, {
20-
method: 'POST',
21-
headers: { 'Content-Type': 'application/json' },
22-
body: JSON.stringify(args),
23-
}).then(res => {
24-
const { status } = res;
25-
if (status === 200) resolve(res.json());
26-
else reject(new Error(`Status Code: ${status}`));
27-
});
28-
}
29-
});
30-
}
31-
return api;
32-
};
33-
34-
let api = buildAPI(['status', 'signIn', 'introspection'], socket);
35-
36-
// Console Emulation
3+
const metacom = new Metacom(location.host);
4+
const { api } = metacom;
5+
window.api = api;
376

387
const ALPHA_UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
398
const ALPHA_LOWER = 'abcdefghijklmnopqrstuvwxyz';
@@ -276,12 +245,12 @@ function commandLoop() {
276245

277246
const signIn = async () => {
278247
try {
248+
await metacom.load('status', 'signIn', 'introspection');
279249
await api.status();
280250
} catch (err) {
281251
await api.signIn({ login: 'marcus', password: 'marcus' });
282252
}
283-
const methods = await api.introspection();
284-
api = buildAPI(methods, socket);
253+
await metacom.load('example');
285254
};
286255

287256
window.addEventListener('load', () => {

static/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<meta charset="utf-8">
66
<link rel="manifest" href="/manifest.json">
77
<link rel="stylesheet" href="/console.css">
8-
<script src="console.js"></script>
8+
<script src="console.js" type="module"></script>
99
<meta name="HandheldFriendly" content="true" />
1010
<meta name="apple-mobile-web-app-capable" content="yes" />
1111
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

static/metacom.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
export class Metacom {
2+
constructor(host) {
3+
this.socket = new WebSocket('wss://' + host);
4+
this.api = {};
5+
this.callId = 0;
6+
this.calls = new Map();
7+
this.socket.onmessage = ({ data }) => {
8+
try {
9+
const packet = JSON.parse(data);
10+
const { callback, event } = packet;
11+
const callId = callback || event;
12+
const [resolve, reject] = this.calls.get(callId);
13+
if (packet.error) {
14+
const { code, message } = packet.error;
15+
const error = new Error(message);
16+
error.code = code;
17+
reject(error);
18+
return;
19+
}
20+
resolve(packet.result);
21+
} catch (err) {
22+
console.error(err);
23+
}
24+
};
25+
}
26+
27+
async load(...methods) {
28+
for (const methodName of methods) {
29+
this.api[methodName] = this.socketCall(methodName);
30+
}
31+
}
32+
33+
httpCall(methodName) {
34+
return (args = {}) => {
35+
const callId = ++this.callId;
36+
const packet = { call: callId, [methodName]: args };
37+
return fetch('/api', {
38+
method: 'POST',
39+
headers: { 'Content-Type': 'application/json' },
40+
body: JSON.stringify(packet),
41+
}).then(res => {
42+
const { status } = res;
43+
if (status === 200) return res.json().then(({ result }) => result);
44+
throw new Error(`Status Code: ${status}`);
45+
});
46+
};
47+
}
48+
49+
socketCall(methodName) {
50+
return (args = {}) => {
51+
const callId = ++this.callId;
52+
return new Promise((resolve, reject) => {
53+
this.calls.set(callId, [resolve, reject]);
54+
const packet = { call: callId, [methodName]: args };
55+
this.socket.send(JSON.stringify(packet));
56+
});
57+
};
58+
}
59+
}

0 commit comments

Comments
 (0)