@ai-ecoverse/slicc-kernel 1.129.0 → 1.130.1

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.
@@ -254,7 +254,7 @@ var init_cpu_clock = __esm({
254
254
  });
255
255
 
256
256
  // src/kernel/protocol.ts
257
- var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_PROCESS_READY, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS;
257
+ var WASM_PROCESS_INIT, WASM_PROCESS_EXIT, WASM_PROCESS_ERROR, WASM_PROCESS_READY, WASM_THREAD_SPAWN, WASM_THREAD_INIT, WASM_THREAD_EXIT, WASM_MAX_THREADS, WASM_DEFAULT_THREADS, JS_THREAD_SPAWN, JS_THREAD_INIT, JS_THREAD_EXIT, JS_THREAD_NO_MEMORY, JS_THREAD_CRASHED;
258
258
  var init_protocol = __esm({
259
259
  "src/kernel/protocol.ts"() {
260
260
  "use strict";
@@ -267,6 +267,11 @@ var init_protocol = __esm({
267
267
  WASM_THREAD_EXIT = "wasm-thread-exit";
268
268
  WASM_MAX_THREADS = 256;
269
269
  WASM_DEFAULT_THREADS = 64;
270
+ JS_THREAD_SPAWN = "js-thread-spawn";
271
+ JS_THREAD_INIT = "js-thread-init";
272
+ JS_THREAD_EXIT = "js-thread-exit";
273
+ JS_THREAD_NO_MEMORY = 256;
274
+ JS_THREAD_CRASHED = 257;
270
275
  }
271
276
  });
272
277
 
@@ -1797,9 +1802,9 @@ function createNodeOps(h) {
1797
1802
  node.live.stat = void 0;
1798
1803
  },
1799
1804
  lookup(parent, name2) {
1800
- const listed = parent.live.listed?.get(name2);
1805
+ const listed2 = parent.live.listed?.get(name2);
1801
1806
  parent.live.listed?.delete(name2);
1802
- const st = listed ?? call2(() => bridgeOf(parent).lstat(childPath(parent, name2)));
1807
+ const st = listed2 ?? call2(() => bridgeOf(parent).lstat(childPath(parent, name2)));
1803
1808
  return makeNode(parent, name2, st);
1804
1809
  },
1805
1810
  mknod(parent, name2, mode) {
@@ -1873,10 +1878,10 @@ function createNodeOps(h) {
1873
1878
  call2(() => bridgeOf(parent).rmdir(childPath(parent, name2)));
1874
1879
  },
1875
1880
  readdir(node) {
1876
- const listed = call2(() => bridgeOf(node).readdirStat(liveNodePath(node)));
1881
+ const listed2 = call2(() => bridgeOf(node).readdirStat(liveNodePath(node)));
1877
1882
  node.live.listed = /* @__PURE__ */ new Map();
1878
- for (const [name2, st] of listed) if (st) node.live.listed.set(name2, st);
1879
- return [".", "..", ...listed.map(([name2]) => name2)];
1883
+ for (const [name2, st] of listed2) if (st) node.live.listed.set(name2, st);
1884
+ return [".", "..", ...listed2.map(([name2]) => name2)];
1880
1885
  },
1881
1886
  symlink(parent, newName, target) {
1882
1887
  parent.live.listed = void 0;
@@ -2659,7 +2664,7 @@ var KERNEL_VERSION, OS_RELEASE;
2659
2664
  var init_version = __esm({
2660
2665
  "src/version.ts"() {
2661
2666
  "use strict";
2662
- KERNEL_VERSION = true ? "1.129.0" : "0.0.0-dev";
2667
+ KERNEL_VERSION = true ? "1.130.1" : "0.0.0-dev";
2663
2668
  OS_RELEASE = "6.0.0-slicc";
2664
2669
  }
2665
2670
  });
@@ -5629,7 +5634,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
5629
5634
  return dir;
5630
5635
  };
5631
5636
  const scans = /* @__PURE__ */ new Map();
5632
- const listed = (target) => {
5637
+ const listed2 = (target) => {
5633
5638
  let found = false;
5634
5639
  for (const [stream, pids] of scans) {
5635
5640
  if (Fs.streams && Fs.streams[stream.fd ?? -1] !== stream) scans.delete(stream);
@@ -5650,7 +5655,7 @@ function useProcfs(Fs, sys, pid, memory = memorySource()) {
5650
5655
  ...procOps2,
5651
5656
  lookup: (parent, name2) => {
5652
5657
  if (/^[1-9]\d*$/.test(name2)) {
5653
- if (!infoOf(Number(name2)) && !listed(Number(name2))) throw error();
5658
+ if (!infoOf(Number(name2)) && !listed2(Number(name2))) throw error();
5654
5659
  return pidDir(name2, Number(name2));
5655
5660
  }
5656
5661
  if (name2 === "mounts") return file(parent, name2, () => mountTable(sys.mountList?.() ?? []));
@@ -6720,35 +6725,64 @@ function copying(bridge, mutating, entry) {
6720
6725
  copy: (from, to, mode, exclusive) => mutating(() => copy2.call(bridge, from, to, mode, exclusive), ...entry(to))
6721
6726
  };
6722
6727
  }
6728
+ function listed({ cache, seen, filled }, p, list, gen, asked) {
6729
+ const base = p === "/" ? "" : p;
6730
+ for (const [name2, st] of list) {
6731
+ if (!st) continue;
6732
+ filled.set(st, asked);
6733
+ const at = `${base}/${name2}`;
6734
+ cache.put(cache.lstats, at, st);
6735
+ if (gen !== void 0) seen.saw(cache.lstats, at, gen);
6736
+ if (st.isSymbolicLink) continue;
6737
+ cache.put(cache.stats, at, st);
6738
+ if (gen !== void 0) seen.saw(cache.stats, at, gen);
6739
+ }
6740
+ }
6741
+ function fetched({
6742
+ view,
6743
+ now,
6744
+ seen,
6745
+ filled,
6746
+ cache
6747
+ }, map, path, get) {
6748
+ const gen = view?.now();
6749
+ const asked = now();
6750
+ let hit;
6751
+ try {
6752
+ hit = get();
6753
+ if (gen !== void 0) seen.saw(map, path, gen);
6754
+ } catch (e) {
6755
+ hit = { error: e, until: asked + MISS_TTL_MS, ...gen !== void 0 ? { gen } : {} };
6756
+ }
6757
+ filled.set(hit, asked);
6758
+ cache.put(map, path, hit);
6759
+ return hit;
6760
+ }
6723
6761
  function cachingBridge(bridge, now = () => performance.now(), shared) {
6724
6762
  const blind = shared !== void 0 && shared.length * 4 < SHARED_IDS_BYTES;
6725
6763
  const cache = new StatCache(blind ? void 0 : shared);
6726
6764
  const { stats, lstats } = cache;
6727
6765
  const view = bridge.changes;
6728
- const live = (miss, path) => miss.until > now() && (view === void 0 || miss.gen === void 0 || !view.changedSince(miss.gen, path).changed);
6766
+ const filled = new Fills(view, now);
6767
+ const young = (entry2) => filled.young(entry2);
6768
+ const live = (miss, path) => miss.until > now() && young(miss) && (view === void 0 || miss.gen === void 0 || !view.changedSince(miss.gen, path).changed);
6729
6769
  const seen = new SeenAt(view, lstats);
6730
- const kept = remember(cache, seen, blind);
6770
+ const kept = remember(cache, seen, blind, (entry2) => filled.set(entry2));
6731
6771
  const gone = (path) => goneAbove([lstats, stats], live, path);
6772
+ const usable = (map, path) => {
6773
+ const hit = map.get(path);
6774
+ if (hit === void 0) return void 0;
6775
+ if ("until" in hit) return live(hit, path) ? hit : void 0;
6776
+ return young(hit) && !seen.changed(map, path) ? hit : void 0;
6777
+ };
6732
6778
  const cached = (map, path, get) => {
6733
- if (blind || view?.foreign()) return get();
6779
+ if (blind) return get();
6734
6780
  cache.fresh();
6735
- let hit = map.get(path);
6736
- if (hit !== void 0 && !("until" in hit) && seen.changed(map, path)) hit = void 0;
6737
- if (hit === void 0 || "until" in hit && !live(hit, path)) {
6781
+ let hit = usable(map, path);
6782
+ if (hit === void 0) {
6738
6783
  const missing2 = gone(path);
6739
6784
  if (missing2) throw missing2.error;
6740
- const gen = view?.now();
6741
- try {
6742
- hit = get();
6743
- if (gen !== void 0) seen.saw(map, path, gen);
6744
- } catch (e) {
6745
- hit = {
6746
- error: e,
6747
- until: now() + MISS_TTL_MS,
6748
- ...gen !== void 0 ? { gen } : {}
6749
- };
6750
- }
6751
- cache.put(map, path, hit);
6785
+ hit = fetched({ view, now, seen, filled, cache }, map, path, get);
6752
6786
  }
6753
6787
  if ("until" in hit) throw hit.error;
6754
6788
  return hit;
@@ -6805,24 +6839,16 @@ function cachingBridge(bridge, now = () => performance.now(), shared) {
6805
6839
  readdir: (p) => bridge.readdir(p),
6806
6840
  readdirStat: (p) => {
6807
6841
  const gen = view?.now();
6842
+ const asked = now();
6808
6843
  const list = bridge.readdirStat(p);
6809
- const base = p === "/" ? "" : p;
6810
- for (const [name2, st] of list) {
6811
- if (!st || blind) continue;
6812
- const at = `${base}/${name2}`;
6813
- cache.put(lstats, at, st);
6814
- if (gen !== void 0) seen.saw(lstats, at, gen);
6815
- if (st.isSymbolicLink) continue;
6816
- cache.put(stats, at, st);
6817
- if (gen !== void 0) seen.saw(stats, at, gen);
6818
- }
6844
+ if (!blind) listed({ cache, seen, filled }, p, list, gen, asked);
6819
6845
  return list;
6820
6846
  },
6821
6847
  readlink: (p) => {
6822
6848
  const known = blind ? void 0 : (cache.fresh(), lstats.get(p));
6823
6849
  const gen = seen.lstat(p);
6824
6850
  const current = view !== void 0 && gen !== void 0 && !view.changedSince(gen, p).changed;
6825
- if (known && current && !("until" in known) && !known.isSymbolicLink) {
6851
+ if (known && current && !("until" in known) && young(known) && !known.isSymbolicLink) {
6826
6852
  throw syncError("EINVAL", `'${p}' is not a symbolic link`);
6827
6853
  }
6828
6854
  return bridge.readlink(p);
@@ -6895,7 +6921,7 @@ function pinnedIo2(bridge, handle, rewriting) {
6895
6921
  } : {}
6896
6922
  };
6897
6923
  }
6898
- var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, CACHE_CAP, FS_GEN, CRED_GEN, UMASK2, RING2, RING_SIZE2, SLOT2, FD_RING, FD_RING_SIZE, SHARED_IDS_BYTES, StatCache, SEEN_CAP, SeenAt, remember;
6924
+ var WasiError, FileBuffer, LocalFile, MAX_LINKS, MISS_TTL_MS, SHARED_TTL_MS, CACHE_CAP, FS_GEN, CRED_GEN, UMASK2, RING2, RING_SIZE2, SLOT2, FD_RING, FD_RING_SIZE, SHARED_IDS_BYTES, StatCache, SEEN_CAP, SeenAt, remember, Fills;
6899
6925
  var init_wasi_files = __esm({
6900
6926
  "src/process/wasi/wasi-files.ts"() {
6901
6927
  "use strict";
@@ -7122,6 +7148,7 @@ var init_wasi_files = __esm({
7122
7148
  };
7123
7149
  MAX_LINKS = 40;
7124
7150
  MISS_TTL_MS = 20;
7151
+ SHARED_TTL_MS = 100;
7125
7152
  CACHE_CAP = 8192;
7126
7153
  FS_GEN = 4;
7127
7154
  CRED_GEN = 5;
@@ -7286,13 +7313,30 @@ var init_wasi_files = __esm({
7286
7313
  return since.changed;
7287
7314
  }
7288
7315
  };
7289
- remember = (cache, seen, blind) => (path, made) => {
7316
+ remember = (cache, seen, blind, fill) => (path, made) => {
7290
7317
  if (!made || blind) return made;
7291
7318
  const { seen: at, ...st } = made;
7319
+ fill(st);
7292
7320
  cache.put(cache.stats, path, st);
7293
7321
  if (at !== void 0) seen.saw(cache.stats, path, at);
7294
7322
  return made;
7295
7323
  };
7324
+ Fills = class {
7325
+ at = /* @__PURE__ */ new WeakMap();
7326
+ view;
7327
+ now;
7328
+ constructor(view, now) {
7329
+ this.view = view;
7330
+ this.now = now;
7331
+ }
7332
+ set(entry, at = this.now()) {
7333
+ this.at.set(entry, at);
7334
+ }
7335
+ young(entry) {
7336
+ if (!this.view?.foreign()) return true;
7337
+ return this.now() - (this.at.get(entry) ?? Number.NEGATIVE_INFINITY) < SHARED_TTL_MS;
7338
+ }
7339
+ };
7296
7340
  }
7297
7341
  });
7298
7342
 
@@ -11373,8 +11417,8 @@ var init_wasi_host = __esm({
11373
11417
  }
11374
11418
  list(path) {
11375
11419
  const { fs } = this.o;
11376
- const listed = fs.readdirStat(path);
11377
- return { names: [".", "..", ...listed.map(([name2]) => name2)], stats: new Map(listed) };
11420
+ const listed2 = fs.readdirStat(path);
11421
+ return { names: [".", "..", ...listed2.map(([name2]) => name2)], stats: new Map(listed2) };
11378
11422
  }
11379
11423
  lstatOrNull(path) {
11380
11424
  try {
@@ -12179,9 +12223,9 @@ function procfsBridge(fs, tree) {
12179
12223
  }
12180
12224
  }),
12181
12225
  () => {
12182
- const listed = fs.readdirStat(p);
12183
- if (p !== "/" || listed.some(([name2]) => name2 === "proc")) return listed;
12184
- return [...listed, ["proc", tree.stat("/proc")]];
12226
+ const listed2 = fs.readdirStat(p);
12227
+ if (p !== "/" || listed2.some(([name2]) => name2 === "proc")) return listed2;
12228
+ return [...listed2, ["proc", tree.stat("/proc")]];
12185
12229
  }
12186
12230
  ),
12187
12231
  rename: (from, to) => readOnly2(
@@ -12423,17 +12467,17 @@ function ptsBridge(fs, call2) {
12423
12467
  },
12424
12468
  readdir: (p) => {
12425
12469
  if (p === PTS) return names();
12426
- const listed = fs.readdir(p);
12427
- return p === "/dev" && !listed.includes("pts") ? [...listed, "pts"] : listed;
12470
+ const listed2 = fs.readdir(p);
12471
+ return p === "/dev" && !listed2.includes("pts") ? [...listed2, "pts"] : listed2;
12428
12472
  },
12429
12473
  readdirStat: (p) => {
12430
12474
  if (p === PTS) {
12431
12475
  const known = open();
12432
12476
  return names(known).map((name2) => listedEntry(name2, known));
12433
12477
  }
12434
- const listed = fs.readdirStat(p);
12435
- if (p !== "/dev" || listed.some(([name2]) => name2 === "pts")) return listed;
12436
- return [...listed, ["pts", dir()]];
12478
+ const listed2 = fs.readdirStat(p);
12479
+ if (p !== "/dev" || listed2.some(([name2]) => name2 === "pts")) return listed2;
12480
+ return [...listed2, ["pts", dir()]];
12437
12481
  }
12438
12482
  };
12439
12483
  return new Proxy(fs, {
@@ -17280,9 +17324,7 @@ function createContext(o) {
17280
17324
  argv: o.argv,
17281
17325
  env: o.env,
17282
17326
  pid: o.pid,
17283
- async ppid() {
17284
- return identityOf(await kernel.json({ op: "proc-identity" }), o).ppid;
17285
- },
17327
+ ppid: async () => identityOf(await kernel.json({ op: "proc-identity" }), o).ppid,
17286
17328
  cwd: o.cwd,
17287
17329
  stdin: readable2(read2),
17288
17330
  stdout: writable2(1),
@@ -17327,6 +17369,7 @@ function createContext(o) {
17327
17369
  websocket: websocketOp(kernel),
17328
17370
  tty: terminal.tty,
17329
17371
  exit,
17372
+ thread: o.thread,
17330
17373
  onUncaught: (listener) => listen(strays.exception, listener),
17331
17374
  onUnhandledRejection: (listener) => listen(strays.rejection, listener)
17332
17375
  };
@@ -17558,11 +17601,100 @@ var init_js_context = __esm({
17558
17601
  }
17559
17602
  });
17560
17603
 
17604
+ // src/process/js/js-thread.ts
17605
+ function outOfMemory(err) {
17606
+ return err instanceof RangeError && OOM.test(err.message);
17607
+ }
17608
+ function optionsOf(options) {
17609
+ if (options === void 0) return {};
17610
+ if (typeof options !== "object" || options === null || Array.isArray(options)) {
17611
+ throw new JsCallError("EINVAL", "thread.spawn");
17612
+ }
17613
+ const { transfer } = options;
17614
+ if (transfer !== void 0 && !Array.isArray(transfer)) {
17615
+ throw new JsCallError("EINVAL", "thread.spawn");
17616
+ }
17617
+ return options;
17618
+ }
17619
+ function started(port2, control) {
17620
+ const exited = Promise.withResolvers();
17621
+ return new Promise((resolve, reject) => {
17622
+ const thread = (tid) => Object.freeze({
17623
+ tid,
17624
+ port: port2,
17625
+ exited: exited.promise,
17626
+ async terminate() {
17627
+ control.postMessage({ terminate: true });
17628
+ await exited.promise;
17629
+ }
17630
+ });
17631
+ control.onmessage = (event) => {
17632
+ const said = event.data;
17633
+ if ("tid" in said) resolve(thread(said.tid));
17634
+ else if ("errno" in said) {
17635
+ control.close();
17636
+ port2.close();
17637
+ reject(new JsCallError(said.errno, "thread.spawn", said.message));
17638
+ } else if ("exited" in said) {
17639
+ control.close();
17640
+ exited.resolve(said.exited);
17641
+ }
17642
+ };
17643
+ });
17644
+ }
17645
+ function threadContext(post2, start2) {
17646
+ const spawn = (options) => {
17647
+ let asked;
17648
+ try {
17649
+ asked = optionsOf(options);
17650
+ } catch (err) {
17651
+ return Promise.reject(err);
17652
+ }
17653
+ const channel = new NativeChannel();
17654
+ const control = new NativeChannel();
17655
+ const transfer = [...asked.transfer ?? []];
17656
+ const msg = {
17657
+ type: JS_THREAD_SPAWN,
17658
+ data: asked.data,
17659
+ port: channel.port2,
17660
+ control: control.port2,
17661
+ transfer
17662
+ };
17663
+ try {
17664
+ post2.postMessage(msg, [channel.port2, control.port2, ...transfer]);
17665
+ } catch (err) {
17666
+ channel.port1.close();
17667
+ control.port1.close();
17668
+ return Promise.reject(err);
17669
+ }
17670
+ return started(channel.port1, control.port1);
17671
+ };
17672
+ return Object.freeze({
17673
+ tid: start2?.tid ?? 0,
17674
+ port: start2?.port,
17675
+ data: start2?.data,
17676
+ NO_MEMORY: JS_THREAD_NO_MEMORY,
17677
+ CRASHED: JS_THREAD_CRASHED,
17678
+ spawn
17679
+ });
17680
+ }
17681
+ var NativeChannel, OOM;
17682
+ var init_js_thread = __esm({
17683
+ "src/process/js/js-thread.ts"() {
17684
+ "use strict";
17685
+ init_protocol();
17686
+ init_js_kernel();
17687
+ NativeChannel = globalThis.MessageChannel;
17688
+ OOM = /out of memory|Array buffer allocation failed|Cannot allocate Wasm memory/i;
17689
+ }
17690
+ });
17691
+
17561
17692
  // src/process/js/js-runtime.ts
17562
17693
  var js_runtime_exports = {};
17563
17694
  __export(js_runtime_exports, {
17564
17695
  mainOf: () => mainOf,
17565
17696
  runJsProcess: () => runJsProcess,
17697
+ runJsThread: () => runJsThread,
17566
17698
  trapStrays: () => trapStrays
17567
17699
  });
17568
17700
  function trapStrays(scope2, stray) {
@@ -17593,7 +17725,15 @@ function mainOf(module) {
17593
17725
  const main = typeof module.default === "function" ? module.default : module.main;
17594
17726
  return typeof main === "function" ? main : void 0;
17595
17727
  }
17596
- async function runJsProcess(init, port2, deps = {}) {
17728
+ function runJsProcess(init, port2, deps = {}) {
17729
+ return runJs(init, port2, deps, void 0);
17730
+ }
17731
+ function runJsThread(init, port2, deps = {}) {
17732
+ const { thread, ...rest2 } = init;
17733
+ return runJs(rest2, port2, deps, thread);
17734
+ }
17735
+ async function runJs(init, port2, deps, thread) {
17736
+ const failed5 = (err) => thread && outOfMemory(err) ? JS_THREAD_NO_MEMORY : 1;
17597
17737
  const transport = createAsyncSabTransport(init.sab, port2, deps.waitAsync);
17598
17738
  let resolveExit;
17599
17739
  const exit = new Promise((resolve) => resolveExit = resolve);
@@ -17605,7 +17745,7 @@ async function runJsProcess(init, port2, deps = {}) {
17605
17745
  let failing;
17606
17746
  const fail = (err) => {
17607
17747
  if (err instanceof JsExit) return;
17608
- failing ??= say(message(err)).then(() => exited(1));
17748
+ failing ??= (thread ? Promise.resolve() : say(message(err))).then(() => exited(failed5(err)));
17609
17749
  };
17610
17750
  const kernel = new JsKernel({
17611
17751
  sab: init.sab,
@@ -17626,7 +17766,8 @@ async function runJsProcess(init, port2, deps = {}) {
17626
17766
  cwd: init.cwd,
17627
17767
  exit: (status3) => exited(statusOf(status3)),
17628
17768
  lane: laneOf(init.lane),
17629
- strays
17769
+ strays,
17770
+ thread: threadContext(port2, thread)
17630
17771
  });
17631
17772
  const say = (text) => ctx.write(2, `${init.argv0}: ${text}
17632
17773
  `).catch(() => void 0);
@@ -17657,8 +17798,8 @@ async function runJsProcess(init, port2, deps = {}) {
17657
17798
  const program = main;
17658
17799
  const ran = Promise.resolve().then(() => program(ctx)).then(statusOf, async (err) => {
17659
17800
  if (err instanceof JsExit) return err.status;
17660
- await say(message(err));
17661
- return 1;
17801
+ if (!thread) await say(message(err));
17802
+ return failed5(err);
17662
17803
  });
17663
17804
  const status2 = await Promise.race([ran, exit]);
17664
17805
  await drain2();
@@ -17671,11 +17812,13 @@ var NOT_RUNNABLE;
17671
17812
  var init_js_runtime = __esm({
17672
17813
  "src/process/js/js-runtime.ts"() {
17673
17814
  "use strict";
17815
+ init_protocol();
17674
17816
  init_wasi_imports();
17675
17817
  init_async_sab();
17676
17818
  init_js_context();
17677
17819
  init_js_kernel();
17678
17820
  init_js_sync();
17821
+ init_js_thread();
17679
17822
  init_lockdown();
17680
17823
  NOT_RUNNABLE = 126;
17681
17824
  }
@@ -17691,7 +17834,7 @@ init_process_runtime();
17691
17834
  var loadWasi = () => Promise.resolve().then(() => (init_wasi_runtime(), wasi_runtime_exports));
17692
17835
  var loadJs = () => Promise.resolve().then(() => (init_js_runtime(), js_runtime_exports));
17693
17836
  var NOT_RUNNABLE2 = 126;
17694
- function started(init, port2, run, wasi, js) {
17837
+ function started2(init, port2, run, wasi, js) {
17695
17838
  if (init.program?.abi === "js") {
17696
17839
  const jsInit = init;
17697
17840
  return js().then((m) => m.runJsProcess(jsInit, port2));
@@ -17721,8 +17864,19 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs,
17721
17864
  };
17722
17865
  return (data) => {
17723
17866
  const type = data?.type;
17724
- if (type !== WASM_THREAD_INIT && type !== WASM_PROCESS_INIT) return;
17867
+ if (type !== WASM_THREAD_INIT && type !== WASM_PROCESS_INIT && type !== JS_THREAD_INIT) return;
17725
17868
  const refusal2 = sealOnce();
17869
+ if (type === JS_THREAD_INIT) {
17870
+ if (refusal2) return failed5(refusal2.error);
17871
+ js().then((m) => {
17872
+ if (!m.runJsThread) throw new Error("this process worker runs no JS threads");
17873
+ return m.runJsThread(data, port2);
17874
+ }).then(
17875
+ (code2) => port2.postMessage({ type: JS_THREAD_EXIT, code: code2 }),
17876
+ failed5
17877
+ );
17878
+ return;
17879
+ }
17726
17880
  const init = data;
17727
17881
  if (type === WASM_THREAD_INIT || init?.program?.abi !== "js") useLocalClock(init?.sab);
17728
17882
  if (type === WASM_THREAD_INIT) {
@@ -17731,7 +17885,7 @@ function processEntry(port2, run = runWasmProcess, wasi = loadWasi, js = loadJs,
17731
17885
  return;
17732
17886
  }
17733
17887
  if (refusal2) return failed5(refusal2.error, NOT_RUNNABLE2);
17734
- started(data, port2, run, wasi, js).then(
17888
+ started2(data, port2, run, wasi, js).then(
17735
17889
  (code2) => port2.postMessage({ type: WASM_PROCESS_EXIT, code: code2 }),
17736
17890
  failed5
17737
17891
  );
@@ -17743,7 +17897,7 @@ init_process_fds();
17743
17897
  var scope = globalThis;
17744
17898
  var post = scope.postMessage.bind(scope);
17745
17899
  var onMessage = processEntry(
17746
- { postMessage: (message2) => post(message2) },
17900
+ { postMessage: (message2, transfer) => post(message2, transfer ?? []) },
17747
17901
  void 0,
17748
17902
  void 0,
17749
17903
  void 0,