@remix_labs/machine-starter 2.3256.0-dev → 2.3260.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 CHANGED
@@ -2,34 +2,61 @@ import { GROOVEBOX_BUILD } from "./groovebox_build.js";
2
2
  import { nanoid } from "nanoid";
3
3
  import { MixcoreTauri, filterFFINames } from "./mixcore.lib.mjs";
4
4
 
5
+ const DEBUG_STATE = 4;
6
+
7
+ let last_hub = null;
8
+
5
9
  let workers = {};
6
10
  let children = {};
7
11
  let ffiLoops = {};
12
+ let blobs = {};
13
+ let blobsLoops = {};
8
14
 
9
15
  function terminateAll() {
10
- console.log("[groovebox-starter] terminate all VMs");
16
+ console.log("[machine-starter] terminate all VMs");
11
17
  for (let [vmID, worker] of Object.entries(workers)) {
12
18
  worker.terminate();
13
19
  };
20
+ for (let [vmID, blist] of Object.entries(blobs)) {
21
+ for (let blob_url of blist) {
22
+ console.log("[machine-starter] revoke ", blob_url);
23
+ URL.revokeObjectURL(blob_url);
24
+ }
25
+ };
14
26
  for (let ffiLoop of Object.values(ffiLoops)) {
15
27
  ffiLoop.terminate();
16
28
  }
29
+ for (let blobsLoop of Object.values(blobsLoops)) {
30
+ blobsLoop.terminate();
31
+ }
17
32
  workers = {};
18
33
  children = {};
19
34
  ffiLoops = {};
35
+ blobs = {};
36
+ blobsLoops = {};
20
37
  }
21
38
 
22
39
  function terminateVM(vmID) {
23
- console.log("[groovebox-starter] terminate VM", vmID);
40
+ console.log("[machine-starter] terminate VM", vmID);
24
41
  let worker = workers[vmID];
25
42
  if (worker) {
26
43
  let vmChildren = children[vmID];
44
+ let blobList = blobs[vmID] || [];
27
45
  let ffiLoop = ffiLoops[vmID];
46
+ let blobsLoop = blobsLoops[vmID];
28
47
  delete workers[vmID];
29
48
  delete children[vmID];
30
49
  delete ffiLoops[vmID];
50
+ delete blobsLoops[vmID];
31
51
  worker.terminate();
32
52
  ffiLoop.terminate();
53
+ if (blobsLoop) {
54
+ blobsLoop.terminate();
55
+ }
56
+ for (let blob_url of blobList) {
57
+ console.log("[machine-starter] revoke ", blob_url);
58
+ URL.revokeObjectURL(blob_url);
59
+ };
33
60
  if (vmChildren) {
34
61
  for (let subID of vmChildren) {
35
62
  terminateVM(subID)
@@ -40,19 +67,37 @@ function terminateVM(vmID) {
40
67
 
41
68
  if (globalThis.Process) {
42
69
  Process.on("exit", () => {
43
- console.log("terminating machine workers");
44
70
  terminateAll()
45
71
  })
46
72
  };
47
73
 
48
- let initialMask = 1024; // default for web
74
+ let initialMask = 0;
75
+ const logMaskTopic = "/logMask";
76
+
77
+ globalThis.MixExplain = (_ => {
78
+ console.debug("Debug levels (call MixSetMask to change):");
79
+ console.debug("DEBUG_MEMORY 1");
80
+ console.debug("DEBUG_SCHEDULER 2");
81
+ console.debug("DEBUG_STATE 4");
82
+ console.debug("DEBUG_STACK 8");
83
+ console.debug("DEBUG_LOOP 16");
84
+ console.debug("DEBUG_MEMORY_OG 32");
85
+ console.debug("DEBUG_GC 64");
86
+ console.debug("DEBUG_INTERPRETER 128");
87
+ console.debug("DEBUG_MIXERROR 256");
88
+ console.debug("DEBUG_MESSAGES 1024");
89
+ console.debug("DEBUG_QUEUES 2048");
90
+ console.debug("DEBUG_OUTPUT 4096");
91
+ console.debug("DEBUG_COMPILER 8192");
92
+ });
49
93
 
50
94
  globalThis.MixSetMask = (m => {
51
95
  initialMask = m;
52
- for (let [vmID, worker] of Object.entries(workers)) {
53
- worker.postMessage({ "_rmx_type": "msg_vm_logMask",
54
- "mask": m
55
- })
96
+ if (last_hub) {
97
+ last_hub.newChannel().then(channel => {
98
+ let msg = channel.newJSONMessage("_rmx_setLogMask", "MixSetMask", { mask: m });
99
+ channel.set(logMaskTopic, msg)
100
+ });
56
101
  }
57
102
  });
58
103
 
@@ -68,7 +113,10 @@ function StartWASM(hub, baseURL, org, workspace, vmID, user, token, noOutputViaM
68
113
  }
69
114
 
70
115
  async function StartWASM2(hub, config) {
71
- console.log("[groovebox-starter] start VM", GROOVEBOX_BUILD, config.vmID, config.mixcore);
116
+ if (!last_hub) {
117
+ console.log("[machine-starter] Call MixExplain() for explaining debug levels, and MixSetMask(m) for changing these")
118
+ };
119
+ last_hub = hub;
72
120
  let channel = await hub.newChannel();
73
121
  // injected by either index.js or node.js
74
122
  let worker = globalThis.GetMachineWASMWorker();
@@ -78,7 +126,7 @@ async function StartWASM2(hub, config) {
78
126
  let localFFIs = config.localFFIs || {};
79
127
  let mixcoreFFIs = await getMixcoreFFIs(config.mixcore);
80
128
  if (mixcoreFFIs) {
81
- console.log("[groovebox-starter] mixcore FFIs", Object.keys(mixcoreFFIs));
129
+ console.log("[machine-starter] mixcore FFIs", Object.keys(mixcoreFFIs));
82
130
  // merge the ffis and store them back into the config so sub vms also get them
83
131
  config.localFFIs = Object.assign(localFFIs, mixcoreFFIs);
84
132
  // delete the mixcore config to avoid being handled further by the worker
@@ -100,7 +148,23 @@ async function StartWASM2(hub, config) {
100
148
  localFFIfuns["$vm_start"] = ffi_vm_start;
101
149
  localFFIkind["$vm_stop"] = vm_kind;
102
150
  localFFIfuns["$vm_stop"] = ffi_vm_stop;
151
+ let mixrtCode = config.mixrtCode;
152
+ if (typeof(mixrtCode) == "string" && mixrtCode.startsWith("remix://")) {
153
+ // for the desktop only: precompile the mixrt module to get faster
154
+ // startup times
155
+ if (globalThis.mixrtCodeModule && globalThis.mixrtCodeURL == mixrtCode) {
156
+ console.log("[machine-starter] reusing mixrt");
157
+ mixrtCode = globalThis.mixrtCodeModule;
158
+ } else {
159
+ let url = mixrtCode;
160
+ console.log("[machine-starter] pre-compiling mixrt");
161
+ mixrtCode = await WebAssembly.compileStreaming(fetch(url));
162
+ globalThis.mixrtCodeURL = url;
163
+ globalThis.mixrtCodeModule = mixrtCode;
164
+ }
165
+ };
103
166
  ffiLoops[config.vmID] = setupLocalFFIs(hub, config, localFFIfuns);
167
+ blobsLoops[config.vmID] = setupBlobs(hub, config);
104
168
  let config_msg =
105
169
  { "_rmx_type": "msg_vm_configure",
106
170
  "baseURL": config.baseURL,
@@ -118,7 +182,7 @@ async function StartWASM2(hub, config) {
118
182
  "interceptFFI": config.interceptFFI,
119
183
  "interceptDynloadFFI": config.interceptDynloadFFI,
120
184
  "mixcore": config.mixcore,
121
- "mixrtCode": config.mixrtCode
185
+ "mixrtCode": mixrtCode
122
186
  // can be: base64-encoded string, Uint8Array, or a URL as string
123
187
  // (http, https, data)
124
188
  };
@@ -128,6 +192,7 @@ async function StartWASM2(hub, config) {
128
192
 
129
193
  async function ffi_vm_start(conn, args) {
130
194
  let vm_id = "embedded." + nanoid();
195
+ console.log("[machine-starter] starting VM: ", vm_id);
131
196
  let config = {};
132
197
  for (const [k, v] of Object.entries(conn.config)) {
133
198
  config[k] = v;
@@ -290,14 +355,15 @@ async function localFFIsMessageLoop(hub, config, localFFIs, terminate) {
290
355
  terminate.then(() => ({terminated: true})),
291
356
  ]);
292
357
  if (terminated) {
293
- console.log("[groovebox-starter] terminate FFI loop", vmID);
358
+ // console.log("[machine-starter] terminate FFI loop", vmID);
294
359
  return;
295
360
  }
296
361
  let name = msg.payload.name;
297
362
  let call_id = msg.payload.call_id;
298
363
  let args = decode(msg.payload.args);
299
364
  let fun = localFFIs[name];
300
- console.log("[groovebox-starter] local FFI call", vmID, call_id, name);
365
+ if (initialMask & DEBUG_STATE)
366
+ console.debug("[groovebox-starter] local FFI call", vmID, call_id, name);
301
367
  try {
302
368
  if (!fun) throw new Error("No such local FFI in groovebox starter: " + name);
303
369
  let connector =
@@ -310,18 +376,57 @@ async function localFFIsMessageLoop(hub, config, localFFIs, terminate) {
310
376
  let r = fun instanceof Function ? fun(connector, args) : fun.run(connector, args);
311
377
  if (r instanceof Promise) {
312
378
  // r.catch(_ => null); // prevent "unhandled rejection"
379
+ if (initialMask & DEBUG_STATE)
380
+ console.debug("[groovebox-starter] running FFI call asynchronously", vmID, call_id, name);
313
381
  await comm.later(call_id);
314
382
  let value = await r;
383
+ if (initialMask & DEBUG_STATE)
384
+ console.debug("[groovebox-starter] async FFI call returned", vmID, call_id, name);
315
385
  await comm.returnOrFail(fun, call_id, value);
316
386
  } else {
387
+ if (initialMask & DEBUG_STATE)
388
+ console.debug("[groovebox-starter] sync FFI call returned", vmID, call_id, name);
317
389
  await comm.returnOrFail(fun, call_id, r);
318
390
  }
319
391
  } catch (reason) {
392
+ if (initialMask & DEBUG_STATE) {
393
+ console.debug("[groovebox-starter] FFI call exception", vmID, call_id, name);
394
+ console.debug("[groovebox-starter] exception", reason);
395
+ };
320
396
  await comm.error(call_id, reason.message, reason.stack);
321
397
  }
322
398
  }
323
399
  }
324
400
 
401
+ function setupBlobs(hub, config) {
402
+ let vmID = config.vmID;
403
+ let terminate = Promise.withResolvers();
404
+ blobsMessageLoop(hub, config, terminate.promise); // don't wait
405
+ return {terminate: terminate.resolve};
406
+ }
407
+ async function blobsMessageLoop(hub, config, terminate) {
408
+ let vmID = config.vmID;
409
+ let channel = await hub.newChannel();
410
+ let comm = new FFIComm(vmID, hub, channel);
411
+ let sub = await channel.subscribe("/local/" + vmID + "/blobs");
412
+ while (true) {
413
+ let {msg, terminated} = await Promise.race([
414
+ sub.next().then((msg) => ({msg})),
415
+ terminate.then(() => ({terminated: true})),
416
+ ]);
417
+ if (terminated) {
418
+ // console.log("[machine-starter] terminate blobs loop", vmID);
419
+ return;
420
+ }
421
+ let name = msg.payload.name;
422
+ let url = msg.payload.url;
423
+ let blobList = blobs[vmID];
424
+ if (!blobList) blobList = [];
425
+ blobList.push(url);
426
+ blobs[vmID] = blobList;
427
+ }
428
+ }
429
+
325
430
  class FFIComm {
326
431
  constructor(vmID, hub, channel) {
327
432
  this.vmID = vmID;
@@ -388,6 +493,7 @@ async function getMixcoreFFIs(config) {
388
493
  mixcore = await MixcoreTauri.create(config.workspace, config.app);
389
494
  break;
390
495
  default:
496
+ console.warn("[machine-starter] not going to configure mixcore - kind: ", config?.kind);
391
497
  return;
392
498
  }
393
499
 
@@ -1,2 +1,2 @@
1
- var GROOVEBOX_BUILD = "3630";
1
+ var GROOVEBOX_BUILD = "3260";
2
2
  export { GROOVEBOX_BUILD }
package/index.js CHANGED
@@ -1,12 +1,10 @@
1
- function workerify(code) {
2
- let blob = new Blob([code], {type: 'application/javascript'});
3
- return new Worker(URL.createObjectURL(blob));
4
- }
5
-
6
1
  import MachineWASMWorker from './machine-wasm.worker.mjs'
7
2
 
3
+ const blob = new Blob([MachineWASMWorker], {type: 'application/javascript'});
4
+ const url = URL.createObjectURL(blob);
5
+
8
6
  function GetMachineWASMWorker() {
9
- return workerify(MachineWASMWorker);
7
+ return new Worker(url);
10
8
  }
11
9
 
12
10
  globalThis.GetMachineWASMWorker = GetMachineWASMWorker;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remix_labs/machine-starter",
3
- "version": "2.3256.0-dev",
3
+ "version": "2.3260.0-dev",
4
4
  "description": "start the groove",
5
5
  "main": "node.js",
6
6
  "browser": "index.js",
@@ -11,9 +11,11 @@
11
11
  "author": "Remixlabs staff",
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
- "@remix_labs/hub-client": "2.3256.0-dev",
14
+ "@remix_labs/hub-client": "2.3260.0-dev",
15
15
  "nanoid": "^5.0.2",
16
16
  "web-worker": "^1.2.0"
17
17
  },
18
- "repository": "https://github.com/remixlabs/groovebox.git"
18
+ "repository": {
19
+ "url": "git+https://github.com/remixlabs/groovebox.git"
20
+ }
19
21
  }
package/package_pub.json CHANGED
@@ -15,5 +15,7 @@
15
15
  "nanoid": "^5.0.2",
16
16
  "web-worker": "^1.2.0"
17
17
  },
18
- "repository": "https://github.com/remixlabs/groovebox.git"
18
+ "repository": {
19
+ "url": "git+https://github.com/remixlabs/groovebox.git"
20
+ }
19
21
  }