@ai-ecoverse/slicc-kernel 1.160.3 → 1.161.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
@@ -3675,7 +3675,7 @@ function satisfies(version, range2) {
3675
3675
  }
3676
3676
 
3677
3677
  // src/version.ts
3678
- var KERNEL_VERSION = true ? "1.160.3" : "0.0.0-dev";
3678
+ var KERNEL_VERSION = true ? "1.161.0" : "0.0.0-dev";
3679
3679
  var OS_RELEASE = "6.0.0-slicc";
3680
3680
  function procVersion() {
3681
3681
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8919,12 +8919,15 @@ function linkedTo(mount, path) {
8919
8919
  var within5 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
8920
8920
  var HeldSet = class extends Set {
8921
8921
  idle;
8922
- constructor(idle2) {
8922
+ moved;
8923
+ constructor(idle2, moved2) {
8923
8924
  super();
8924
8925
  this.idle = idle2;
8926
+ this.moved = moved2;
8925
8927
  }
8926
8928
  add(holds2) {
8927
8929
  holds2.onIdle = this.idle;
8930
+ holds2.onMoved = this.moved;
8928
8931
  return super.add(holds2);
8929
8932
  }
8930
8933
  doubt(paths, over) {
@@ -8961,6 +8964,7 @@ var HeldPaths = class extends Map {
8961
8964
  doubted = /* @__PURE__ */ new Map();
8962
8965
  doubts = 0;
8963
8966
  onIdle;
8967
+ onMoved;
8964
8968
  keyOf(path) {
8965
8969
  return this.aliases.get(path) ?? path;
8966
8970
  }
@@ -9121,6 +9125,7 @@ var HeldPaths = class extends Map {
9121
9125
  for (const [id2, key] of this.handles) {
9122
9126
  if (within5(key, from)) this.handles.set(id2, to + key.slice(from.length));
9123
9127
  }
9128
+ this.onMoved?.(from, to);
9124
9129
  }
9125
9130
  isRevoked(path) {
9126
9131
  return this.revoked.has(path);
@@ -10748,12 +10753,18 @@ async function holdOp(entry, path, req) {
10748
10753
  if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
10749
10754
  const fid = req.ino === void 0 ? void 0 : await idOf(entry, real ?? path);
10750
10755
  if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
10751
- return json2(entry.hold?.(path, on, open, real, void 0, req.ino, fid) ?? null);
10756
+ return json2(await heldOpen(entry, path, real, req, fid));
10752
10757
  }
10753
10758
  }
10754
10759
  entry.hold?.(path, on, open, void 0, req.handle);
10755
10760
  return done;
10756
10761
  }
10762
+ async function heldOpen(entry, path, real, req, fid) {
10763
+ const handle = entry.hold?.(path, true, true, real, void 0, req.ino, fid);
10764
+ if (handle === void 0) return null;
10765
+ await entry.announceHold?.(real ?? path, fid, ((req.mode ?? 0) & HOLD_CREATED) !== 0);
10766
+ return handle;
10767
+ }
10757
10768
  async function idOf(entry, path) {
10758
10769
  return await entry.fileId?.(path)?.catch(() => void 0) ?? void 0;
10759
10770
  }
@@ -11771,6 +11782,10 @@ var SYS_TREE = {
11771
11782
  `,
11772
11783
  slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
11773
11784
  `,
11785
+ slicc_peer_holds: ({ holds: holds2 }) => `${holds2?.mine ?? 0} ${holds2?.peers ?? 0} ${holds2?.sent ?? 0}
11786
+ `,
11787
+ slicc_peer_held: ({ holds: holds2 }) => (holds2?.held ?? []).map((path) => `${path}
11788
+ `).join(""),
11774
11789
  slicc_rename_acks: (listing) => {
11775
11790
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
11776
11791
  const median = samples[Math.floor(samples.length / 2)] ?? 0;
@@ -22853,6 +22868,7 @@ function holdingToken(opts, holds2, caller) {
22853
22868
  ...opts.statfs ? { statfs: opts.statfs } : {},
22854
22869
  ...opts.renames ? { renames: opts.renames } : {},
22855
22870
  ...opts.fileId ? { fileId: opts.fileId } : {},
22871
+ ...opts.announceHold ? { announceHold: opts.announceHold } : {},
22856
22872
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
22857
22873
  hold: (path, on, open, real, handle, ino, fid) => holds2.hold(path, on, open, real, handle, ino, fid),
22858
22874
  boundIno: holds2.boundIno.bind(holds2),
@@ -23404,6 +23420,11 @@ var RemoteWatch = class {
23404
23420
  mourned = /* @__PURE__ */ new Set();
23405
23421
  others = /* @__PURE__ */ new Map();
23406
23422
  union = /* @__PURE__ */ new Set();
23423
+ myHolds = /* @__PURE__ */ new Map();
23424
+ peerHolds = /* @__PURE__ */ new Map();
23425
+ holdsSent = 0;
23426
+ silent = /* @__PURE__ */ new Set();
23427
+ holders = /* @__PURE__ */ new Set();
23407
23428
  listeners = /* @__PURE__ */ new Set();
23408
23429
  waiting = /* @__PURE__ */ new Map();
23409
23430
  locks;
@@ -23447,7 +23468,7 @@ var RemoteWatch = class {
23447
23468
  this.settled = true;
23448
23469
  this.recount();
23449
23470
  });
23450
- this.channel.postMessage({ hello: this.tab, renames: true });
23471
+ this.channel.postMessage({ hello: this.tab, renames: true, keeps: true });
23451
23472
  }
23452
23473
  async join() {
23453
23474
  if (!this.locks) return;
@@ -23507,8 +23528,12 @@ var RemoteWatch = class {
23507
23528
  return `${this.name}:${tab}`;
23508
23529
  }
23509
23530
  receive(data) {
23531
+ const spoke = data.hello ?? data.here ?? data.tab ?? data.from;
23532
+ if (spoke !== void 0) this.silent.delete(spoke);
23510
23533
  const sender = data.hello ?? data.here ?? (data.paths !== void 0 ? data.tab : void 0);
23511
23534
  if (sender !== void 0 && data.renames) this.ackers.add(sender);
23535
+ const keeper = data.hello ?? data.here;
23536
+ if (keeper !== void 0 && data.keeps) this.holders.add(keeper);
23512
23537
  if (data.hello !== void 0) this.greeted(data.hello);
23513
23538
  if (data.renaming !== void 0 && data.tab !== void 0) this.heard(data);
23514
23539
  if (data.renamed !== void 0) this.renamed?.(data.renamed);
@@ -23519,6 +23544,7 @@ var RemoteWatch = class {
23519
23544
  this.met?.();
23520
23545
  }
23521
23546
  if (data.tab !== void 0 && data.paths !== void 0) this.announced(data);
23547
+ if (data.tab !== void 0 && data.holds !== void 0) this.heldBy(data);
23522
23548
  if (data.ack !== void 0 && data.to === this.tab && data.from !== void 0) {
23523
23549
  this.acked(data.ack, data.from);
23524
23550
  }
@@ -23545,8 +23571,10 @@ var RemoteWatch = class {
23545
23571
  void this.locks.request(name2, async () => {
23546
23572
  this.mourned.delete(peer);
23547
23573
  this.others.delete(peer);
23574
+ this.peerHolds.delete(peer);
23548
23575
  this.peers.delete(peer);
23549
23576
  this.ackers.delete(peer);
23577
+ this.holders.delete(peer);
23550
23578
  this.flushedAt(peer);
23551
23579
  this.rebuild();
23552
23580
  this.recount();
@@ -23559,8 +23587,9 @@ var RemoteWatch = class {
23559
23587
  greeted(peer) {
23560
23588
  this.arrived(peer);
23561
23589
  const answer2 = () => {
23562
- this.channel.postMessage({ here: this.tab, to: peer, renames: true });
23590
+ this.channel.postMessage({ here: this.tab, to: peer, renames: true, keeps: true });
23563
23591
  if (this.mine.length > 0) void this.announce(this.mine);
23592
+ if (this.myHolds.size > 0) this.sendHolds([...this.myHolds], []);
23564
23593
  };
23565
23594
  if (!this.quiet) {
23566
23595
  answer2();
@@ -23583,6 +23612,69 @@ var RemoteWatch = class {
23583
23612
  this.rebuild();
23584
23613
  this.channel.postMessage({ ack: seq2, from: this.tab, to: from });
23585
23614
  }
23615
+ heldBy({ tab, holds: holds2, seq: seq2 }) {
23616
+ const from = tab;
23617
+ const { add, drop } = holds2;
23618
+ const held = this.peerHolds.get(from) ?? /* @__PURE__ */ new Map();
23619
+ for (const path of drop) held.delete(path);
23620
+ for (const [path, fid] of add) held.set(path, fid);
23621
+ if (held.size > 0) this.peerHolds.set(from, held);
23622
+ else this.peerHolds.delete(from);
23623
+ this.channel.postMessage({ ack: seq2, from: this.tab, to: from });
23624
+ }
23625
+ hold(add, drop, wait2) {
23626
+ const fresh3 = add.filter(
23627
+ ([path, fid]) => !this.myHolds.has(path) || this.myHolds.get(path) !== fid
23628
+ );
23629
+ const gone = drop.filter((path) => this.myHolds.has(path));
23630
+ for (const path of gone) this.myHolds.delete(path);
23631
+ for (const [path, fid] of fresh3) this.myHolds.set(path, fid);
23632
+ if (fresh3.length === 0 && gone.length === 0 || this.peers.size === 0)
23633
+ return Promise.resolve();
23634
+ const seq2 = this.sendHolds(fresh3, gone);
23635
+ if (!wait2) return Promise.resolve();
23636
+ const heard = new Set(
23637
+ [...this.peers].filter((peer) => this.holders.has(peer) && !this.silent.has(peer))
23638
+ );
23639
+ return this.acks(seq2, heard, (left) => {
23640
+ for (const peer of left) this.silent.add(peer);
23641
+ });
23642
+ }
23643
+ rehold(from, to) {
23644
+ const add = [];
23645
+ const drop = [];
23646
+ for (const [path, fid] of [...this.myHolds]) {
23647
+ if (path !== from && !path.startsWith(`${from}/`)) continue;
23648
+ const moved2 = to + path.slice(from.length);
23649
+ this.myHolds.delete(path);
23650
+ this.myHolds.set(moved2, fid);
23651
+ drop.push(path);
23652
+ add.push([moved2, fid]);
23653
+ }
23654
+ if (drop.length > 0 && this.peers.size > 0) this.sendHolds(add, drop);
23655
+ }
23656
+ sendHolds(add, drop) {
23657
+ const seq2 = ++this.seq;
23658
+ this.holdsSent++;
23659
+ this.channel.postMessage({ tab: this.tab, holds: { add: [...add], drop: [...drop] }, seq: seq2 });
23660
+ return seq2;
23661
+ }
23662
+ peerHeld(path) {
23663
+ const out = [];
23664
+ for (const [tab, held] of this.peerHolds)
23665
+ if (held.has(path)) out.push({ tab, fid: held.get(path) });
23666
+ return out;
23667
+ }
23668
+ peerHeldPaths() {
23669
+ const out = /* @__PURE__ */ new Set();
23670
+ for (const held of this.peerHolds.values()) for (const path of held.keys()) out.add(path);
23671
+ return [...out].sort();
23672
+ }
23673
+ holdCounts() {
23674
+ let peers = 0;
23675
+ for (const held of this.peerHolds.values()) peers += held.size;
23676
+ return { mine: this.myHolds.size, peers, sent: this.holdsSent };
23677
+ }
23586
23678
  acked(seq2, from) {
23587
23679
  const wait2 = this.waiting.get(seq2);
23588
23680
  if (!wait2) return;
@@ -23597,11 +23689,13 @@ var RemoteWatch = class {
23597
23689
  if (!this.locks) return;
23598
23690
  const held = new Set(((await this.locks.query()).held ?? []).map((lock) => lock.name));
23599
23691
  let left = false;
23600
- for (const tab of /* @__PURE__ */ new Set([...this.others.keys(), ...this.peers])) {
23692
+ for (const tab of /* @__PURE__ */ new Set([...this.others.keys(), ...this.peers, ...this.peerHolds.keys()])) {
23601
23693
  if (!held.has(this.lockOf(tab))) {
23602
23694
  if (this.peers.delete(tab)) left = true;
23603
23695
  this.others.delete(tab);
23696
+ this.peerHolds.delete(tab);
23604
23697
  this.ackers.delete(tab);
23698
+ this.holders.delete(tab);
23605
23699
  }
23606
23700
  }
23607
23701
  this.rebuild();
@@ -23649,8 +23743,9 @@ var RemoteWatch = class {
23649
23743
  renamedTree(lock) {
23650
23744
  this.channel.postMessage({ renamed: lock });
23651
23745
  }
23652
- acks(seq2, from) {
23746
+ acks(seq2, from, missed) {
23653
23747
  if (from.size === 0) return Promise.resolve();
23748
+ const left = new Set(from);
23654
23749
  return new Promise((resolve2) => {
23655
23750
  const done4 = () => {
23656
23751
  clearTimeout(timer);
@@ -23658,10 +23753,11 @@ var RemoteWatch = class {
23658
23753
  resolve2();
23659
23754
  };
23660
23755
  const timer = setTimeout(() => {
23756
+ missed?.(left);
23661
23757
  done4();
23662
23758
  void this.prune();
23663
23759
  }, ANNOUNCE_WAIT_MS);
23664
- this.waiting.set(seq2, { left: new Set(from), done: done4 });
23760
+ this.waiting.set(seq2, { left, done: done4 });
23665
23761
  });
23666
23762
  }
23667
23763
  emit(change) {
@@ -25342,6 +25438,16 @@ var OpfsFs = class {
25342
25438
  return this.remote?.listen(listener) ?? (() => {
25343
25439
  });
25344
25440
  }
25441
+ announceHolds(add, drop, wait2) {
25442
+ return this.remote?.hold(add, drop, wait2) ?? Promise.resolve();
25443
+ }
25444
+ holdCounts() {
25445
+ const remote = this.remote;
25446
+ return remote && { ...remote.holdCounts(), held: remote.peerHeldPaths() };
25447
+ }
25448
+ rehold(from, to) {
25449
+ this.remote?.rehold(from, to);
25450
+ }
25345
25451
  announceWatch(paths) {
25346
25452
  return this.remote?.announce(paths) ?? Promise.resolve();
25347
25453
  }
@@ -30034,7 +30140,12 @@ var Launcher = class {
30034
30140
  identities = { asked: 0, timedOut: 0 };
30035
30141
  nodes;
30036
30142
  unlinked;
30037
- held = new HeldSet((path) => this.released(path));
30143
+ held = new HeldSet(
30144
+ (path) => this.released(path),
30145
+ (from, to) => {
30146
+ if (this.mounts.locate(to) === void 0) this.rootFs.rehold?.(from, to);
30147
+ }
30148
+ );
30038
30149
  processMounts;
30039
30150
  booting = new AbortController();
30040
30151
  fstab = Promise.resolve([]);
@@ -31252,7 +31363,8 @@ var Launcher = class {
31252
31363
  cwdChecks: this.cwds.checks,
31253
31364
  renameAcks: this.rootFs.renameWaits?.(),
31254
31365
  staleFds: staleFdCount(),
31255
- fileIds: this.rootFs.fileIdWrites?.() ?? 0
31366
+ fileIds: this.rootFs.fileIdWrites?.() ?? 0,
31367
+ holds: this.rootFs.holdCounts?.()
31256
31368
  }),
31257
31369
  sudo: (call, signal) => this.sudo(pid, call, signal),
31258
31370
  crontab: (call) => this.crontab(pid, call),
@@ -31264,6 +31376,7 @@ var Launcher = class {
31264
31376
  statfs: (path) => this.mounts.statfs(path),
31265
31377
  renames: (since2, held) => this.renameLog.since(since2, held),
31266
31378
  fileId: (path) => this.locks.shared?.() === true ? this.rootFileId(path) : void 0,
31379
+ announceHold: (path, fid, created4) => this.locks.shared?.() === true && this.mounts.locate(path) === void 0 ? this.rootFs.announceHolds?.([[path, fid]], [], !created4) : void 0,
31267
31380
  renameSeq: (from, to) => this.renameLog.seqOf(from, to),
31268
31381
  mounts: () => this.mounts.list(),
31269
31382
  mount: (call, signal) => this.processMount(pid, call, signal),
@@ -31705,6 +31818,8 @@ var Launcher = class {
31705
31818
  const at = normalizePath(path);
31706
31819
  this.unlinked.closed(at);
31707
31820
  this.writers?.unlinked.closed(at);
31821
+ if (![...this.held].some((holds2) => holds2.holding(at)))
31822
+ void this.rootFs.announceHolds?.([], [at], false);
31708
31823
  const open = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
31709
31824
  if (!open) void this.mounts.commit(at).catch(() => void 0);
31710
31825
  }