@nimbus-sh/worker 0.1.5 → 0.1.6

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.
Files changed (135) hide show
  1. package/README.md +37 -0
  2. package/dist/_shared/crypto.d.ts +15 -0
  3. package/dist/_shared/crypto.d.ts.map +1 -0
  4. package/dist/_shared/crypto.js +122 -0
  5. package/dist/facets/manager.d.ts +24 -0
  6. package/dist/facets/manager.d.ts.map +1 -1
  7. package/dist/facets/manager.js +279 -70
  8. package/dist/facets/process.d.ts +11 -2
  9. package/dist/facets/process.d.ts.map +1 -1
  10. package/dist/facets/process.js +187 -21
  11. package/dist/facets/vite-dev-server.d.ts +2 -0
  12. package/dist/facets/vite-dev-server.d.ts.map +1 -1
  13. package/dist/facets/vite-dev-server.js +39 -12
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/loaders/child-process/spawn-facet.d.ts +1 -3
  18. package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -1
  19. package/dist/loaders/child-process/spawn-facet.js +1 -12
  20. package/dist/loaders/child-process/spawn-pool.d.ts +1 -1
  21. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
  22. package/dist/loaders/child-process/spawn-pool.js +1 -6
  23. package/dist/npm/installer.d.ts.map +1 -1
  24. package/dist/npm/installer.js +47 -27
  25. package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
  26. package/dist/npm/pre-bundle-facet.js +2 -1
  27. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  28. package/dist/npm/resolve-one-facet.js +41 -13
  29. package/dist/npm/resolver.d.ts.map +1 -1
  30. package/dist/npm/resolver.js +70 -35
  31. package/dist/router/index.d.ts.map +1 -1
  32. package/dist/router/index.js +45 -21
  33. package/dist/router/remote-api.d.ts.map +1 -1
  34. package/dist/router/remote-api.js +29 -8
  35. package/dist/runtime/barrel-synthesizer.d.ts +7 -0
  36. package/dist/runtime/barrel-synthesizer.d.ts.map +1 -1
  37. package/dist/runtime/barrel-synthesizer.js +11 -0
  38. package/dist/runtime/clang-runner.d.ts.map +1 -1
  39. package/dist/runtime/clang-runner.js +1 -8
  40. package/dist/runtime/esbuild-service.d.ts +12 -5
  41. package/dist/runtime/esbuild-service.d.ts.map +1 -1
  42. package/dist/runtime/esbuild-service.js +28 -14
  43. package/dist/runtime/node-runner.d.ts +2 -0
  44. package/dist/runtime/node-runner.d.ts.map +1 -1
  45. package/dist/runtime/node-shims.d.ts +4 -2
  46. package/dist/runtime/node-shims.d.ts.map +1 -1
  47. package/dist/runtime/node-shims.js +404 -55
  48. package/dist/runtime/os-contracts.d.ts +128 -0
  49. package/dist/runtime/os-contracts.d.ts.map +1 -0
  50. package/dist/runtime/os-contracts.js +1 -0
  51. package/dist/runtime/package-manager.d.ts.map +1 -1
  52. package/dist/runtime/package-manager.js +32 -7
  53. package/dist/runtime/port-registry.d.ts +5 -0
  54. package/dist/runtime/port-registry.d.ts.map +1 -1
  55. package/dist/runtime/port-registry.js +22 -1
  56. package/dist/runtime/pyodide-runtime-assets.d.ts +19 -0
  57. package/dist/runtime/pyodide-runtime-assets.d.ts.map +1 -0
  58. package/dist/runtime/pyodide-runtime-assets.js +44 -0
  59. package/dist/runtime/python-repl.d.ts +3 -1
  60. package/dist/runtime/python-repl.d.ts.map +1 -1
  61. package/dist/runtime/python-repl.js +11 -29
  62. package/dist/runtime/python-runner.d.ts +8 -9
  63. package/dist/runtime/python-runner.d.ts.map +1 -1
  64. package/dist/runtime/python-runner.js +897 -61
  65. package/dist/runtime/python-socket-shim.d.ts +11 -0
  66. package/dist/runtime/python-socket-shim.d.ts.map +1 -0
  67. package/dist/runtime/python-socket-shim.js +526 -0
  68. package/dist/runtime/require-resolver.d.ts.map +1 -1
  69. package/dist/runtime/require-resolver.js +2 -11
  70. package/dist/runtime/ruby-gems.d.ts +25 -0
  71. package/dist/runtime/ruby-gems.d.ts.map +1 -0
  72. package/dist/runtime/ruby-gems.js +582 -0
  73. package/dist/runtime/ruby-runner.d.ts +2 -4
  74. package/dist/runtime/ruby-runner.d.ts.map +1 -1
  75. package/dist/runtime/ruby-runner.js +335 -34
  76. package/dist/runtime/runtime-catalog.d.ts +16 -4
  77. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  78. package/dist/runtime/runtime-catalog.js +21 -10
  79. package/dist/runtime/runtime-registry.d.ts +3 -0
  80. package/dist/runtime/runtime-registry.d.ts.map +1 -1
  81. package/dist/runtime/runtime-registry.js +4 -0
  82. package/dist/runtime/sqlite-runtime-fs-bridge.d.ts +43 -0
  83. package/dist/runtime/sqlite-runtime-fs-bridge.d.ts.map +1 -0
  84. package/dist/runtime/sqlite-runtime-fs-bridge.js +224 -0
  85. package/dist/runtime/static-server.d.ts +3 -0
  86. package/dist/runtime/static-server.d.ts.map +1 -0
  87. package/dist/runtime/static-server.js +121 -0
  88. package/dist/runtime/vfs-snapshot.d.ts +57 -0
  89. package/dist/runtime/vfs-snapshot.d.ts.map +1 -0
  90. package/dist/runtime/vfs-snapshot.js +141 -0
  91. package/dist/runtime/virtual-socket-kernel.d.ts +16 -0
  92. package/dist/runtime/virtual-socket-kernel.d.ts.map +1 -0
  93. package/dist/runtime/virtual-socket-kernel.js +360 -0
  94. package/dist/runtime/wasi-instance.d.ts +6 -3
  95. package/dist/runtime/wasi-instance.d.ts.map +1 -1
  96. package/dist/runtime/wasm-runner.d.ts +1 -25
  97. package/dist/runtime/wasm-runner.d.ts.map +1 -1
  98. package/dist/runtime/wasm-runner.js +1 -160
  99. package/dist/session/agent.d.ts +43 -0
  100. package/dist/session/agent.d.ts.map +1 -0
  101. package/dist/session/agent.js +1252 -0
  102. package/dist/session/init.d.ts.map +1 -1
  103. package/dist/session/init.js +15 -16
  104. package/dist/session/nimbus-session.d.ts +13 -2
  105. package/dist/session/nimbus-session.d.ts.map +1 -1
  106. package/dist/session/nimbus-session.js +55 -7
  107. package/dist/session/programmatic.d.ts +10 -0
  108. package/dist/session/programmatic.d.ts.map +1 -1
  109. package/dist/session/programmatic.js +121 -0
  110. package/dist/session/routes.d.ts.map +1 -1
  111. package/dist/session/routes.js +19 -1
  112. package/dist/session/rpc.d.ts +11 -0
  113. package/dist/session/rpc.d.ts.map +1 -1
  114. package/dist/session/rpc.js +56 -43
  115. package/dist/session/supervisor-rpc.d.ts +15 -0
  116. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  117. package/dist/session/supervisor-rpc.js +32 -0
  118. package/dist/session/ws.d.ts +4 -3
  119. package/dist/session/ws.d.ts.map +1 -1
  120. package/dist/session/ws.js +11 -1
  121. package/dist/shell/unix-commands.js +12 -16
  122. package/dist/vfs/path.d.ts +8 -4
  123. package/dist/vfs/path.d.ts.map +1 -1
  124. package/dist/vfs/path.js +16 -4
  125. package/dist/vfs/sqlite-vfs.d.ts +2 -0
  126. package/dist/vfs/sqlite-vfs.d.ts.map +1 -1
  127. package/dist/vfs/sqlite-vfs.js +11 -0
  128. package/dist/vfs/symlink-registry.d.ts +7 -1
  129. package/dist/vfs/symlink-registry.d.ts.map +1 -1
  130. package/dist/vfs/symlink-registry.js +16 -11
  131. package/package.json +4 -1
  132. package/public/index.html +240 -0
  133. package/public/s/index.html +1172 -146
  134. package/runtime-contracts/pyodide-workerd-adapter.json +18 -0
  135. package/scripts/bundle-runtime.mjs +99 -24
@@ -17,8 +17,10 @@
17
17
  * - child_process: ChildProcess objects (execution requires supervisor RPC)
18
18
  * - assert, util, url, querystring, string_decoder, readline, tty, timers
19
19
  *
20
- * VFS access: reads from __vfsBundle (pre-bundled by FacetManager),
21
- * writes to __vfsWrites (flushed back to VFS on completion).
20
+ * VFS access: sync reads use __vfsBundle (pre-bundled by FacetManager);
21
+ * async reads and common async mutations can use the supervisor bridge for
22
+ * live SQLite VFS coherence. Sync writes stay in __vfsWrites and flush on
23
+ * completion.
22
24
  */
23
25
  /**
24
26
  * Generate the shared shim block that goes inside both the DO-facet and
@@ -26,7 +28,7 @@
26
28
  *
27
29
  * At runtime the following variables must exist in scope:
28
30
  * - __vfsBundle: Record<string, string> (path→utf8 content)
29
- * - __vfsWrites: Record<string, string> (written files, returned in result)
31
+ * - __vfsWrites: Record<string, string | Uint8Array> (sync writes / failed async writes)
30
32
  * - __vfsDirs: Record<string, boolean> (dirs created)
31
33
  * - __vfsBaseUrl: string (supervisor URL for lazy VFS reads)
32
34
  * - cwd: string
@@ -230,6 +232,244 @@ const __fsMod = (() => {
230
232
  return undefined;
231
233
  }
232
234
 
235
+ function _fsErr(code, syscall, p) {
236
+ const err = new Error(code + ": " + syscall + " '" + p + "'");
237
+ err.code = code;
238
+ err.errno = code === "ENOENT" ? -2 : -1;
239
+ err.syscall = syscall;
240
+ err.path = String(p);
241
+ return err;
242
+ }
243
+
244
+ function _supervisor() {
245
+ try { return typeof __supervisor !== "undefined" ? __supervisor : null; }
246
+ catch { return null; }
247
+ }
248
+
249
+ function _rememberBundle(absPath, content) {
250
+ if (__vfsBundle && content !== undefined && content !== null) {
251
+ __vfsBundle[_strip(absPath)] = content;
252
+ }
253
+ return content;
254
+ }
255
+
256
+ function _writtenCell(absPath) {
257
+ const k = _strip(absPath);
258
+ if (__vfsWrites && k in __vfsWrites) return __vfsWrites[k];
259
+ if (__vfsBundle && k in __vfsBundle) return __vfsBundle[k];
260
+ return undefined;
261
+ }
262
+
263
+ function _markVfsStale() {
264
+ globalThis.__nimbusVfsMayBeStale = true;
265
+ }
266
+
267
+ function _statObject(meta) {
268
+ const type = meta?.type || (meta?.isDir || meta?.isDirectory ? "directory" : "file");
269
+ const isDir = type === "directory";
270
+ const isSymlink = type === "symlink";
271
+ const size = Number(meta?.size || 0);
272
+ const mtime = new Date(Number(meta?.mtime || Date.now()));
273
+ const mode = Number(meta?.mode || (isDir ? 0o755 : 0o644));
274
+ return {
275
+ isFile: () => !isDir && !isSymlink,
276
+ isDirectory: () => isDir,
277
+ isSymbolicLink: () => isSymlink,
278
+ size,
279
+ mtime,
280
+ mode,
281
+ };
282
+ }
283
+
284
+ function _direntObject(name, type) {
285
+ const isDir = type === "directory" || type === "dir";
286
+ const isSymlink = type === "symlink";
287
+ return {
288
+ name,
289
+ isFile: () => !isDir && !isSymlink,
290
+ isDirectory: () => isDir,
291
+ isSymbolicLink: () => isSymlink,
292
+ };
293
+ }
294
+
295
+ async function _liveReadFile(p, opts) {
296
+ const absPath = _resolve(p);
297
+ const encoding = typeof opts === "string" ? opts : opts?.encoding;
298
+ const supervisor = _supervisor();
299
+ if (!supervisor) throw _fsErr("ENOENT", "open", p);
300
+
301
+ if (typeof supervisor.readFileBytes === "function") {
302
+ const bytes = await supervisor.readFileBytes(absPath);
303
+ if (bytes !== null && bytes !== undefined) {
304
+ _rememberBundle(absPath, bytes);
305
+ return encoding ? _asString(bytes) : __BufferMod.from(bytes);
306
+ }
307
+ }
308
+
309
+ if (typeof supervisor.readFile === "function") {
310
+ const text = await supervisor.readFile(absPath);
311
+ if (text !== null && text !== undefined) {
312
+ _rememberBundle(absPath, text);
313
+ return encoding ? _asString(text) : __BufferMod.from(text);
314
+ }
315
+ }
316
+
317
+ throw _fsErr("ENOENT", "open", p);
318
+ }
319
+
320
+ async function _readFileAsync(p, opts) {
321
+ try { return readFileSync(p, opts); }
322
+ catch (e) {
323
+ if (e?.code !== "ENOENT") throw e;
324
+ return _liveReadFile(p, opts);
325
+ }
326
+ }
327
+
328
+ async function _statAsync(p) {
329
+ const absPath = _resolve(p);
330
+ try {
331
+ const local = statSync(p);
332
+ if (!(local.isFile && local.isFile() && local.size === 0 && _bundleLookup(absPath) === undefined)) {
333
+ return local;
334
+ }
335
+ } catch (e) {
336
+ if (e?.code !== "ENOENT") throw e;
337
+ const supervisor = _supervisor();
338
+ if (!supervisor || typeof supervisor.stat !== "function") throw e;
339
+ const meta = await supervisor.stat(absPath);
340
+ if (!meta) throw e;
341
+ return _statObject(meta);
342
+ }
343
+
344
+ const supervisor = _supervisor();
345
+ if (supervisor && typeof supervisor.stat === "function") {
346
+ const meta = await supervisor.stat(absPath);
347
+ if (meta) return _statObject(meta);
348
+ }
349
+ return statSync(p);
350
+ }
351
+
352
+ async function _readdirAsync(p, opts) {
353
+ const absPath = _resolve(p);
354
+ let local;
355
+ let localError;
356
+ try { local = readdirSync(p, opts); } catch (e) { localError = e; }
357
+ const mayBeStale = !!globalThis.__nimbusVfsMayBeStale;
358
+ if (Array.isArray(local) && !mayBeStale && !opts?.withFileTypes) return local;
359
+
360
+ const supervisor = _supervisor();
361
+ if (supervisor && typeof supervisor.readdir === "function") {
362
+ const entries = await supervisor.readdir(absPath);
363
+ if (Array.isArray(entries)) {
364
+ if (opts?.withFileTypes) {
365
+ const byName = new Map();
366
+ if (Array.isArray(local)) {
367
+ for (const entry of local) {
368
+ byName.set(entry.name, _direntObject(entry.name, entry.isDirectory && entry.isDirectory() ? "directory" : "file"));
369
+ }
370
+ }
371
+ for (const entry of entries) byName.set(entry.name, _direntObject(entry.name, entry.type));
372
+ return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));
373
+ }
374
+ const names = new Set(Array.isArray(local) ? local : []);
375
+ for (const entry of entries) names.add(entry.name);
376
+ return Array.from(names).sort();
377
+ }
378
+ }
379
+ if (Array.isArray(local)) return local;
380
+ throw localError || _fsErr("ENOENT", "scandir", p);
381
+ }
382
+
383
+ async function _existsAsync(p) {
384
+ if (existsSync(p)) return true;
385
+ const supervisor = _supervisor();
386
+ if (!supervisor || typeof supervisor.exists !== "function") return false;
387
+ return !!(await supervisor.exists(_resolve(p)));
388
+ }
389
+
390
+ async function _readlinkAsync(p) {
391
+ const supervisor = _supervisor();
392
+ if (supervisor && typeof supervisor.readlink === "function") {
393
+ const target = await supervisor.readlink(_resolve(p));
394
+ if (target !== null && target !== undefined) return target;
395
+ }
396
+ throw _fsErr("EINVAL", "readlink", p);
397
+ }
398
+
399
+ async function _symlinkAsync(target, path) {
400
+ const supervisor = _supervisor();
401
+ if (supervisor && typeof supervisor.symlink === "function") {
402
+ await supervisor.symlink(String(target), _resolve(path));
403
+ _markVfsStale();
404
+ return;
405
+ }
406
+ throw _fsErr("ENOSYS", "symlink", path);
407
+ }
408
+
409
+ async function _writeFileAsync(p, data, opts) {
410
+ const absPath = _resolve(p);
411
+ writeFileSync(p, data, opts);
412
+ const supervisor = _supervisor();
413
+ if (supervisor && typeof supervisor.writeFile === "function") {
414
+ const cell = _writtenCell(absPath);
415
+ if (cell !== undefined) {
416
+ await supervisor.writeFile(absPath, cell);
417
+ if (__vfsWrites) delete __vfsWrites[_strip(absPath)];
418
+ _markVfsStale();
419
+ }
420
+ }
421
+ }
422
+
423
+ async function _appendFileAsync(p, data, opts) {
424
+ const absPath = _resolve(p);
425
+ appendFileSync(p, data, opts);
426
+ const supervisor = _supervisor();
427
+ if (supervisor && typeof supervisor.writeFile === "function") {
428
+ const cell = _writtenCell(absPath);
429
+ if (cell !== undefined) {
430
+ await supervisor.writeFile(absPath, cell);
431
+ if (__vfsWrites) delete __vfsWrites[_strip(absPath)];
432
+ _markVfsStale();
433
+ }
434
+ }
435
+ }
436
+
437
+ async function _mkdirAsync(p, opts) {
438
+ mkdirSync(p, opts);
439
+ const supervisor = _supervisor();
440
+ if (supervisor && typeof supervisor.mkdir === "function") {
441
+ await supervisor.mkdir(_resolve(p));
442
+ _markVfsStale();
443
+ }
444
+ }
445
+
446
+ async function _unlinkAsync(p) {
447
+ unlinkSync(p);
448
+ const supervisor = _supervisor();
449
+ if (supervisor && typeof supervisor.unlink === "function") {
450
+ await supervisor.unlink(_resolve(p));
451
+ _markVfsStale();
452
+ }
453
+ }
454
+
455
+ async function _rmdirAsync(p) {
456
+ rmdirSync(p);
457
+ const supervisor = _supervisor();
458
+ if (supervisor && typeof supervisor.rmdir === "function") {
459
+ await supervisor.rmdir(_resolve(p));
460
+ _markVfsStale();
461
+ }
462
+ }
463
+
464
+ async function _renameAsync(oldP, newP) {
465
+ renameSync(oldP, newP);
466
+ const supervisor = _supervisor();
467
+ if (supervisor && typeof supervisor.rename === "function") {
468
+ await supervisor.rename(_resolve(oldP), _resolve(newP));
469
+ _markVfsStale();
470
+ }
471
+ }
472
+
233
473
  // ── readFileSync ──
234
474
  // Returns a Buffer when no encoding requested, a string otherwise.
235
475
  // The cell shape (string vs Uint8Array) drives conversion:
@@ -492,7 +732,8 @@ const __fsMod = (() => {
492
732
  }
493
733
 
494
734
  // ── realpathSync (X.5-T per X5Z5-plan §4.3 + X526b-retro §3.1) ──
495
- // VFS has no symlinks; identity-resolve to the absolute path. The
735
+ // Sync realpath stays local and identity-resolves. Async symlink
736
+ // operations use the live supervisor bridge below.
496
737
  // .native static is required by TypeScript's getNodeSystem at
497
738
  function realpathSync(p, opts) { return _resolve(String(p)); }
498
739
  realpathSync.native = realpathSync;
@@ -500,26 +741,30 @@ const __fsMod = (() => {
500
741
  // ── Async variants (thin wrappers returning via callback) ──
501
742
  function readFile(p, opts, cb) {
502
743
  if (typeof opts === "function") { cb = opts; opts = undefined; }
503
- try { const r = readFileSync(p, opts); if (cb) cb(null, r); } catch (e) { if (cb) cb(e); }
744
+ _readFileAsync(p, opts).then((r) => { if (cb) cb(null, r); }).catch((e) => { if (cb) cb(e); });
504
745
  }
505
746
  function writeFile(p, d, opts, cb) {
506
747
  if (typeof opts === "function") { cb = opts; opts = undefined; }
507
- try { writeFileSync(p, d, opts); if (cb) cb(null); } catch (e) { if (cb) cb(e); }
748
+ _writeFileAsync(p, d, opts).then(() => { if (cb) cb(null); }).catch((e) => { if (cb) cb(e); });
508
749
  }
509
- function stat(p, cb) { try { cb(null, statSync(p)); } catch (e) { cb(e); } }
750
+ function stat(p, cb) { _statAsync(p).then((s) => cb(null, s)).catch((e) => cb(e)); }
510
751
  function readdir(p, opts, cb) {
511
752
  if (typeof opts === "function") { cb = opts; opts = undefined; }
512
- try { cb(null, readdirSync(p, opts)); } catch (e) { cb(e); }
753
+ _readdirAsync(p, opts).then((d) => cb(null, d)).catch((e) => cb(e));
513
754
  }
514
- function exists(p, cb) { cb(existsSync(p)); }
755
+ function exists(p, cb) { _existsAsync(p).then((ok) => cb(ok)).catch(() => cb(false)); }
515
756
  function mkdir(p, opts, cb) {
516
757
  if (typeof opts === "function") { cb = opts; opts = undefined; }
517
- try { mkdirSync(p, opts); if (cb) cb(null); } catch (e) { if (cb) cb(e); }
758
+ _mkdirAsync(p, opts).then(() => { if (cb) cb(null); }).catch((e) => { if (cb) cb(e); });
518
759
  }
519
- function unlink(p, cb) { try { unlinkSync(p); if (cb) cb(null); } catch (e) { if (cb) cb(e); } }
760
+ function unlink(p, cb) { _unlinkAsync(p).then(() => { if (cb) cb(null); }).catch((e) => { if (cb) cb(e); }); }
761
+ function rename(oldP, newP, cb) { _renameAsync(oldP, newP).then(() => { if (cb) cb(null); }).catch((e) => { if (cb) cb(e); }); }
520
762
  function access(p, mode, cb) {
521
763
  if (typeof mode === "function") { cb = mode; mode = undefined; }
522
- if (existsSync(p)) cb(null); else { const e = new Error("ENOENT"); e.code = "ENOENT"; cb(e); }
764
+ _existsAsync(p).then((ok) => {
765
+ if (ok) cb(null);
766
+ else cb(_fsErr("ENOENT", "access", p));
767
+ }).catch((e) => cb(e));
523
768
  }
524
769
 
525
770
  // ── FileHandle (W3) — returned from fs.promises.open ──
@@ -530,11 +775,8 @@ const __fsMod = (() => {
530
775
  constructor(path, flags) { this._path = path; this._flags = flags || 'r'; this._closed = false; this.fd = 0; }
531
776
  async read(buffer, offset, length, position) {
532
777
  const absPath = _resolve(this._path);
533
- const data = _bundleLookup(absPath);
534
- if (data === undefined) {
535
- const e = new Error("ENOENT: no such file, read '" + this._path + "'");
536
- e.code = "ENOENT"; throw e;
537
- }
778
+ let data = _bundleLookup(absPath);
779
+ if (data === undefined) data = await _liveReadFile(this._path);
538
780
  // _bundleLookup may return string OR Uint8Array (binary-fs wave).
539
781
  const buf = _isBytes(data) ? data : _enc.encode(data);
540
782
  const start = position || 0;
@@ -552,24 +794,24 @@ const __fsMod = (() => {
552
794
  const o = offset || 0;
553
795
  const l = length === undefined ? buffer.length - o : length;
554
796
  const sub = buffer.substr(o, l);
555
- appendFileSync(this._path, sub);
797
+ await _appendFileAsync(this._path, sub);
556
798
  chunkBytesWritten = _enc.encode(sub).length;
557
799
  } else {
558
800
  const o = offset || 0;
559
801
  const l = length === undefined ? buffer.length - o : length;
560
802
  const sub = buffer.subarray(o, o + l);
561
- appendFileSync(this._path, sub);
803
+ await _appendFileAsync(this._path, sub);
562
804
  chunkBytesWritten = sub.byteLength;
563
805
  }
564
806
  return { bytesWritten: chunkBytesWritten, buffer };
565
807
  }
566
- async readFile(opts) { return readFileSync(this._path, opts); }
567
- async writeFile(data, opts) { writeFileSync(this._path, data, opts); }
568
- async appendFile(data, opts) { appendFileSync(this._path, data, opts); }
569
- async stat() { return statSync(this._path); }
808
+ async readFile(opts) { return _readFileAsync(this._path, opts); }
809
+ async writeFile(data, opts) { await _writeFileAsync(this._path, data, opts); }
810
+ async appendFile(data, opts) { await _appendFileAsync(this._path, data, opts); }
811
+ async stat() { return _statAsync(this._path); }
570
812
  async truncate(len) {
571
813
  const cur = readFileSync(this._path, "utf8");
572
- writeFileSync(this._path, cur.slice(0, len || 0));
814
+ await _writeFileAsync(this._path, cur.slice(0, len || 0));
573
815
  }
574
816
  async chmod() {} async chown() {} async utimes() {} async sync() {} async datasync() {}
575
817
  async close() { this._closed = true; }
@@ -591,7 +833,7 @@ const __fsMod = (() => {
591
833
  access: (p, m) => new Promise((res, rej) => access(p, m, (e) => e ? rej(e) : res())),
592
834
 
593
835
  // W3 additions:
594
- appendFile: async (p, d, o) => { appendFileSync(p, d, o); },
836
+ appendFile: async (p, d, o) => { await _appendFileAsync(p, d, o); },
595
837
  lstat: (p) => new Promise((res, rej) => stat(p, (e, s) => e ? rej(e) : res(s))),
596
838
  rm: async (p, opts) => {
597
839
  const o = opts || {};
@@ -602,7 +844,7 @@ const __fsMod = (() => {
602
844
  if (__vfsWrites) for (const wk of Object.keys(__vfsWrites)) if (wk === k || wk.startsWith(prefix)) delete __vfsWrites[wk];
603
845
  if (__vfsDirs) for (const dk of Object.keys(__vfsDirs)) if (dk === k || dk.startsWith(prefix)) delete __vfsDirs[dk];
604
846
  } else {
605
- try { unlinkSync(p); } catch (e) { if (!o.force) throw e; }
847
+ try { await _unlinkAsync(p); } catch (e) { if (!o.force) throw e; }
606
848
  }
607
849
  },
608
850
  cp: async (src, dest, opts) => {
@@ -611,7 +853,7 @@ const __fsMod = (() => {
611
853
  const srcK = _strip(srcAbs);
612
854
  const destK = _strip(_resolve(dest));
613
855
  const content = _bundleLookup(srcAbs);
614
- if (content !== undefined) { writeFileSync(dest, content); return; }
856
+ if (content !== undefined) { await _writeFileAsync(dest, content); return; }
615
857
  if (!o.recursive) {
616
858
  const err = new Error("EISDIR: cp without recursive on directory: " + src);
617
859
  err.code = "EISDIR"; throw err;
@@ -629,18 +871,19 @@ const __fsMod = (() => {
629
871
  if (__vfsBundle) __vfsBundle[newK] = v;
630
872
  }
631
873
  },
632
- copyFile: async (src, dest) => { copyFileSync(src, dest); },
633
- rename: async (oldP, newP) => { renameSync(oldP, newP); },
634
- rmdir: async (p) => { rmdirSync(p); },
874
+ copyFile: async (src, dest) => { await _writeFileAsync(dest, await _readFileAsync(src)); },
875
+ rename: async (oldP, newP) => { await _renameAsync(oldP, newP); },
876
+ rmdir: async (p) => { await _rmdirAsync(p); },
635
877
  realpath: async (p) => __pathMod.resolve(String(p)),
636
878
  truncate: async (p, len) => {
637
879
  const cur = (() => { try { return readFileSync(p, "utf8"); } catch { return ""; } })();
638
- writeFileSync(p, cur.slice(0, len || 0));
880
+ await _writeFileAsync(p, cur.slice(0, len || 0));
639
881
  },
640
882
  chmod: async () => {}, chown: async () => {}, lchmod: async () => {}, lchown: async () => {},
641
883
  utimes: async () => {}, lutimes: async () => {},
642
- symlink: async () => {}, link: async () => {},
643
- readlink: async (p) => String(p),
884
+ symlink: async (target, path) => { await _symlinkAsync(target, path); },
885
+ link: async () => { throw _fsErr("ENOSYS", "link", ""); },
886
+ readlink: async (p) => _readlinkAsync(p),
644
887
  mkdtemp: async (prefix) => {
645
888
  const name = String(prefix) + Math.random().toString(36).slice(2, 10);
646
889
  mkdirSync(name, { recursive: true });
@@ -696,7 +939,7 @@ const __fsMod = (() => {
696
939
  readFileSync, writeFileSync, appendFileSync, existsSync, statSync, lstatSync,
697
940
  readdirSync, mkdirSync, unlinkSync, rmdirSync, renameSync, copyFileSync,
698
941
  realpathSync,
699
- readFile, writeFile, stat, readdir, exists, mkdir, unlink, access,
942
+ readFile, writeFile, stat, readdir, exists, mkdir, unlink, rename, access,
700
943
  promises, constants,
701
944
  createReadStream: (p, opts) => {
702
945
  const rs = new __streamMod.Readable({
@@ -1512,7 +1755,7 @@ const __assertMod = Object.assign(
1512
1755
  );
1513
1756
 
1514
1757
  // ═══════════════════════════════════════════════════════════════════════
1515
- // ── querystring, string_decoder, child_process (stubs) ─────────────
1758
+ // ── querystring, string_decoder, child_process ─────────────────────
1516
1759
  // ═══════════════════════════════════════════════════════════════════════
1517
1760
  const __qsMod = {
1518
1761
  stringify: (o, sep, eq) => Object.entries(o || {}).map(([k,v]) => encodeURIComponent(k) + (eq||"=") + encodeURIComponent(String(v))).join(sep||"&"),
@@ -1616,26 +1859,39 @@ const __childProcessMod = (() => {
1616
1859
  }
1617
1860
  return String(chunk);
1618
1861
  }
1862
+ function _queueStdinWrite(child, data) {
1863
+ if (!child.pid) {
1864
+ child._pendingStdin = child._pendingStdin || [];
1865
+ child._pendingStdin.push(data);
1866
+ return Promise.resolve();
1867
+ }
1868
+ if (!HAS_SUPERVISOR) return Promise.reject(new Error("ERR_CHILD_PROCESS_UNAVAILABLE"));
1869
+ const prior = child._stdinChain || Promise.resolve();
1870
+ const next = prior.then(() => __supervisor.cpStdinWrite(child.pid, data));
1871
+ child._stdinChain = next.catch(() => {});
1872
+ __pendingIO.push(next.catch(() => {}));
1873
+ return next;
1874
+ }
1875
+ function _queueStdinEnd(child) {
1876
+ child._pendingStdinEnd = true;
1877
+ if (!child.pid) return Promise.resolve();
1878
+ if (!HAS_SUPERVISOR) return Promise.resolve();
1879
+ const prior = child._stdinChain || Promise.resolve();
1880
+ const next = prior.then(() => __supervisor.cpStdinEnd(child.pid));
1881
+ child._stdinChain = next.catch(() => {});
1882
+ __pendingIO.push(next.catch(() => {}));
1883
+ return next;
1884
+ }
1619
1885
  function _makeWritable(child) {
1620
1886
  const w = new __streamMod.Writable({
1621
1887
  write(chunk, enc, cb) {
1622
1888
  const s = _toUtf8(chunk);
1623
- if (!child.pid) {
1624
- // Child not yet spawned — buffer until pid available.
1625
- child._pendingStdin = child._pendingStdin || [];
1626
- child._pendingStdin.push(s);
1627
- cb();
1628
- return;
1629
- }
1630
- if (!HAS_SUPERVISOR) { cb(new Error("ERR_CHILD_PROCESS_UNAVAILABLE")); return; }
1631
- Promise.resolve(__supervisor.cpStdinWrite(child.pid, s))
1889
+ _queueStdinWrite(child, s)
1632
1890
  .then(() => cb())
1633
1891
  .catch((e) => cb(e));
1634
1892
  },
1635
1893
  final(cb) {
1636
- if (!child.pid) { cb(); return; }
1637
- if (!HAS_SUPERVISOR) { cb(); return; }
1638
- Promise.resolve(__supervisor.cpStdinEnd(child.pid))
1894
+ _queueStdinEnd(child)
1639
1895
  .then(() => cb())
1640
1896
  .catch(() => cb()); // best-effort end
1641
1897
  },
@@ -1675,6 +1931,30 @@ const __childProcessMod = (() => {
1675
1931
  child._pendingKill = null; // {signal} if kill called before pid
1676
1932
  child._exitFired = false;
1677
1933
  child._closeFired = false;
1934
+ child._stdinChain = Promise.resolve();
1935
+ child._pendingStdin = [];
1936
+ child._pendingStdinEnd = false;
1937
+ let _resolveClosePromise;
1938
+ child._closePromise = new Promise((resolve) => { _resolveClosePromise = resolve; });
1939
+ child._resolveClosePromise = _resolveClosePromise;
1940
+ child._closeTracked = false;
1941
+ const _trackCloseInterest = (event) => {
1942
+ if ((event === "close" || event === "exit") && !child._closeTracked) {
1943
+ child._closeTracked = true;
1944
+ __pendingIO.push(child._closePromise.catch(() => {}));
1945
+ }
1946
+ };
1947
+ const _childOn = child.on.bind(child);
1948
+ const _childOnce = child.once.bind(child);
1949
+ child.on = function(event, listener) {
1950
+ _trackCloseInterest(event);
1951
+ return _childOn(event, listener);
1952
+ };
1953
+ child.addListener = child.on;
1954
+ child.once = function(event, listener) {
1955
+ _trackCloseInterest(event);
1956
+ return _childOnce(event, listener);
1957
+ };
1678
1958
  // For non-piped fds, treat them as already-ended so 'close' can
1679
1959
  // fire after exit without waiting for end events that never come.
1680
1960
  child._stdoutEnded = stdio[1] !== "pipe";
@@ -1722,7 +2002,9 @@ const __childProcessMod = (() => {
1722
2002
  function _maybeFireClose(child) {
1723
2003
  if (child._exitFired && child._stdoutEnded && child._stderrEnded && !child._closeFired) {
1724
2004
  child._closeFired = true;
2005
+ globalThis.__nimbusVfsMayBeStale = true;
1725
2006
  try { child.emit("close", child.exitCode, child.signalCode); } catch {}
2007
+ try { child._resolveClosePromise({ code: child.exitCode, signal: child.signalCode }); } catch {}
1726
2008
  // Evict from the live-children map after a microtask so any
1727
2009
  // close listeners that re-read child state see consistent values.
1728
2010
  queueMicrotask(() => {
@@ -1845,12 +2127,17 @@ const __childProcessMod = (() => {
1845
2127
  __cpChildren.set(child.pid, child);
1846
2128
  try { child.emit("spawn"); } catch {}
1847
2129
 
1848
- // Flush any stdin written before pid was known.
2130
+ // Flush any stdin written before pid was known, preserving
2131
+ // write-before-end ordering for common child.stdin.write();
2132
+ // child.stdin.end() patterns.
1849
2133
  if (child._pendingStdin && child._pendingStdin.length > 0) {
1850
- for (const d of child._pendingStdin) {
1851
- __pendingIO.push(__supervisor.cpStdinWrite(child.pid, d).catch(() => {}));
2134
+ const pending = child._pendingStdin.splice(0);
2135
+ for (const d of pending) {
2136
+ await __supervisor.cpStdinWrite(child.pid, d).catch(() => {});
1852
2137
  }
1853
- child._pendingStdin = null;
2138
+ }
2139
+ if (child._pendingStdinEnd) {
2140
+ await __supervisor.cpStdinEnd(child.pid).catch(() => {});
1854
2141
  }
1855
2142
 
1856
2143
  // Flush a queued kill if .kill() was called before pid landed.
@@ -1866,9 +2153,9 @@ const __childProcessMod = (() => {
1866
2153
  // is null and we skip the read-loop entirely.
1867
2154
  const stdoutSeq = { value: 0 };
1868
2155
  const stderrSeq = { value: 0 };
1869
- if (child.stdout) __pendingIO.push(_runReadLoop(child, 1, child.stdout, stdoutSeq));
1870
- if (child.stderr) __pendingIO.push(_runReadLoop(child, 2, child.stderr, stderrSeq));
1871
- __pendingIO.push(_runWaitLoop(child));
2156
+ if (child.stdout) void _runReadLoop(child, 1, child.stdout, stdoutSeq);
2157
+ if (child.stderr) void _runReadLoop(child, 2, child.stderr, stderrSeq);
2158
+ void _runWaitLoop(child);
1872
2159
  } catch (e) {
1873
2160
  try { child.emit("error", e); } catch {}
1874
2161
  child._exitFired = true;
@@ -2134,6 +2421,68 @@ const __consoleMod = {
2134
2421
  // ═══════════════════════════════════════════════════════════════════════
2135
2422
  // ── process shim ───────────────────────────────────────────────────
2136
2423
  // ═══════════════════════════════════════════════════════════════════════
2424
+ function __makeProcessStdin() {
2425
+ const r = new __streamMod.PassThrough();
2426
+ let seeded = false;
2427
+ let encoding = null;
2428
+ r.isTTY = false;
2429
+ r.setEncoding = function(enc) { encoding = enc || null; return r; };
2430
+ const liveChildPid = env && env.NIMBUS_CP_CHILD_PID
2431
+ ? Number(env.NIMBUS_CP_CHILD_PID)
2432
+ : 0;
2433
+ async function pumpLiveStdin() {
2434
+ while (liveChildPid && __supervisor && typeof __supervisor.cpReadStdin === "function") {
2435
+ const packet = await __supervisor.cpReadStdin(liveChildPid, 1000);
2436
+ if (packet && packet.data) r.write(packet.data);
2437
+ if (packet && packet.ended) {
2438
+ r.end();
2439
+ break;
2440
+ }
2441
+ }
2442
+ }
2443
+ const seed = () => {
2444
+ if (seeded) return;
2445
+ seeded = true;
2446
+ if (liveChildPid && __supervisor && typeof __supervisor.cpReadStdin === "function") {
2447
+ __pendingIO.push(pumpLiveStdin().catch(() => {
2448
+ try { r.end(); } catch {}
2449
+ }));
2450
+ return;
2451
+ }
2452
+ queueMicrotask(() => {
2453
+ const data = typeof stdin === "string" ? stdin : "";
2454
+ if (data.length > 0) r.write(data);
2455
+ r.end();
2456
+ });
2457
+ };
2458
+ const origOn = r.on.bind(r);
2459
+ function wrapDataListener(listener) {
2460
+ return (chunk) => {
2461
+ let out = chunk;
2462
+ if (encoding && chunk instanceof Uint8Array) {
2463
+ try { out = new TextDecoder(encoding).decode(chunk); }
2464
+ catch { out = chunk; }
2465
+ }
2466
+ return listener(out);
2467
+ };
2468
+ }
2469
+ r.on = function(event, listener) {
2470
+ seed();
2471
+ if (event === "data" && typeof listener === "function") {
2472
+ const wrapped = wrapDataListener(listener);
2473
+ listener.__wrapped = wrapped;
2474
+ const ret = origOn(event, wrapped);
2475
+ try { r.resume(); } catch {}
2476
+ return ret;
2477
+ }
2478
+ return origOn(event, listener);
2479
+ };
2480
+ r.addListener = r.on;
2481
+ const origRead = r.read.bind(r);
2482
+ r.read = function(size) { seed(); return origRead(size); };
2483
+ return r;
2484
+ }
2485
+
2137
2486
  const __processMod = {
2138
2487
  argv: ["node", ...(argv || [])],
2139
2488
  env: env || {},
@@ -2145,7 +2494,7 @@ const __processMod = {
2145
2494
  pid: 1, ppid: 0, title: "node",
2146
2495
  stdout: { write: (d) => { stdout += String(d); return true; }, isTTY: false },
2147
2496
  stderr: { write: (d) => { stderr += String(d); return true; }, isTTY: false },
2148
- stdin: { read: () => null, on: () => __processMod.stdin, isTTY: false },
2497
+ stdin: __makeProcessStdin(),
2149
2498
  hrtime: Object.assign(
2150
2499
  (prev) => { const n = Date.now(); const s = Math.floor(n / 1000); const ns = (n % 1000) * 1e6; if (!prev) return [s, ns]; return [s - prev[0], ns - prev[1]]; },
2151
2500
  { bigint: () => BigInt(Date.now()) * 1000000n }