@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.
package/dist/node.js CHANGED
@@ -3365,7 +3365,7 @@ function satisfies(version, range2) {
3365
3365
  }
3366
3366
 
3367
3367
  // src/version.ts
3368
- var KERNEL_VERSION = true ? "1.152.0" : "0.0.0-dev";
3368
+ var KERNEL_VERSION = true ? "1.152.2" : "0.0.0-dev";
3369
3369
  var OS_RELEASE = "6.0.0-slicc";
3370
3370
  function procVersion() {
3371
3371
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -4242,6 +4242,7 @@ var PathMarks = class {
4242
4242
  floor = 0;
4243
4243
  touched = /* @__PURE__ */ new Map();
4244
4244
  flying = /* @__PURE__ */ new Map();
4245
+ waiting = /* @__PURE__ */ new Set();
4245
4246
  generation() {
4246
4247
  return this.gen;
4247
4248
  }
@@ -4274,10 +4275,22 @@ var PathMarks = class {
4274
4275
  const n = (this.flying.get(p) ?? 1) - 1;
4275
4276
  if (n > 0) this.flying.set(p, n);
4276
4277
  else this.flying.delete(p);
4278
+ for (const wake of [...this.waiting]) wake();
4277
4279
  this.touch(p);
4278
4280
  }
4279
4281
  }
4280
4282
  }
4283
+ async landed(path) {
4284
+ if (!this.inFlight(path)) return;
4285
+ await new Promise((resolve2) => {
4286
+ const wake = () => {
4287
+ if (this.inFlight(path)) return;
4288
+ this.waiting.delete(wake);
4289
+ resolve2();
4290
+ };
4291
+ this.waiting.add(wake);
4292
+ });
4293
+ }
4281
4294
  inFlight(path) {
4282
4295
  for (let p = path; this.flying.size > 0; p = parentOf2(p)) {
4283
4296
  if (this.flying.has(p)) return true;
@@ -4468,6 +4481,9 @@ var UnlinkedKeeper = class {
4468
4481
  changedSince(path, gen) {
4469
4482
  return this.marks.changedSince(path, gen);
4470
4483
  }
4484
+ landed(path) {
4485
+ return this.marks.landed(path);
4486
+ }
4471
4487
  inFlight(path) {
4472
4488
  return this.marks.inFlight(path);
4473
4489
  }
@@ -6324,9 +6340,9 @@ function withEtcFiles(fs, files) {
6324
6340
  readFileBuffer: (path) => fs.readFileBuffer(path).catch(fallback(path, (b) => b)),
6325
6341
  ...ranged2 ? {
6326
6342
  pread: (path, offset, length2, version) => ranged2.pread(path, offset, length2, version).catch(fallback(path, (b) => b.slice(offset, offset + length2))),
6327
- pwrite: async (path, offset, bytes, transfer) => {
6343
+ pwrite: async (path, offset, bytes, transfer, options) => {
6328
6344
  if (files.has(path)) await materialize(path);
6329
- return ranged2.pwrite(path, offset, bytes, transfer);
6345
+ return ranged2.pwrite(path, offset, bytes, transfer, options);
6330
6346
  },
6331
6347
  truncate: async (path, size) => {
6332
6348
  if (files.has(path)) await materialize(path);
@@ -6435,10 +6451,10 @@ var FreshModules = class {
6435
6451
  };
6436
6452
  const ranged2 = rangedOps(fs);
6437
6453
  if (ranged2) {
6438
- overrides.pwrite = async (path, at, bytes, transfer) => {
6454
+ overrides.pwrite = async (path, at, bytes, transfer, options) => {
6439
6455
  const touches3 = at < MAGIC.length && this.fresh.has(normalizePath(path));
6440
6456
  const first = at === 0 && bytes.length >= MAGIC.length ? bytes.slice(0, MAGIC.length) : void 0;
6441
- await ranged2.pwrite(path, at, bytes, transfer);
6457
+ await ranged2.pwrite(path, at, bytes, transfer, options);
6442
6458
  if (touches3) await decide(path, first);
6443
6459
  };
6444
6460
  overrides.truncate = async (path, size) => {
@@ -8119,6 +8135,9 @@ var HeldSet = class extends Set {
8119
8135
  if (over !== void 0) holds2.doubt(over);
8120
8136
  }
8121
8137
  }
8138
+ async bindIds(id2) {
8139
+ for (const holds2 of [...this]) await holds2.bindIds(id2);
8140
+ }
8122
8141
  delete(holds2) {
8123
8142
  const removed = super.delete(holds2);
8124
8143
  for (const path of /* @__PURE__ */ new Set([...holds2.keys(), ...holds2.opens.keys()])) this.idle(path);
@@ -8172,12 +8191,24 @@ var HeldPaths = class extends Map {
8172
8191
  }
8173
8192
  boundIno(handle) {
8174
8193
  const doubt = this.doubted.get(handle);
8175
- const ino = this.bound.get(handle);
8176
- return doubt === void 0 || ino === void 0 ? void 0 : { ino, doubt };
8194
+ const bound3 = this.bound.get(handle);
8195
+ return doubt === void 0 || bound3 === void 0 ? void 0 : { ...bound3, doubt };
8196
+ }
8197
+ async bindIds(id2) {
8198
+ for (const [handle, bound3] of [...this.bound]) {
8199
+ const key = this.handles.get(handle);
8200
+ if (bound3.fid !== void 0 || key === void 0) continue;
8201
+ const fid = await id2(key)?.catch(() => void 0);
8202
+ if (fid !== void 0 && this.bound.get(handle) === bound3)
8203
+ this.bound.set(handle, { ...bound3, fid });
8204
+ }
8177
8205
  }
8178
8206
  trust(handle, doubt) {
8179
8207
  if (this.doubted.get(handle) === doubt) this.doubted.delete(handle);
8180
8208
  }
8209
+ pathOf(handle) {
8210
+ return this.handles.get(handle);
8211
+ }
8181
8212
  keptFor(handle) {
8182
8213
  return this.keptHandles.get(handle);
8183
8214
  }
@@ -8214,14 +8245,15 @@ var HeldPaths = class extends Map {
8214
8245
  for (const file of [...this.uses.keys()]) this.letGo(file, true);
8215
8246
  this.keptHandles.clear();
8216
8247
  }
8217
- hold(path, on, open = false, real, handle, ino) {
8248
+ hold(path, on, open = false, real, handle, ino, fid) {
8218
8249
  if (open) {
8219
8250
  const made2 = this.holdOpen(path, on, real, handle);
8220
8251
  if (handle !== void 0) {
8221
8252
  this.bound.delete(handle);
8222
8253
  this.doubted.delete(handle);
8223
8254
  }
8224
- if (made2 !== void 0 && ino !== void 0) this.bound.set(made2, ino);
8255
+ if (made2 !== void 0 && ino !== void 0)
8256
+ this.bound.set(made2, fid === void 0 ? { ino } : { ino, fid });
8225
8257
  return made2;
8226
8258
  }
8227
8259
  this.holdWrite(path, on);
@@ -8957,7 +8989,7 @@ var MountFs = class _MountFs {
8957
8989
  );
8958
8990
  }
8959
8991
  }
8960
- async pwrite(path, offset, bytes, transfer = false, redirects = 0) {
8992
+ async pwrite(path, offset, bytes, transfer = false, options, redirects = 0) {
8961
8993
  const real = await this.follow(path, 0, true);
8962
8994
  const found = this.at(real);
8963
8995
  const { pwrite } = this.base;
@@ -8965,8 +8997,8 @@ var MountFs = class _MountFs {
8965
8997
  return this.based(
8966
8998
  [real],
8967
8999
  redirects,
8968
- () => pwrite.call(this.base, real, offset, bytes),
8969
- ([to], n) => this.pwrite(to, offset, bytes, transfer, n)
9000
+ () => pwrite.call(this.base, real, offset, bytes, false, options),
9001
+ ([to], n) => this.pwrite(to, offset, bytes, transfer, options, n)
8970
9002
  );
8971
9003
  }
8972
9004
  if (!found)
@@ -8990,7 +9022,7 @@ var MountFs = class _MountFs {
8990
9022
  op: "open",
8991
9023
  path: rel2,
8992
9024
  write: true,
8993
- create: true,
9025
+ create: options?.create !== false,
8994
9026
  truncate: false,
8995
9027
  exclusive: false
8996
9028
  });
@@ -9758,7 +9790,7 @@ async function run(entry, path, req) {
9758
9790
  case "truncate":
9759
9791
  return ranged(fs, path, req);
9760
9792
  case "append":
9761
- return json2(await appended(fs, path, req.body ?? new Uint8Array(0)));
9793
+ return json2(await appended(fs, path, req.body ?? new Uint8Array(0), req.handle));
9762
9794
  default:
9763
9795
  return { ok: false, errno: "EINVAL", message: `sync-fs: unknown op '${req.op}'` };
9764
9796
  }
@@ -9902,13 +9934,17 @@ async function holdOp(entry, path, req) {
9902
9934
  await entry.source?.open(path, real);
9903
9935
  await stillThere(entry, path, req);
9904
9936
  if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
9937
+ const fid = req.ino === void 0 ? void 0 : await idOf(entry, real ?? path);
9905
9938
  if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
9906
- return json2(entry.hold?.(path, on, open, real, void 0, req.ino) ?? null);
9939
+ return json2(entry.hold?.(path, on, open, real, void 0, req.ino, fid) ?? null);
9907
9940
  }
9908
9941
  }
9909
9942
  entry.hold?.(path, on, open, void 0, req.handle);
9910
9943
  return done;
9911
9944
  }
9945
+ async function idOf(entry, path) {
9946
+ return await entry.fileId?.(path)?.catch(() => void 0) ?? void 0;
9947
+ }
9912
9948
  async function ownEntry(entry, path, real) {
9913
9949
  const own = await entry.fs.realpath?.(path, false).catch((err) => {
9914
9950
  if (err.code !== "ENOENT") throw err;
@@ -10003,14 +10039,14 @@ async function createExclusive(fs, path, owner) {
10003
10039
  await fs.writeFile(path, new Uint8Array(0), owner);
10004
10040
  }
10005
10041
  var appending = /* @__PURE__ */ new Map();
10006
- async function appended(fs, path, body) {
10042
+ async function appended(fs, path, body, handle) {
10007
10043
  const key = await fs.realpath?.(path, true).catch(() => void 0) ?? path;
10008
10044
  const before = appending.get(key) ?? Promise.resolve();
10009
10045
  const run2 = before.then(async () => {
10010
10046
  if (fs.append) return fs.append(path, body);
10011
10047
  const size = (await fs.stat(path)).size;
10012
10048
  const ops = rangedOps(fs);
10013
- if (ops) await ops.pwrite(path, size, body, true);
10049
+ if (ops) await ops.pwrite(path, size, body, true, noCreate(handle));
10014
10050
  else {
10015
10051
  const whole = new Uint8Array(size + body.length);
10016
10052
  whole.set(await fs.readFileBuffer(path));
@@ -10026,6 +10062,9 @@ async function appended(fs, path, body) {
10026
10062
  });
10027
10063
  return run2;
10028
10064
  }
10065
+ function noCreate(handle) {
10066
+ return handle === void 0 ? void 0 : { create: false };
10067
+ }
10029
10068
  async function ranged(fs, path, req) {
10030
10069
  const ops = rangedOps(fs);
10031
10070
  if (!ops) throw syncError("ENOSYS", path);
@@ -10036,7 +10075,8 @@ async function ranged(fs, path, req) {
10036
10075
  kind: "bytes",
10037
10076
  bytes: await ops.pread(path, offset, req.length ?? 0, req.version)
10038
10077
  };
10039
- if (req.op === "pwrite") await ops.pwrite(path, offset, req.body ?? new Uint8Array(0), true);
10078
+ if (req.op === "pwrite")
10079
+ await ops.pwrite(path, offset, req.body ?? new Uint8Array(0), true, noCreate(req.handle));
10040
10080
  else await ops.truncate(path, req.length ?? 0);
10041
10081
  return done;
10042
10082
  }
@@ -10052,12 +10092,20 @@ async function linkedElsewhere(fs, path, from) {
10052
10092
  const source = from === void 0 ? void 0 : await fs.lstat(from).catch(() => void 0);
10053
10093
  return !(source && source.ino === st.ino && source.dev === st.dev);
10054
10094
  }
10095
+ async function gatedByHandle(entry, opEntry, path, req, opReq) {
10096
+ const heldAt2 = () => req.handle === void 0 ? void 0 : opEntry.heldAt?.(req.handle);
10097
+ if (req.handle !== void 0) await opEntry.replacements?.landed?.(heldAt2() ?? path);
10098
+ const at = heldAt2() ?? path;
10099
+ const serve = async () => run(opEntry, await keptOr(opEntry, at, req.handle), opReq);
10100
+ return entry.gate ? entry.gate(at, serve) : serve();
10101
+ }
10055
10102
  async function keptOr(entry, path, handle) {
10056
10103
  if (handle !== void 0) {
10057
10104
  const hidden = entry.keptFor?.(handle)?.hidden;
10058
10105
  if (hidden !== void 0) return hidden;
10059
- await bound(entry, path, handle);
10060
- return path;
10106
+ const at = entry.heldAt?.(handle) ?? path;
10107
+ await bound(entry, at, handle);
10108
+ return at;
10061
10109
  }
10062
10110
  const kept = entry.unlinked?.(path);
10063
10111
  return kept && !await entry.fs.exists(path) ? kept.hidden : path;
@@ -10066,7 +10114,10 @@ async function bound(entry, path, handle) {
10066
10114
  const bound3 = entry.boundIno?.(handle);
10067
10115
  if (bound3 === void 0) return;
10068
10116
  const now = await entry.fs.stat(path).catch(() => void 0);
10069
- if (now?.ino === bound3.ino) {
10117
+ if (now === void 0 && bound3.fid !== void 0 && !await entry.fs.lstat(path).catch(() => void 0))
10118
+ throw syncError("ENOENT", path);
10119
+ const same2 = bound3.fid === void 0 ? now?.ino === bound3.ino : now?.fid === bound3.fid || await idOf(entry, path) === bound3.fid;
10120
+ if (same2) {
10070
10121
  entry.trust?.(handle, bound3.doubt);
10071
10122
  return;
10072
10123
  }
@@ -10247,8 +10298,7 @@ async function dispatchPath(entry, req) {
10247
10298
  if (entry.revoked?.(resolvedPath))
10248
10299
  return { ok: false, errno: "EIO", message: `${resolvedPath} was unmounted` };
10249
10300
  if (req.op === "write" && req.mode === 1 || UNLINKED_OPS.has(req.op)) {
10250
- const serve = async () => run(opEntry, await keptOr(opEntry, resolvedPath, req.handle), opReq);
10251
- return await (entry.gate ? entry.gate(resolvedPath, serve) : serve());
10301
+ return await gatedByHandle(entry, opEntry, resolvedPath, req, opReq);
10252
10302
  }
10253
10303
  if (!entry.own || !OWN_OPS.has(req.op)) return await run(opEntry, resolvedPath, opReq);
10254
10304
  const target = resolvedArg2 ?? (TWO_PATHS.has(req.op) ? fs.resolvePath(cwd, req.arg2 ?? "") : resolvedPath);
@@ -10880,6 +10930,8 @@ var SYS_TREE = {
10880
10930
  slicc_rename_ack_busy: (listing) => `${listing.renameAcks?.busy ?? 0}
10881
10931
  `,
10882
10932
  slicc_stale_fds: (listing) => `${listing.staleFds ?? 0}
10933
+ `,
10934
+ slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
10883
10935
  `,
10884
10936
  slicc_rename_acks: (listing) => {
10885
10937
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
@@ -19387,10 +19439,10 @@ function heldIo(fs, nodes, changed) {
19387
19439
  const held = await node(path);
19388
19440
  return held ? held.byName(() => held.pread(n, at)) : ranged2.pread(path, at, n, version);
19389
19441
  },
19390
- pwrite: (path, at, bytes, transfer) => write(
19442
+ pwrite: (path, at, bytes, transfer, options) => write(
19391
19443
  path,
19392
19444
  async (held) => void await held.pwrite(bytes, at),
19393
- () => ranged2.pwrite(path, at, bytes, transfer)
19445
+ () => ranged2.pwrite(path, at, bytes, transfer, options)
19394
19446
  ),
19395
19447
  truncate: (path, size) => write(
19396
19448
  path,
@@ -21675,11 +21727,13 @@ function holdingToken(opts, holds2, caller) {
21675
21727
  cwd: opts.cwd,
21676
21728
  ...opts.statfs ? { statfs: opts.statfs } : {},
21677
21729
  ...opts.renames ? { renames: opts.renames } : {},
21730
+ ...opts.fileId ? { fileId: opts.fileId } : {},
21678
21731
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
21679
- hold: (path, on, open, real, handle, ino) => holds2.hold(path, on, open, real, handle, ino),
21732
+ hold: (path, on, open, real, handle, ino, fid) => holds2.hold(path, on, open, real, handle, ino, fid),
21680
21733
  boundIno: holds2.boundIno.bind(holds2),
21681
21734
  trust: holds2.trust.bind(holds2),
21682
21735
  keptFor: (handle) => holds2.keptFor(handle),
21736
+ heldAt: (handle) => holds2.pathOf(handle),
21683
21737
  unlinked: (path) => holds2.keptAt(path),
21684
21738
  gate: (path, op) => opts.unlinkGate && holds2.holding(path) ? opts.unlinkGate.run(holds2.keyOf(path), op) : op(),
21685
21739
  own: (path, op) => holds2.own(path, op),
@@ -24095,9 +24149,10 @@ var OpfsFs = class {
24095
24149
  }
24096
24150
  async fileId(path) {
24097
24151
  const found = await this.locate(path, true);
24098
- const [entry] = await this.meta.get([found.path]);
24152
+ const [entry] = await (this.meta.fresh ?? this.meta.get).call(this.meta, [found.path]);
24099
24153
  if (entry?.fid !== void 0) return entry.fid;
24100
24154
  const fid = crypto.randomUUID();
24155
+ this.idWrites++;
24101
24156
  await this.meta.update(found.path, (now) => ({
24102
24157
  ...occupied(now),
24103
24158
  path: found.path,
@@ -24368,6 +24423,10 @@ var OpfsFs = class {
24368
24423
  opfsCalls() {
24369
24424
  return this.calls;
24370
24425
  }
24426
+ idWrites = 0;
24427
+ fileIdWrites() {
24428
+ return this.idWrites;
24429
+ }
24371
24430
  opfsOps() {
24372
24431
  return this.calls + this.others;
24373
24432
  }
@@ -24827,7 +24886,7 @@ var OpfsFs = class {
24827
24886
  return new Uint8Array(await file.slice(offset, offset + length2).arrayBuffer());
24828
24887
  });
24829
24888
  }
24830
- async pwrite(path, offset, bytes) {
24889
+ async pwrite(path, offset, bytes, _transfer, options) {
24831
24890
  const at = normalizePath(path);
24832
24891
  const movedAway = this.renamesInFlight() ? await this.writeWaits(at) : false;
24833
24892
  this.fileWrites.set(at, (this.fileWrites.get(at) ?? 0) + 1);
@@ -24842,7 +24901,10 @@ var OpfsFs = class {
24842
24901
  this.files.delete(target);
24843
24902
  }
24844
24903
  }
24845
- const [handle] = await this.fileFor(path, !existed && !movedAway);
24904
+ const [handle] = await this.fileFor(
24905
+ path,
24906
+ !existed && !movedAway && options?.create !== false
24907
+ );
24846
24908
  await this.writeAt(handle, target, path, offset, bytes);
24847
24909
  } finally {
24848
24910
  this.writeEnded(at);
@@ -29974,7 +30036,8 @@ var Launcher = class {
29974
30036
  opfsOps: this.rootFs.opfsOps?.() ?? 0,
29975
30037
  cwdChecks: this.cwds.checks,
29976
30038
  renameAcks: this.rootFs.renameWaits?.(),
29977
- staleFds: staleFdCount()
30039
+ staleFds: staleFdCount(),
30040
+ fileIds: this.rootFs.fileIdWrites?.() ?? 0
29978
30041
  }),
29979
30042
  sudo: (call, signal) => this.sudo(pid, call, signal),
29980
30043
  crontab: (call) => this.crontab(pid, call),
@@ -29985,6 +30048,7 @@ var Launcher = class {
29985
30048
  replacements: stack.unlinked,
29986
30049
  statfs: (path) => this.mounts.statfs(path),
29987
30050
  renames: (since2, held) => this.renameLog.since(since2, held),
30051
+ fileId: (path) => this.locks.shared?.() === true ? this.rootFileId(path) : void 0,
29988
30052
  renameSeq: (from, to) => this.renameLog.seqOf(from, to),
29989
30053
  mounts: () => this.mounts.list(),
29990
30054
  mount: (call, signal) => this.processMount(pid, call, signal),
@@ -30864,12 +30928,16 @@ var Launcher = class {
30864
30928
  this.writers ??= this.writerStack();
30865
30929
  return this.writers;
30866
30930
  }
30931
+ rootFileId(path) {
30932
+ return this.mounts.locate(path) === void 0 ? this.rootFs.fileId?.(path) : void 0;
30933
+ }
30867
30934
  flushingPeers(fs) {
30868
30935
  const peers = fs.peers?.();
30869
30936
  if (!peers) return void 0;
30870
30937
  peers.watch((crowded) => {
30871
30938
  this.changes.flush();
30872
30939
  this.changes.foreign(crowded);
30940
+ if (crowded) void this.held?.bindIds((path) => this.rootFileId(path));
30873
30941
  });
30874
30942
  return {
30875
30943
  ...peers,
@@ -30955,9 +31023,9 @@ var Launcher = class {
30955
31023
  }
30956
31024
  moved(from, to, source) {
30957
31025
  this.renameLog.add(from, to);
31026
+ for (const holds2 of this.held) holds2.renamed(from, to);
30958
31027
  if (source) return;
30959
31028
  for (const nodes of this.openFiles) nodes.renamed(from, to);
30960
- for (const holds2 of this.held) holds2.renamed(from, to);
30961
31029
  this.watchers.moved(from, to);
30962
31030
  }
30963
31031
  processChain(fs, nodes, unlinked) {