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