@remix_labs/machine-starter 2.1995.0-dev → 2.1999.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common.js +91 -33
- package/groovebox_build.js +1 -1
- package/index.js +0 -1
- package/machine-wasm.worker.js +1 -1
- package/package.json +3 -3
- package/package_pub.json +1 -1
- package/start.js +29 -11
package/common.js
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
import { GROOVEBOX_BUILD } from "./groovebox_build.js";
|
|
2
|
+
import { nanoid } from "nanoid";
|
|
2
3
|
|
|
3
|
-
let
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
let workers = {};
|
|
5
|
+
let parents = {};
|
|
6
|
+
|
|
7
|
+
function terminateAll() {
|
|
8
|
+
for (let [vmID, worker] of Object.entries(workers)) {
|
|
9
|
+
worker.terminate();
|
|
10
|
+
};
|
|
11
|
+
workers = {};
|
|
12
|
+
parents = {};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function terminateVM(vmID) {
|
|
16
|
+
let worker = workers[vmID];
|
|
17
|
+
if (worker) {
|
|
18
|
+
delete workers[vmID];
|
|
19
|
+
delete parents[vmID];
|
|
20
|
+
worker.terminate();
|
|
21
|
+
for (let [subID, parentID] of Object.entries(parents)) {
|
|
22
|
+
terminateVM(subID);
|
|
23
|
+
};
|
|
10
24
|
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (globalThis.Process) {
|
|
28
|
+
Process.on("exit", () => {
|
|
29
|
+
console.log("terminating machine workers");
|
|
30
|
+
terminateAll()
|
|
31
|
+
})
|
|
11
32
|
};
|
|
12
33
|
|
|
13
34
|
let initialMask = 64 + 1024; // default for web
|
|
35
|
+
|
|
14
36
|
globalThis.MixSetMask = (m => {
|
|
15
37
|
initialMask = m;
|
|
38
|
+
for (let [vmID, worker] of Object.entries(workers)) {
|
|
39
|
+
worker.postMessage({ "_rmx_type": "msg_vm_logMask",
|
|
40
|
+
"mask": m
|
|
41
|
+
})
|
|
42
|
+
}
|
|
16
43
|
});
|
|
17
44
|
|
|
18
45
|
function StartWASM(hub, baseURL, org, workspace, vmID, user, token, noOutputViaMQTT) {
|
|
@@ -31,16 +58,24 @@ function StartWASM2(hub, config) {
|
|
|
31
58
|
return hub.newChannel().then(channel => {
|
|
32
59
|
// injected by either index.js or node.js
|
|
33
60
|
let worker = globalThis.GetMachineWASMWorker();
|
|
34
|
-
|
|
61
|
+
workers[config.vmID] = worker;
|
|
62
|
+
let localFFIkind = {};
|
|
63
|
+
let localFFIfuns = {};
|
|
35
64
|
if (config.localFFIs) {
|
|
36
65
|
for (const [k, v] of Object.entries(config.localFFIs)) {
|
|
66
|
+
localFFIfuns[k] = {...v};
|
|
37
67
|
if (v.isRaw && (v.canFail || v.useJsonDecoder)) {
|
|
38
68
|
console.error("A raw, local FFI must neither be failing nor use the JSON decoder: " + k);
|
|
39
69
|
} else {
|
|
40
|
-
|
|
41
|
-
delete
|
|
70
|
+
localFFIkind[k] = {...v};
|
|
71
|
+
delete localFFIkind[k].run;
|
|
42
72
|
}
|
|
43
|
-
}
|
|
73
|
+
};
|
|
74
|
+
let vm_kind = { isRaw:false, canFail:false, useJsonDecoder:false};
|
|
75
|
+
localFFIkind["$vm_start"] = vm_kind;
|
|
76
|
+
localFFIfuns["$vm_start"] = ffi_vm_start;
|
|
77
|
+
localFFIkind["$vm_stop"] = vm_kind;
|
|
78
|
+
localFFIfuns["$vm_stop"] = ffi_vm_stop;
|
|
44
79
|
}
|
|
45
80
|
let config_msg =
|
|
46
81
|
{ "_rmx_type": "msg_vm_configure",
|
|
@@ -54,24 +89,43 @@ function StartWASM2(hub, config) {
|
|
|
54
89
|
"outputViaMQTT": !(config.noOutputViaMQTT),
|
|
55
90
|
"machType": config.machType,
|
|
56
91
|
"debugMask": initialMask,
|
|
57
|
-
"localFFIs":
|
|
92
|
+
"localFFIs": localFFIkind,
|
|
58
93
|
"allowInsecureHttp": globalThis.GROOVEBOX_ALLOW_INSECURE_HTTP,
|
|
59
94
|
"interceptFFI": config.interceptFFI,
|
|
60
95
|
"interceptDynloadFFI": config.interceptDynloadFFI,
|
|
61
96
|
};
|
|
62
97
|
worker.postMessage(config_msg, [ channel.port ]);
|
|
63
|
-
terminate(() => worker.terminate());
|
|
64
|
-
globalThis.MixSetMask = (m => {
|
|
65
|
-
worker.postMessage({ "_rmx_type": "msg_vm_logMask",
|
|
66
|
-
"mask": m
|
|
67
|
-
})
|
|
68
|
-
});
|
|
69
98
|
if (config.localFFIs)
|
|
70
|
-
setupLocalFFIs(hub, config); // don't await!
|
|
99
|
+
setupLocalFFIs(hub, config, localFFIfuns); // don't await!
|
|
71
100
|
return worker;
|
|
72
101
|
})
|
|
73
102
|
}
|
|
74
103
|
|
|
104
|
+
async function ffi_vm_start(conn, args) {
|
|
105
|
+
let vm_id = "embedded." + nanoid();
|
|
106
|
+
let config = {};
|
|
107
|
+
for (const [k, v] of Object.entries(conn.config)) {
|
|
108
|
+
config[k] = v;
|
|
109
|
+
}
|
|
110
|
+
config["vmID"] = vm_id;
|
|
111
|
+
parents[vm_id] = conn.config.vmID;
|
|
112
|
+
let arg_config = args[0];
|
|
113
|
+
if (arg_config.interceptFFI !== undefined)
|
|
114
|
+
config["interceptFFI"] = arg_config.interceptFFI;
|
|
115
|
+
if (arg_config.interceptDynloadFFI !== undefined)
|
|
116
|
+
config["interceptDynloadFFI"] = arg_config.interceptDynloadFFI;
|
|
117
|
+
let worker = await StartWASM2(conn.hub, config);
|
|
118
|
+
return vm_id;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function ffi_vm_stop(conn, args) {
|
|
122
|
+
let vm_id = args[0];
|
|
123
|
+
let worker = workers[vm_id];
|
|
124
|
+
if (!worker) throw new Error("no such VM: " + vm_id);
|
|
125
|
+
terminateVM(vm_id);
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
|
|
75
129
|
class Token {
|
|
76
130
|
constructor(data, enabled, extras) {
|
|
77
131
|
// data: must be an Uint8Array
|
|
@@ -187,13 +241,13 @@ function decode(val) {
|
|
|
187
241
|
}
|
|
188
242
|
}
|
|
189
243
|
|
|
190
|
-
async function setupLocalFFIs(hub, config) {
|
|
244
|
+
async function setupLocalFFIs(hub, config, localFFIs) {
|
|
245
|
+
let vmID = config.vmID;
|
|
191
246
|
let channel = await hub.newChannel();
|
|
192
|
-
let comm = new FFIComm(hub, channel);
|
|
193
|
-
|
|
194
|
-
await channel.
|
|
195
|
-
await channel.
|
|
196
|
-
let sub = await channel.subscribe("/local/ffi/call");
|
|
247
|
+
let comm = new FFIComm(vmID, hub, channel);
|
|
248
|
+
await channel.setLocalSubTopic("/local/" + vmID);
|
|
249
|
+
await channel.setLocalPubTopic("/local/" + vmID);
|
|
250
|
+
let sub = await channel.subscribe("/local/" + vmID + "/ffi/call");
|
|
197
251
|
while (true) {
|
|
198
252
|
let msg = await sub.next();
|
|
199
253
|
let name = msg.payload.name;
|
|
@@ -207,14 +261,15 @@ async function setupLocalFFIs(hub, config) {
|
|
|
207
261
|
{ call_id: call_id,
|
|
208
262
|
hub: hub,
|
|
209
263
|
channel: channel,
|
|
264
|
+
config: config,
|
|
210
265
|
state: config.state,
|
|
211
266
|
};
|
|
212
267
|
let r = fun instanceof Function ? fun(connector, args) : fun.run(connector, args);
|
|
213
268
|
if (r instanceof Promise) {
|
|
269
|
+
// r.catch(_ => null); // prevent "unhandled rejection"
|
|
214
270
|
await comm.later(call_id);
|
|
215
|
-
r
|
|
216
|
-
|
|
217
|
-
(reason) => comm.error(call_id, reason.message, reason.stack));
|
|
271
|
+
let value = await r;
|
|
272
|
+
await comm.returnOrFail(fun, call_id, value);
|
|
218
273
|
} else {
|
|
219
274
|
await comm.returnOrFail(fun, call_id, r);
|
|
220
275
|
}
|
|
@@ -225,7 +280,8 @@ async function setupLocalFFIs(hub, config) {
|
|
|
225
280
|
}
|
|
226
281
|
|
|
227
282
|
class FFIComm {
|
|
228
|
-
constructor(hub, channel) {
|
|
283
|
+
constructor(vmID, hub, channel) {
|
|
284
|
+
this.vmID = vmID;
|
|
229
285
|
this.hub = hub;
|
|
230
286
|
this.channel = channel;
|
|
231
287
|
}
|
|
@@ -234,7 +290,7 @@ class FFIComm {
|
|
|
234
290
|
{ call_id: call_id,
|
|
235
291
|
};
|
|
236
292
|
let response = this.hub.newLocalMessage("msg_ffi_later", "starter", r_payload);
|
|
237
|
-
return this.channel.publish("/local/ffi/return", response, false);
|
|
293
|
+
return this.channel.publish("/local/" + this.vmID + "/ffi/return", response, false);
|
|
238
294
|
}
|
|
239
295
|
return_(fun, call_id, result) {
|
|
240
296
|
let r_payload =
|
|
@@ -242,7 +298,7 @@ class FFIComm {
|
|
|
242
298
|
value: fun.useJsonDecoder ? result : encode(result)
|
|
243
299
|
};
|
|
244
300
|
let response = this.hub.newLocalMessage("msg_ffi_return", "starter", r_payload);
|
|
245
|
-
return this.channel.publish("/local/ffi/return", response, false);
|
|
301
|
+
return this.channel.publish("/local/" + this.vmID + "/ffi/return", response, false);
|
|
246
302
|
}
|
|
247
303
|
error(call_id, message, stack) {
|
|
248
304
|
let r_payload =
|
|
@@ -251,7 +307,7 @@ class FFIComm {
|
|
|
251
307
|
stack: stack === undefined ? [] : stack,
|
|
252
308
|
};
|
|
253
309
|
let response = this.hub.newLocalMessage("msg_ffi_error", "starter", r_payload);
|
|
254
|
-
this.channel.publish("/local/ffi/return", response, false);
|
|
310
|
+
this.channel.publish("/local/" + this.vmID + "/ffi/return", response, false);
|
|
255
311
|
}
|
|
256
312
|
returnOrFail(fun, call_id, result) {
|
|
257
313
|
if (fun.canFail) {
|
|
@@ -281,4 +337,6 @@ class FFIComm {
|
|
|
281
337
|
|
|
282
338
|
// use worker.terminate() to shut a worker down!
|
|
283
339
|
|
|
284
|
-
export { StartWASM, StartWASM2,
|
|
340
|
+
export { StartWASM, StartWASM2, terminateAll, terminateVM,
|
|
341
|
+
Token, Case, Opaque
|
|
342
|
+
}
|
package/groovebox_build.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var GROOVEBOX_BUILD = "
|
|
1
|
+
var GROOVEBOX_BUILD = "2129";
|
|
2
2
|
export { GROOVEBOX_BUILD }
|
package/index.js
CHANGED