@ai-ecoverse/slicc-kernel 1.98.1 → 1.98.2

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
@@ -7651,9 +7651,19 @@ function touches(watcher, changed) {
7651
7651
  (watched) => changed === watched || under3(watched, changed) || (watcher.recursive ? under3(changed, watched) : parentOf6(changed) === watched)
7652
7652
  );
7653
7653
  }
7654
+ var REALS_KEPT = 4096;
7654
7655
  var FsWatchers = class {
7655
7656
  watchers = /* @__PURE__ */ new Set();
7656
7657
  taps = [];
7658
+ reals = /* @__PURE__ */ new Map();
7659
+ reshapes = [];
7660
+ onReshape(listener) {
7661
+ this.reshapes.push(listener);
7662
+ }
7663
+ reshaped() {
7664
+ this.reals.clear();
7665
+ for (const listener of this.reshapes) listener();
7666
+ }
7657
7667
  tap(listener) {
7658
7668
  this.taps.push(listener);
7659
7669
  }
@@ -7697,8 +7707,41 @@ var FsWatchers = class {
7697
7707
  this.changed(...changed(...args));
7698
7708
  }
7699
7709
  };
7710
+ const reals = this.reals;
7711
+ const realOf = async (path) => {
7712
+ const at = normalizePath(path);
7713
+ const known = reals.get(at);
7714
+ if (known !== void 0) return known;
7715
+ if (!fs.realpath) return at;
7716
+ let real;
7717
+ try {
7718
+ real = await fs.realpath(at, true);
7719
+ } catch {
7720
+ return at;
7721
+ }
7722
+ if (reals.size >= REALS_KEPT) reals.clear();
7723
+ reals.set(at, real);
7724
+ return real;
7725
+ };
7726
+ const content = (run2) => async (...args) => {
7727
+ try {
7728
+ await run2(...args);
7729
+ } finally {
7730
+ const at = normalizePath(args[0]);
7731
+ const real = await realOf(at);
7732
+ this.changed(...real === at ? [at] : [at, real]);
7733
+ }
7734
+ };
7735
+ const reshaping = (run2) => async (...args) => {
7736
+ this.reshaped();
7737
+ try {
7738
+ await run2(...args);
7739
+ } finally {
7740
+ this.reshaped();
7741
+ }
7742
+ };
7700
7743
  const overrides = {
7701
- writeFile: after(fs.writeFile.bind(fs), (path) => [path]),
7744
+ writeFile: content(fs.writeFile.bind(fs)),
7702
7745
  mkdir: async (path, options) => {
7703
7746
  const created3 = [];
7704
7747
  if (options?.recursive) {
@@ -7714,13 +7757,15 @@ var FsWatchers = class {
7714
7757
  this.changed(...created3, path);
7715
7758
  }
7716
7759
  },
7717
- rm: after(fs.rm.bind(fs), (path) => [path]),
7718
- rename: after(fs.rename.bind(fs), (from, to) => [from, to]),
7719
- link: after(
7720
- (from, to, follow2) => fs.link(from, to, follow2),
7721
- (_from, to) => [to]
7760
+ rm: reshaping(after(fs.rm.bind(fs), (path) => [path])),
7761
+ rename: reshaping(after(fs.rename.bind(fs), (from, to) => [from, to])),
7762
+ link: reshaping(
7763
+ after(
7764
+ (from, to, follow2) => fs.link(from, to, follow2),
7765
+ (_from, to) => [to]
7766
+ )
7722
7767
  ),
7723
- symlink: after(fs.symlink.bind(fs), (_target, path) => [path]),
7768
+ symlink: reshaping(after(fs.symlink.bind(fs), (_target, path) => [path])),
7724
7769
  chmod: after(fs.chmod.bind(fs), (path) => [path]),
7725
7770
  ...fs.chown ? { chown: after(fs.chown.bind(fs), (path) => [path]) } : {},
7726
7771
  utimes: after(fs.utimes.bind(fs), (path) => [path]),
@@ -7731,8 +7776,8 @@ var FsWatchers = class {
7731
7776
  };
7732
7777
  const ranged2 = rangedOps(fs);
7733
7778
  if (ranged2) {
7734
- overrides.pwrite = after(ranged2.pwrite, (path) => [path]);
7735
- overrides.truncate = after(ranged2.truncate, (path) => [path]);
7779
+ overrides.pwrite = content(ranged2.pwrite);
7780
+ overrides.truncate = content(ranged2.truncate);
7736
7781
  }
7737
7782
  return new Proxy(fs, {
7738
7783
  get(target, key, receiver) {
@@ -8671,6 +8716,7 @@ var MountTable = class {
8671
8716
  };
8672
8717
  mounted = mount;
8673
8718
  this.mounts.set(target, mount);
8719
+ this.deps.reshaped?.();
8674
8720
  this.notes.delete(target);
8675
8721
  return this.list().find((m) => m.target === target);
8676
8722
  }
@@ -8685,6 +8731,7 @@ var MountTable = class {
8685
8731
  if (!detach && this.deps.busy(at)) throw errnoError("EBUSY", `${at} has open files`);
8686
8732
  this.notes.delete(at);
8687
8733
  this.mounts.delete(at);
8734
+ this.deps.reshaped?.();
8688
8735
  const waits = [...this.sessions].filter(([, s]) => s.mount === mount).map(([real]) => this.commit(real));
8689
8736
  for (const c of this.committing.values()) if (c.mount === mount) waits.push(c.done);
8690
8737
  const close = () => {
@@ -11028,7 +11075,7 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
11028
11075
  var EARLY_WHOLE_FILE = 64 * 1024;
11029
11076
 
11030
11077
  // src/version.ts
11031
- var KERNEL_VERSION = true ? "1.98.1" : "0.0.0-dev";
11078
+ var KERNEL_VERSION = true ? "1.98.2" : "0.0.0-dev";
11032
11079
  var OS_RELEASE = "6.0.0-slicc";
11033
11080
  function procVersion() {
11034
11081
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -14556,6 +14603,7 @@ var VfsNodes = class {
14556
14603
  if (!this.byPath.has(to)) this.byPath.set(to, node);
14557
14604
  }
14558
14605
  know(node, id2) {
14606
+ this.reshaped();
14559
14607
  node.id = id2;
14560
14608
  if (!this.byId.has(id2)) this.byId.set(id2, node);
14561
14609
  }
@@ -14565,6 +14613,7 @@ var VfsNodes = class {
14565
14613
  return out;
14566
14614
  }
14567
14615
  forget(node) {
14616
+ this.reshaped();
14568
14617
  for (const p of this.namesOf(node)) this.byPath.delete(p);
14569
14618
  if (node.id !== void 0 && this.byId.get(node.id) === node) this.byId.delete(node.id);
14570
14619
  }
@@ -14579,6 +14628,38 @@ var VfsNodes = class {
14579
14628
  if (node.path === path) node.renamedTo(others[0]);
14580
14629
  return true;
14581
14630
  }
14631
+ holdsAny() {
14632
+ return this.byPath.size > 0;
14633
+ }
14634
+ epoch = 0;
14635
+ plain = /* @__PURE__ */ new Map();
14636
+ reshaped() {
14637
+ this.epoch++;
14638
+ this.plain.clear();
14639
+ }
14640
+ plainAt(path) {
14641
+ return this.plain.get(path) === this.epoch;
14642
+ }
14643
+ get shape() {
14644
+ return this.epoch;
14645
+ }
14646
+ notePlain(path, shape) {
14647
+ if (shape !== this.epoch) return;
14648
+ if (this.plain.size >= 4096) this.plain.clear();
14649
+ this.plain.set(path, shape);
14650
+ }
14651
+ holdsName(name2) {
14652
+ for (const path of this.byPath.keys())
14653
+ if (path.slice(path.lastIndexOf("/") + 1) === name2) return true;
14654
+ return false;
14655
+ }
14656
+ holdsLinked() {
14657
+ return this.byId.size > 0;
14658
+ }
14659
+ holdingId(id2) {
14660
+ const node = this.byId.get(id2);
14661
+ return node && !node.orphaned ? node : void 0;
14662
+ }
14582
14663
  holding(path) {
14583
14664
  if (this.byPath.size === 0) return void 0;
14584
14665
  const node = this.byPath.get(path);
@@ -14590,6 +14671,7 @@ var VfsNodes = class {
14590
14671
  return node;
14591
14672
  }
14592
14673
  create(path, id2, node) {
14674
+ this.reshaped();
14593
14675
  node.onDirty = () => this.changed?.(node.path);
14594
14676
  this.byPath.set(path, node);
14595
14677
  if (id2 !== void 0) this.know(node, id2);
@@ -14731,11 +14813,35 @@ async function refuseReadonly(fs, path, flags2, opts = {}) {
14731
14813
  const st = own ?? await stat(await targetDir(fs, path));
14732
14814
  if (st?.readonly) throw new KernelError("EROFS");
14733
14815
  }
14816
+ var baseName = (path) => path.slice(path.lastIndexOf("/") + 1);
14817
+ async function byRealPath(fs, nodes, at) {
14818
+ const real = await fs.realpath?.(at, true).catch(() => void 0);
14819
+ return real === void 0 || real === at ? void 0 : nodes.holding(real);
14820
+ }
14821
+ async function aliasOf(fs, nodes, at) {
14822
+ if (nodes.holdsName(baseName(at))) {
14823
+ const named = await byRealPath(fs, nodes, at);
14824
+ if (named) return named;
14825
+ }
14826
+ const st = await fs.lstat(at).catch(() => void 0);
14827
+ if (!st) return void 0;
14828
+ if (st.isSymbolicLink) return byRealPath(fs, nodes, at);
14829
+ if (st.ino === void 0 || (st.nlink ?? 1) < 2 || !nodes.holdsLinked()) return void 0;
14830
+ return nodes.holdingId(`${st.dev ?? 0}:${st.ino}`);
14831
+ }
14832
+ async function heldAt(fs, nodes, at) {
14833
+ const held = nodes.holding(at);
14834
+ if (held || !nodes.holdsAny() || nodes.plainAt(at)) return held;
14835
+ const shape = nodes.shape;
14836
+ const found = await aliasOf(fs, nodes, at);
14837
+ if (!found) nodes.notePlain(at, shape);
14838
+ return found;
14839
+ }
14734
14840
  function heldIo(fs, nodes, changed) {
14735
14841
  const ranged2 = rangedOps(fs);
14736
- const node = (path) => nodes.holding(fs.resolvePath("/", path));
14842
+ const node = (path) => heldAt(fs, nodes, fs.resolvePath("/", path));
14737
14843
  const write = async (path, op, fallback) => {
14738
- const held = node(path);
14844
+ const held = await node(path);
14739
14845
  if (!held) return fallback();
14740
14846
  const out = await held.serial(async () => {
14741
14847
  const done4 = await op(held);
@@ -14743,6 +14849,7 @@ function heldIo(fs, nodes, changed) {
14743
14849
  return done4;
14744
14850
  });
14745
14851
  changed(fs.resolvePath("/", path));
14852
+ if (held.path !== fs.resolvePath("/", path)) changed(held.path);
14746
14853
  return out;
14747
14854
  };
14748
14855
  return {
@@ -14767,17 +14874,17 @@ function heldIo(fs, nodes, changed) {
14767
14874
  ),
14768
14875
  async stat(path) {
14769
14876
  const st = await fs.stat(path);
14770
- const held = st.isFile ? node(path) : void 0;
14877
+ const held = st.isFile ? await node(path) : void 0;
14771
14878
  return held ? { ...st, size: await held.serial(() => held.size()) } : st;
14772
14879
  },
14773
14880
  async readFileBuffer(path) {
14774
- const held = node(path);
14881
+ const held = await node(path);
14775
14882
  if (!held) return fs.readFileBuffer(path);
14776
14883
  return held.serial(async () => held.pread(await held.size(), 0));
14777
14884
  },
14778
14885
  ...ranged2 ? {
14779
- pread: (path, at, n, version) => {
14780
- const held = node(path);
14886
+ pread: async (path, at, n, version) => {
14887
+ const held = await node(path);
14781
14888
  return held ? held.serial(() => held.pread(n, at)) : ranged2.pread(path, at, n, version);
14782
14889
  },
14783
14890
  pwrite: (path, at, bytes, transfer) => write(
@@ -14825,9 +14932,9 @@ function keepingOpen(fs, nodes, changed = () => {
14825
14932
  nodes.renamed(a, b);
14826
14933
  });
14827
14934
  },
14828
- writeFile: (path, content, owner) => {
14935
+ writeFile: async (path, content, owner) => {
14829
14936
  const at = fs.resolvePath("/", path);
14830
- const held = nodes.holding(at);
14937
+ const held = await heldAt(fs, nodes, at);
14831
14938
  if (!held) return nodes.onEntry(at, () => fs.writeFile(path, content, owner));
14832
14939
  const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
14833
14940
  return held.serial(async () => {
@@ -14835,6 +14942,7 @@ function keepingOpen(fs, nodes, changed = () => {
14835
14942
  await held.pwrite(bytes, 0);
14836
14943
  await held.flush();
14837
14944
  changed(at);
14945
+ if (held.path !== at) changed(held.path);
14838
14946
  });
14839
14947
  },
14840
14948
  createExclusive: async (path, owner) => nodes.createExclusive(await nodes.entryKey(fs.resolvePath("/", path)), owner),
@@ -19980,7 +20088,7 @@ function usersMode(mode = "off") {
19980
20088
  function tagOption(tag) {
19981
20089
  if (tag !== void 0 && typeof tag !== "string") throw new TypeError("a tag must be a string");
19982
20090
  }
19983
- function baseName(path) {
20091
+ function baseName2(path) {
19984
20092
  return path.slice(path.lastIndexOf("/") + 1);
19985
20093
  }
19986
20094
  function packageRootOf(path, roots) {
@@ -20023,7 +20131,7 @@ function appendedRoots(given) {
20023
20131
  }
20024
20132
  function plainEnv(words2) {
20025
20133
  const next2 = words2[1];
20026
- if (baseName(words2[0] ?? "") !== "env" || next2 === void 0) return false;
20134
+ if (baseName2(words2[0] ?? "") !== "env" || next2 === void 0) return false;
20027
20135
  return next2 === "-S" || !next2.startsWith("-") && !next2.includes("=");
20028
20136
  }
20029
20137
  function shebangCommand(words2) {
@@ -20039,9 +20147,9 @@ function shebangCommand(words2) {
20039
20147
  function interpreter(head) {
20040
20148
  const words2 = shebang(head);
20041
20149
  if (!words2) return "node";
20042
- if (baseName(words2[0]) === "env") words2.shift();
20150
+ if (baseName2(words2[0]) === "env") words2.shift();
20043
20151
  if (words2[0] === "-S") words2.shift();
20044
- return baseName(words2[0] ?? "");
20152
+ return baseName2(words2[0] ?? "");
20045
20153
  }
20046
20154
  function expandDefaults(defaults, env) {
20047
20155
  const out = {};
@@ -20215,6 +20323,9 @@ var Launcher = class {
20215
20323
  this.sealed.userOf = async (uid) => (await this.users.lookup(uid))?.name;
20216
20324
  if (this.owners) options.fs.trackOwners?.();
20217
20325
  this.watchers.tap((paths) => this.changes.publish(...paths));
20326
+ this.watchers.onReshape(() => {
20327
+ for (const nodes of this.openFiles) nodes.reshaped();
20328
+ });
20218
20329
  this.mounts = new MountTable({
20219
20330
  open: (type, spec) => this.driver(type, spec),
20220
20331
  busy: (target) => [...this.openFiles].some((nodes) => nodes.holds(target)) || heldUnder(this.held, target),
@@ -20222,6 +20333,7 @@ var Launcher = class {
20222
20333
  if (paths.some((path) => this.pnpmChain.has(path))) this.pnpmStale();
20223
20334
  this.watchers.changed(...paths);
20224
20335
  },
20336
+ reshaped: () => this.watchers.reshaped(),
20225
20337
  owners: this.owners
20226
20338
  });
20227
20339
  this.mounted = this.mounts.wrap(options.fs);
@@ -20479,22 +20591,22 @@ var Launcher = class {
20479
20591
  const head = await this.head(glue);
20480
20592
  if (!head) return void 0;
20481
20593
  if (isWasm(head)) {
20482
- const owner2 = await this.wasmOwner(glue, baseName(file).replace(/\.wasm$/, ""), scope);
20594
+ const owner2 = await this.wasmOwner(glue, baseName2(file).replace(/\.wasm$/, ""), scope);
20483
20595
  if (owner2) return { ...targetOf(owner2), ...asked };
20484
20596
  return {
20485
20597
  abi: "wasi",
20486
20598
  glue,
20487
20599
  wasm: glue,
20488
- argv0: baseName(argv0 || file).replace(/\.wasm$/, ""),
20600
+ argv0: baseName2(argv0 || file).replace(/\.wasm$/, ""),
20489
20601
  ...asked
20490
20602
  };
20491
20603
  }
20492
20604
  if (interpreter(head) !== "node") return void 0;
20493
20605
  const wasm = modulePath(glue);
20494
20606
  if (await this.base.exists(wasm)) {
20495
- return { abi: "emscripten", glue, wasm, argv0: baseName(argv0 || file), ...asked };
20607
+ return { abi: "emscripten", glue, wasm, argv0: baseName2(argv0 || file), ...asked };
20496
20608
  }
20497
- const owner = await this.glueOwner(glue, baseName(file), scope);
20609
+ const owner = await this.glueOwner(glue, baseName2(file), scope);
20498
20610
  return owner && { ...targetOf(owner), ...asked };
20499
20611
  }
20500
20612
  async glueOwner(glue, name2, scope) {
@@ -20504,11 +20616,11 @@ var Launcher = class {
20504
20616
  return owners.find((c) => c.name === name2) ?? owners[0];
20505
20617
  }
20506
20618
  async wasmOwner(wasm, name2, scope) {
20507
- const leaf = baseName(wasm);
20619
+ const leaf = baseName2(wasm);
20508
20620
  const real = await physicalPathAsync(this.base, wasm);
20509
20621
  const owners = [];
20510
20622
  for (const command of (await this.commands(scope)).values()) {
20511
- if (command.abi !== "wasi" || command.script || baseName(command.wasm) !== leaf) continue;
20623
+ if (command.abi !== "wasi" || command.script || baseName2(command.wasm) !== leaf) continue;
20512
20624
  if (command.wasm === wasm || await physicalPathAsync(this.base, command.wasm) === real)
20513
20625
  owners.push(command);
20514
20626
  }
@@ -21572,7 +21684,7 @@ var Launcher = class {
21572
21684
  const path = normalizePath(given);
21573
21685
  if (!await this.base.exists(path)) return void 0;
21574
21686
  if (path === "/") return path;
21575
- return joinName(await realDir(this.base, parentOf(path)), baseName(path));
21687
+ return joinName(await realDir(this.base, parentOf(path)), baseName2(path));
21576
21688
  }
21577
21689
  pnpmReady() {
21578
21690
  if (this.pnpmMade !== void 0) return this.pnpmMade;