@ai-ecoverse/slicc-kernel 1.68.0 → 1.70.0

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/dist/node.js CHANGED
@@ -838,6 +838,16 @@ function written(device, bytes) {
838
838
  if (device === "full" && bytes.length > 0) throw new KernelError("ENOSPC");
839
839
  return bytes.length;
840
840
  }
841
+ var DEVICE_PATHS = /* @__PURE__ */ new Map([
842
+ ["/dev/null", "null"],
843
+ ["/dev/zero", "zero"],
844
+ ["/dev/full", "full"],
845
+ ["/dev/urandom", "urandom"],
846
+ ["/dev/random", "urandom"]
847
+ ]);
848
+ function deviceAt(path) {
849
+ return DEVICE_PATHS.get(path);
850
+ }
841
851
  function deviceFile(device, access2) {
842
852
  const read = async (max) => {
843
853
  if (device === "null") return new Uint8Array(0);
@@ -5377,6 +5387,18 @@ function capturing(chunks2, max = Number.POSITIVE_INFINITY, overflow) {
5377
5387
  size += bytes.length;
5378
5388
  };
5379
5389
  }
5390
+ function captureFile(onData, control) {
5391
+ if (!control) return sinkFile(onData);
5392
+ control.opened = true;
5393
+ return new OpenFile({
5394
+ write: async (bytes) => {
5395
+ if (control.shut) throw new KernelError("EPIPE");
5396
+ onData(bytes.slice());
5397
+ return bytes.length;
5398
+ },
5399
+ close: () => control.ended()
5400
+ });
5401
+ }
5380
5402
  function concat2(chunks2) {
5381
5403
  const out = new Uint8Array(chunks2.reduce((n, c) => n + c.length, 0));
5382
5404
  let offset = 0;
@@ -5411,7 +5433,12 @@ var ChildTable = class {
5411
5433
  const fds = new FdTable();
5412
5434
  const captured = /* @__PURE__ */ new Map();
5413
5435
  try {
5414
- for (const [n, slot2] of stdio.entries()) fds.installAt(n, this.openSlot(slot2, n, captured));
5436
+ for (const [n, slot2] of stdio.entries()) {
5437
+ fds.installAt(
5438
+ n,
5439
+ "sameAs" in slot2 ? fds.get(slot2.sameAs).retain() : this.openSlot(slot2, n, captured)
5440
+ );
5441
+ }
5415
5442
  for (const slot2 of inherit2) {
5416
5443
  if (slot2.fd <= 2) continue;
5417
5444
  if ("device" in slot2) {
@@ -5468,7 +5495,7 @@ var ChildTable = class {
5468
5495
  if ("capture" in slot2) {
5469
5496
  const chunks2 = [];
5470
5497
  captured.set(n, chunks2);
5471
- return sinkFile(capturing(chunks2, slot2.max, slot2.overflow));
5498
+ return captureFile(capturing(chunks2, slot2.max, slot2.overflow), slot2.control);
5472
5499
  }
5473
5500
  return deviceFile("null");
5474
5501
  }
@@ -10323,9 +10350,11 @@ function capLimit(maxBuffer) {
10323
10350
  return Math.min(asked, RUN_CAPTURE_CAP);
10324
10351
  }
10325
10352
  function slot(how, n, extra) {
10353
+ if (how === "stdout") return { sameAs: 1 };
10354
+ if (typeof how === "number") return { fd: how };
10326
10355
  if (how === "inherit") return { fd: n };
10327
10356
  if (how === "ignore") return { none: true };
10328
- return extra;
10357
+ return extra();
10329
10358
  }
10330
10359
  function frame2(outcome, out, err) {
10331
10360
  const head = new TextEncoder().encode(JSON.stringify(outcome));
@@ -10355,12 +10384,20 @@ async function runChild(req, deps) {
10355
10384
  if (failure !== void 0) return;
10356
10385
  failure = code;
10357
10386
  if (pid !== 0) kill();
10387
+ decided.resolve();
10388
+ };
10389
+ const controls = [];
10390
+ const capture = () => {
10391
+ const { promise, resolve } = Promise.withResolvers();
10392
+ const control = { shut: false, ended: resolve, eof: promise };
10393
+ controls.push(control);
10394
+ return { capture: true, max, overflow: () => stop("ENOBUFS"), control };
10358
10395
  };
10359
- const capture = () => ({ capture: true, max, overflow: () => stop("ENOBUFS") });
10396
+ const decided = Promise.withResolvers();
10360
10397
  const stdio = [
10361
- slot(req.stdin, 0, { input: req.input ?? new Uint8Array(0) }),
10362
- slot(req.stdout, 1, capture()),
10363
- slot(req.stderr, 2, capture())
10398
+ slot(req.stdin, 0, () => ({ input: req.input ?? new Uint8Array(0) })),
10399
+ slot(req.stdout, 1, capture),
10400
+ slot(req.stderr, 2, capture)
10364
10401
  ];
10365
10402
  try {
10366
10403
  pid = await deps.children.spawn(
@@ -10377,8 +10414,11 @@ async function runChild(req, deps) {
10377
10414
  let status;
10378
10415
  try {
10379
10416
  status = await reaped(deps, pid);
10417
+ const open = controls.filter((c) => c.opened);
10418
+ await Promise.race([Promise.all(open.map((c) => c.eof)), decided.promise]);
10380
10419
  } finally {
10381
10420
  clearTimeout(timer);
10421
+ for (const control of controls) control.shut = true;
10382
10422
  }
10383
10423
  const out = deps.children.captured(pid, 1);
10384
10424
  const err = deps.children.captured(pid, 2);
@@ -11476,6 +11516,8 @@ var WasmProcess = class {
11476
11516
  }
11477
11517
  async openVfs(req) {
11478
11518
  if (inProc(req.path)) return this.openProc(req, req.path);
11519
+ const device = req.orphan ? void 0 : deviceAt(req.path);
11520
+ if (device) return this.openDevice(req, device);
11479
11521
  const alias = req.orphan ? void 0 : await procAlias(this.options.fs, req.path, !req.exclusive);
11480
11522
  if (typeof alias === "object")
11481
11523
  throw Object.assign(new Error(alias.refused), { code: alias.refused });
@@ -11513,6 +11555,14 @@ var WasmProcess = class {
11513
11555
  }
11514
11556
  return fd;
11515
11557
  }
11558
+ openDevice(req, device) {
11559
+ if (req.exclusive) throw Object.assign(new Error(req.path), { code: "EEXIST" });
11560
+ const access2 = req.flags & WRITE_ACCESS;
11561
+ return this.fds.install(
11562
+ deviceFile(device, access2 === 0 ? "read" : access2 === 1 ? "write" : void 0),
11563
+ 3
11564
+ );
11565
+ }
11516
11566
  async identified(stat, known) {
11517
11567
  const first = await stat();
11518
11568
  if (first.orphan) return first;