@ai-ecoverse/slicc-kernel 1.152.0 → 1.152.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.
@@ -1569,9 +1569,10 @@ var OpfsFs = class {
1569
1569
  }
1570
1570
  async fileId(path) {
1571
1571
  const found = await this.locate(path, true);
1572
- const [entry] = await this.meta.get([found.path]);
1572
+ const [entry] = await (this.meta.fresh ?? this.meta.get).call(this.meta, [found.path]);
1573
1573
  if (entry?.fid !== void 0) return entry.fid;
1574
1574
  const fid = crypto.randomUUID();
1575
+ this.idWrites++;
1575
1576
  await this.meta.update(found.path, (now) => ({
1576
1577
  ...occupied(now),
1577
1578
  path: found.path,
@@ -1842,6 +1843,10 @@ var OpfsFs = class {
1842
1843
  opfsCalls() {
1843
1844
  return this.calls;
1844
1845
  }
1846
+ idWrites = 0;
1847
+ fileIdWrites() {
1848
+ return this.idWrites;
1849
+ }
1845
1850
  opfsOps() {
1846
1851
  return this.calls + this.others;
1847
1852
  }
@@ -2301,7 +2306,7 @@ var OpfsFs = class {
2301
2306
  return new Uint8Array(await file.slice(offset, offset + length2).arrayBuffer());
2302
2307
  });
2303
2308
  }
2304
- async pwrite(path, offset, bytes) {
2309
+ async pwrite(path, offset, bytes, _transfer, options) {
2305
2310
  const at = normalizePath(path);
2306
2311
  const movedAway = this.renamesInFlight() ? await this.writeWaits(at) : false;
2307
2312
  this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
@@ -2316,7 +2321,10 @@ var OpfsFs = class {
2316
2321
  this.files.delete(target);
2317
2322
  }
2318
2323
  }
2319
- const [handle] = await this.fileFor(path, !existed && !movedAway);
2324
+ const [handle] = await this.fileFor(
2325
+ path,
2326
+ !existed && !movedAway && options?.create !== false
2327
+ );
2320
2328
  await this.writeAt(handle, target, path, offset, bytes);
2321
2329
  } finally {
2322
2330
  this.writeEnded(at);
@@ -7918,7 +7926,7 @@ function satisfies(version, range2) {
7918
7926
  }
7919
7927
 
7920
7928
  // src/version.ts
7921
- var KERNEL_VERSION = true ? "1.152.0" : "0.0.0-dev";
7929
+ var KERNEL_VERSION = true ? "1.152.2" : "0.0.0-dev";
7922
7930
  var OS_RELEASE = "6.0.0-slicc";
7923
7931
  function procVersion() {
7924
7932
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8795,6 +8803,7 @@ var PathMarks = class {
8795
8803
  floor = 0;
8796
8804
  touched = /* @__PURE__ */ new Map();
8797
8805
  flying = /* @__PURE__ */ new Map();
8806
+ waiting = /* @__PURE__ */ new Set();
8798
8807
  generation() {
8799
8808
  return this.gen;
8800
8809
  }
@@ -8827,10 +8836,22 @@ var PathMarks = class {
8827
8836
  const n = (this.flying.get(p) ?? 1) - 1;
8828
8837
  if (n > 0) this.flying.set(p, n);
8829
8838
  else this.flying.delete(p);
8839
+ for (const wake of [...this.waiting]) wake();
8830
8840
  this.touch(p);
8831
8841
  }
8832
8842
  }
8833
8843
  }
8844
+ async landed(path) {
8845
+ if (!this.inFlight(path)) return;
8846
+ await new Promise((resolve2) => {
8847
+ const wake = () => {
8848
+ if (this.inFlight(path)) return;
8849
+ this.waiting.delete(wake);
8850
+ resolve2();
8851
+ };
8852
+ this.waiting.add(wake);
8853
+ });
8854
+ }
8834
8855
  inFlight(path) {
8835
8856
  for (let p = path; this.flying.size > 0; p = parentOf5(p)) {
8836
8857
  if (this.flying.has(p)) return true;
@@ -9008,6 +9029,9 @@ var UnlinkedKeeper = class {
9008
9029
  changedSince(path, gen) {
9009
9030
  return this.marks.changedSince(path, gen);
9010
9031
  }
9032
+ landed(path) {
9033
+ return this.marks.landed(path);
9034
+ }
9011
9035
  inFlight(path) {
9012
9036
  return this.marks.inFlight(path);
9013
9037
  }
@@ -10699,9 +10723,9 @@ function withEtcFiles(fs, files) {
10699
10723
  readFileBuffer: (path) => fs.readFileBuffer(path).catch(fallback(path, (b) => b)),
10700
10724
  ...ranged2 ? {
10701
10725
  pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(fallback(path, (b) => b.slice(offset, offset + length2))),
10702
- pwrite: async (path, offset, bytes, transfer) => {
10726
+ pwrite: async (path, offset, bytes, transfer, options) => {
10703
10727
  if (files.has(path)) await materialize(path);
10704
- return ranged2.pwrite(path, offset, bytes, transfer);
10728
+ return ranged2.pwrite(path, offset, bytes, transfer, options);
10705
10729
  },
10706
10730
  truncate: async (path, size) => {
10707
10731
  if (files.has(path)) await materialize(path);
@@ -10810,10 +10834,10 @@ var FreshModules = class {
10810
10834
  };
10811
10835
  const ranged2 = rangedOps(fs);
10812
10836
  if (ranged2) {
10813
- overrides.pwrite = async (path, at, bytes, transfer) => {
10837
+ overrides.pwrite = async (path, at, bytes, transfer, options) => {
10814
10838
  const touches3 = at < MAGIC.length && this.fresh.has(normalizePath(path));
10815
10839
  const first = at === 0 && bytes.length >= MAGIC.length ? bytes.slice(0, MAGIC.length) : void 0;
10816
- await ranged2.pwrite(path, at, bytes, transfer);
10840
+ await ranged2.pwrite(path, at, bytes, transfer, options);
10817
10841
  if (touches3) await decide(path, first);
10818
10842
  };
10819
10843
  overrides.truncate = async (path, size) => {
@@ -12091,6 +12115,9 @@ var HeldSet = class extends Set {
12091
12115
  if (over !== void 0) holds2.doubt(over);
12092
12116
  }
12093
12117
  }
12118
+ async bindIds(id2) {
12119
+ for (const holds2 of [...this]) await holds2.bindIds(id2);
12120
+ }
12094
12121
  delete(holds2) {
12095
12122
  const removed = super.delete(holds2);
12096
12123
  for (const path of /* @__PURE__ */ new Set([...holds2.keys(), ...holds2.opens.keys()])) this.idle(path);
@@ -12144,12 +12171,24 @@ var HeldPaths = class extends Map {
12144
12171
  }
12145
12172
  boundIno(handle) {
12146
12173
  const doubt = this.doubted.get(handle);
12147
- const ino = this.bound.get(handle);
12148
- return doubt === void 0 || ino === void 0 ? void 0 : { ino, doubt };
12174
+ const bound3 = this.bound.get(handle);
12175
+ return doubt === void 0 || bound3 === void 0 ? void 0 : { ...bound3, doubt };
12176
+ }
12177
+ async bindIds(id2) {
12178
+ for (const [handle, bound3] of [...this.bound]) {
12179
+ const key = this.handles.get(handle);
12180
+ if (bound3.fid !== void 0 || key === void 0) continue;
12181
+ const fid = await id2(key)?.catch(() => void 0);
12182
+ if (fid !== void 0 && this.bound.get(handle) === bound3)
12183
+ this.bound.set(handle, { ...bound3, fid });
12184
+ }
12149
12185
  }
12150
12186
  trust(handle, doubt) {
12151
12187
  if (this.doubted.get(handle) === doubt) this.doubted.delete(handle);
12152
12188
  }
12189
+ pathOf(handle) {
12190
+ return this.handles.get(handle);
12191
+ }
12153
12192
  keptFor(handle) {
12154
12193
  return this.keptHandles.get(handle);
12155
12194
  }
@@ -12186,14 +12225,15 @@ var HeldPaths = class extends Map {
12186
12225
  for (const file of [...this.uses.keys()]) this.letGo(file, true);
12187
12226
  this.keptHandles.clear();
12188
12227
  }
12189
- hold(path, on, open2 = false, real, handle, ino) {
12228
+ hold(path, on, open2 = false, real, handle, ino, fid) {
12190
12229
  if (open2) {
12191
12230
  const made2 = this.holdOpen(path, on, real, handle);
12192
12231
  if (handle !== void 0) {
12193
12232
  this.bound.delete(handle);
12194
12233
  this.doubted.delete(handle);
12195
12234
  }
12196
- if (made2 !== void 0 && ino !== void 0) this.bound.set(made2, ino);
12235
+ if (made2 !== void 0 && ino !== void 0)
12236
+ this.bound.set(made2, fid === void 0 ? { ino } : { ino, fid });
12197
12237
  return made2;
12198
12238
  }
12199
12239
  this.holdWrite(path, on);
@@ -12929,7 +12969,7 @@ var MountFs = class _MountFs {
12929
12969
  );
12930
12970
  }
12931
12971
  }
12932
- async pwrite(path, offset, bytes, transfer = false, redirects = 0) {
12972
+ async pwrite(path, offset, bytes, transfer = false, options, redirects = 0) {
12933
12973
  const real = await this.follow(path, 0, true);
12934
12974
  const found = this.at(real);
12935
12975
  const { pwrite } = this.base;
@@ -12937,8 +12977,8 @@ var MountFs = class _MountFs {
12937
12977
  return this.based(
12938
12978
  [real],
12939
12979
  redirects,
12940
- () => pwrite.call(this.base, real, offset, bytes),
12941
- ([to], n) => this.pwrite(to, offset, bytes, transfer, n)
12980
+ () => pwrite.call(this.base, real, offset, bytes, false, options),
12981
+ ([to], n) => this.pwrite(to, offset, bytes, transfer, options, n)
12942
12982
  );
12943
12983
  }
12944
12984
  if (!found)
@@ -12962,7 +13002,7 @@ var MountFs = class _MountFs {
12962
13002
  op: "open",
12963
13003
  path: rel2,
12964
13004
  write: true,
12965
- create: true,
13005
+ create: options?.create !== false,
12966
13006
  truncate: false,
12967
13007
  exclusive: false
12968
13008
  });
@@ -13730,7 +13770,7 @@ async function run(entry, path, req) {
13730
13770
  case "truncate":
13731
13771
  return ranged(fs, path, req);
13732
13772
  case "append":
13733
- return json2(await appended(fs, path, req.body ?? new Uint8Array(0)));
13773
+ return json2(await appended(fs, path, req.body ?? new Uint8Array(0), req.handle));
13734
13774
  default:
13735
13775
  return { ok: false, errno: "EINVAL", message: `sync-fs: unknown op '${req.op}'` };
13736
13776
  }
@@ -13874,13 +13914,17 @@ async function holdOp(entry, path, req) {
13874
13914
  await entry.source?.open(path, real);
13875
13915
  await stillThere(entry, path, req);
13876
13916
  if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
13917
+ const fid = req.ino === void 0 ? void 0 : await idOf(entry, real ?? path);
13877
13918
  if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
13878
- return json2(entry.hold?.(path, on, open2, real, void 0, req.ino) ?? null);
13919
+ return json2(entry.hold?.(path, on, open2, real, void 0, req.ino, fid) ?? null);
13879
13920
  }
13880
13921
  }
13881
13922
  entry.hold?.(path, on, open2, void 0, req.handle);
13882
13923
  return done2;
13883
13924
  }
13925
+ async function idOf(entry, path) {
13926
+ return await entry.fileId?.(path)?.catch(() => void 0) ?? void 0;
13927
+ }
13884
13928
  async function ownEntry(entry, path, real) {
13885
13929
  const own = await entry.fs.realpath?.(path, false).catch((err) => {
13886
13930
  if (err.code !== "ENOENT") throw err;
@@ -13975,14 +14019,14 @@ async function createExclusive(fs, path, owner) {
13975
14019
  await fs.writeFile(path, new Uint8Array(0), owner);
13976
14020
  }
13977
14021
  var appending = /* @__PURE__ */ new Map();
13978
- async function appended(fs, path, body) {
14022
+ async function appended(fs, path, body, handle) {
13979
14023
  const key = await fs.realpath?.(path, true).catch(() => void 0) ?? path;
13980
14024
  const before = appending.get(key) ?? Promise.resolve();
13981
14025
  const run2 = before.then(async () => {
13982
14026
  if (fs.append) return fs.append(path, body);
13983
14027
  const size = (await fs.stat(path)).size;
13984
14028
  const ops = rangedOps(fs);
13985
- if (ops) await ops.pwrite(path, size, body, true);
14029
+ if (ops) await ops.pwrite(path, size, body, true, noCreate(handle));
13986
14030
  else {
13987
14031
  const whole = new Uint8Array(size + body.length);
13988
14032
  whole.set(await fs.readFileBuffer(path));
@@ -13998,6 +14042,9 @@ async function appended(fs, path, body) {
13998
14042
  });
13999
14043
  return run2;
14000
14044
  }
14045
+ function noCreate(handle) {
14046
+ return handle === void 0 ? void 0 : { create: false };
14047
+ }
14001
14048
  async function ranged(fs, path, req) {
14002
14049
  const ops = rangedOps(fs);
14003
14050
  if (!ops) throw syncError("ENOSYS", path);
@@ -14008,7 +14055,8 @@ async function ranged(fs, path, req) {
14008
14055
  kind: "bytes",
14009
14056
  bytes: await ops.pread(path, offset, req.length ?? 0, req.version)
14010
14057
  };
14011
- if (req.op === "pwrite") await ops.pwrite(path, offset, req.body ?? new Uint8Array(0), true);
14058
+ if (req.op === "pwrite")
14059
+ await ops.pwrite(path, offset, req.body ?? new Uint8Array(0), true, noCreate(req.handle));
14012
14060
  else await ops.truncate(path, req.length ?? 0);
14013
14061
  return done2;
14014
14062
  }
@@ -14024,12 +14072,20 @@ async function linkedElsewhere(fs, path, from) {
14024
14072
  const source = from === void 0 ? void 0 : await fs.lstat(from).catch(() => void 0);
14025
14073
  return !(source && source.ino === st.ino && source.dev === st.dev);
14026
14074
  }
14075
+ async function gatedByHandle(entry, opEntry, path, req, opReq) {
14076
+ const heldAt2 = () => req.handle === void 0 ? void 0 : opEntry.heldAt?.(req.handle);
14077
+ if (req.handle !== void 0) await opEntry.replacements?.landed?.(heldAt2() ?? path);
14078
+ const at = heldAt2() ?? path;
14079
+ const serve = async () => run(opEntry, await keptOr(opEntry, at, req.handle), opReq);
14080
+ return entry.gate ? entry.gate(at, serve) : serve();
14081
+ }
14027
14082
  async function keptOr(entry, path, handle) {
14028
14083
  if (handle !== void 0) {
14029
14084
  const hidden = entry.keptFor?.(handle)?.hidden;
14030
14085
  if (hidden !== void 0) return hidden;
14031
- await bound(entry, path, handle);
14032
- return path;
14086
+ const at = entry.heldAt?.(handle) ?? path;
14087
+ await bound(entry, at, handle);
14088
+ return at;
14033
14089
  }
14034
14090
  const kept = entry.unlinked?.(path);
14035
14091
  return kept && !await entry.fs.exists(path) ? kept.hidden : path;
@@ -14038,7 +14094,10 @@ async function bound(entry, path, handle) {
14038
14094
  const bound3 = entry.boundIno?.(handle);
14039
14095
  if (bound3 === void 0) return;
14040
14096
  const now = await entry.fs.stat(path).catch(() => void 0);
14041
- if (now?.ino === bound3.ino) {
14097
+ if (now === void 0 && bound3.fid !== void 0 && !await entry.fs.lstat(path).catch(() => void 0))
14098
+ throw syncError("ENOENT", path);
14099
+ const same3 = bound3.fid === void 0 ? now?.ino === bound3.ino : now?.fid === bound3.fid || await idOf(entry, path) === bound3.fid;
14100
+ if (same3) {
14042
14101
  entry.trust?.(handle, bound3.doubt);
14043
14102
  return;
14044
14103
  }
@@ -14219,8 +14278,7 @@ async function dispatchPath(entry, req) {
14219
14278
  if (entry.revoked?.(resolvedPath))
14220
14279
  return { ok: false, errno: "EIO", message: `${resolvedPath} was unmounted` };
14221
14280
  if (req.op === "write" && req.mode === 1 || UNLINKED_OPS.has(req.op)) {
14222
- const serve = async () => run(opEntry, await keptOr(opEntry, resolvedPath, req.handle), opReq);
14223
- return await (entry.gate ? entry.gate(resolvedPath, serve) : serve());
14281
+ return await gatedByHandle(entry, opEntry, resolvedPath, req, opReq);
14224
14282
  }
14225
14283
  if (!entry.own || !OWN_OPS.has(req.op)) return await run(opEntry, resolvedPath, opReq);
14226
14284
  const target = resolvedArg2 ?? (TWO_PATHS.has(req.op) ? fs.resolvePath(cwd, req.arg2 ?? "") : resolvedPath);
@@ -14852,6 +14910,8 @@ var SYS_TREE = {
14852
14910
  slicc_rename_ack_busy: (listing) => `${listing.renameAcks?.busy ?? 0}
14853
14911
  `,
14854
14912
  slicc_stale_fds: (listing) => `${listing.staleFds ?? 0}
14913
+ `,
14914
+ slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
14855
14915
  `,
14856
14916
  slicc_rename_acks: (listing) => {
14857
14917
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
@@ -23519,10 +23579,10 @@ function heldIo(fs, nodes, changed) {
23519
23579
  const held = await node(path);
23520
23580
  return held ? held.byName(() => held.pread(n, at)) : ranged2.pread(path, at, n, version);
23521
23581
  },
23522
- pwrite: (path, at, bytes, transfer) => write(
23582
+ pwrite: (path, at, bytes, transfer, options) => write(
23523
23583
  path,
23524
23584
  async (held) => void await held.pwrite(bytes, at),
23525
- () => ranged2.pwrite(path, at, bytes, transfer)
23585
+ () => ranged2.pwrite(path, at, bytes, transfer, options)
23526
23586
  ),
23527
23587
  truncate: (path, size) => write(
23528
23588
  path,
@@ -25807,11 +25867,13 @@ function holdingToken(opts, holds2, caller) {
25807
25867
  cwd: opts.cwd,
25808
25868
  ...opts.statfs ? { statfs: opts.statfs } : {},
25809
25869
  ...opts.renames ? { renames: opts.renames } : {},
25870
+ ...opts.fileId ? { fileId: opts.fileId } : {},
25810
25871
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
25811
- hold: (path, on, open2, real, handle, ino) => holds2.hold(path, on, open2, real, handle, ino),
25872
+ hold: (path, on, open2, real, handle, ino, fid) => holds2.hold(path, on, open2, real, handle, ino, fid),
25812
25873
  boundIno: holds2.boundIno.bind(holds2),
25813
25874
  trust: holds2.trust.bind(holds2),
25814
25875
  keptFor: (handle) => holds2.keptFor(handle),
25876
+ heldAt: (handle) => holds2.pathOf(handle),
25815
25877
  unlinked: (path) => holds2.keptAt(path),
25816
25878
  gate: (path, op) => opts.unlinkGate && holds2.holding(path) ? opts.unlinkGate.run(holds2.keyOf(path), op) : op(),
25817
25879
  own: (path, op) => holds2.own(path, op),
@@ -30960,7 +31022,8 @@ var Launcher = class {
30960
31022
  opfsOps: this.rootFs.opfsOps?.() ?? 0,
30961
31023
  cwdChecks: this.cwds.checks,
30962
31024
  renameAcks: this.rootFs.renameWaits?.(),
30963
- staleFds: staleFdCount()
31025
+ staleFds: staleFdCount(),
31026
+ fileIds: this.rootFs.fileIdWrites?.() ?? 0
30964
31027
  }),
30965
31028
  sudo: (call, signal) => this.sudo(pid, call, signal),
30966
31029
  crontab: (call) => this.crontab(pid, call),
@@ -30971,6 +31034,7 @@ var Launcher = class {
30971
31034
  replacements: stack.unlinked,
30972
31035
  statfs: (path) => this.mounts.statfs(path),
30973
31036
  renames: (since, held) => this.renameLog.since(since, held),
31037
+ fileId: (path) => this.locks.shared?.() === true ? this.rootFileId(path) : void 0,
30974
31038
  renameSeq: (from, to) => this.renameLog.seqOf(from, to),
30975
31039
  mounts: () => this.mounts.list(),
30976
31040
  mount: (call, signal) => this.processMount(pid, call, signal),
@@ -31850,12 +31914,16 @@ var Launcher = class {
31850
31914
  this.writers ??= this.writerStack();
31851
31915
  return this.writers;
31852
31916
  }
31917
+ rootFileId(path) {
31918
+ return this.mounts.locate(path) === void 0 ? this.rootFs.fileId?.(path) : void 0;
31919
+ }
31853
31920
  flushingPeers(fs) {
31854
31921
  const peers = fs.peers?.();
31855
31922
  if (!peers) return void 0;
31856
31923
  peers.watch((crowded) => {
31857
31924
  this.changes.flush();
31858
31925
  this.changes.foreign(crowded);
31926
+ if (crowded) void this.held?.bindIds((path) => this.rootFileId(path));
31859
31927
  });
31860
31928
  return {
31861
31929
  ...peers,
@@ -31941,9 +32009,9 @@ var Launcher = class {
31941
32009
  }
31942
32010
  moved(from, to, source) {
31943
32011
  this.renameLog.add(from, to);
32012
+ for (const holds2 of this.held) holds2.renamed(from, to);
31944
32013
  if (source) return;
31945
32014
  for (const nodes of this.openFiles) nodes.renamed(from, to);
31946
- for (const holds2 of this.held) holds2.renamed(from, to);
31947
32015
  this.watchers.moved(from, to);
31948
32016
  }
31949
32017
  processChain(fs, nodes, unlinked) {