@ai-ecoverse/slicc-kernel 1.160.2 → 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
@@ -1,6 +1,8 @@
1
1
  // src/node.ts
2
2
  import { createHash } from "node:crypto";
3
- import { isAbsolute } from "node:path";
3
+ import { lstatSync, mkdtempSync, readdirSync, rmSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { isAbsolute, join } from "node:path";
4
6
  import { MessageChannel as MessageChannel2, Worker } from "node:worker_threads";
5
7
 
6
8
  // src/bytes.ts
@@ -3673,7 +3675,7 @@ function satisfies(version, range2) {
3673
3675
  }
3674
3676
 
3675
3677
  // src/version.ts
3676
- var KERNEL_VERSION = true ? "1.160.2" : "0.0.0-dev";
3678
+ var KERNEL_VERSION = true ? "1.161.0" : "0.0.0-dev";
3677
3679
  var OS_RELEASE = "6.0.0-slicc";
3678
3680
  function procVersion() {
3679
3681
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -8917,12 +8919,15 @@ function linkedTo(mount, path) {
8917
8919
  var within5 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
8918
8920
  var HeldSet = class extends Set {
8919
8921
  idle;
8920
- constructor(idle2) {
8922
+ moved;
8923
+ constructor(idle2, moved2) {
8921
8924
  super();
8922
8925
  this.idle = idle2;
8926
+ this.moved = moved2;
8923
8927
  }
8924
8928
  add(holds2) {
8925
8929
  holds2.onIdle = this.idle;
8930
+ holds2.onMoved = this.moved;
8926
8931
  return super.add(holds2);
8927
8932
  }
8928
8933
  doubt(paths, over) {
@@ -8959,6 +8964,7 @@ var HeldPaths = class extends Map {
8959
8964
  doubted = /* @__PURE__ */ new Map();
8960
8965
  doubts = 0;
8961
8966
  onIdle;
8967
+ onMoved;
8962
8968
  keyOf(path) {
8963
8969
  return this.aliases.get(path) ?? path;
8964
8970
  }
@@ -9119,6 +9125,7 @@ var HeldPaths = class extends Map {
9119
9125
  for (const [id2, key] of this.handles) {
9120
9126
  if (within5(key, from)) this.handles.set(id2, to + key.slice(from.length));
9121
9127
  }
9128
+ this.onMoved?.(from, to);
9122
9129
  }
9123
9130
  isRevoked(path) {
9124
9131
  return this.revoked.has(path);
@@ -10746,12 +10753,18 @@ async function holdOp(entry, path, req) {
10746
10753
  if (req.nofollow && !await ownEntry(entry, path, real ?? path)) continue;
10747
10754
  const fid = req.ino === void 0 ? void 0 : await idOf(entry, real ?? path);
10748
10755
  if (!r || !r.missed(path) && !r.changedSince(path, gen) && !r.inFlight?.(path))
10749
- return json2(entry.hold?.(path, on, open, real, void 0, req.ino, fid) ?? null);
10756
+ return json2(await heldOpen(entry, path, real, req, fid));
10750
10757
  }
10751
10758
  }
10752
10759
  entry.hold?.(path, on, open, void 0, req.handle);
10753
10760
  return done;
10754
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
+ }
10755
10768
  async function idOf(entry, path) {
10756
10769
  return await entry.fileId?.(path)?.catch(() => void 0) ?? void 0;
10757
10770
  }
@@ -11769,6 +11782,10 @@ var SYS_TREE = {
11769
11782
  `,
11770
11783
  slicc_file_ids: (listing) => `${listing.fileIds ?? 0}
11771
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(""),
11772
11789
  slicc_rename_acks: (listing) => {
11773
11790
  const samples = [...listing.renameAcks?.ackMs ?? []].sort((a, b) => a - b);
11774
11791
  const median = samples[Math.floor(samples.length / 2)] ?? 0;
@@ -22851,6 +22868,7 @@ function holdingToken(opts, holds2, caller) {
22851
22868
  ...opts.statfs ? { statfs: opts.statfs } : {},
22852
22869
  ...opts.renames ? { renames: opts.renames } : {},
22853
22870
  ...opts.fileId ? { fileId: opts.fileId } : {},
22871
+ ...opts.announceHold ? { announceHold: opts.announceHold } : {},
22854
22872
  ...opts.renameSeq ? { renameSeq: opts.renameSeq } : {},
22855
22873
  hold: (path, on, open, real, handle, ino, fid) => holds2.hold(path, on, open, real, handle, ino, fid),
22856
22874
  boundIno: holds2.boundIno.bind(holds2),
@@ -23402,6 +23420,11 @@ var RemoteWatch = class {
23402
23420
  mourned = /* @__PURE__ */ new Set();
23403
23421
  others = /* @__PURE__ */ new Map();
23404
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();
23405
23428
  listeners = /* @__PURE__ */ new Set();
23406
23429
  waiting = /* @__PURE__ */ new Map();
23407
23430
  locks;
@@ -23445,7 +23468,7 @@ var RemoteWatch = class {
23445
23468
  this.settled = true;
23446
23469
  this.recount();
23447
23470
  });
23448
- this.channel.postMessage({ hello: this.tab, renames: true });
23471
+ this.channel.postMessage({ hello: this.tab, renames: true, keeps: true });
23449
23472
  }
23450
23473
  async join() {
23451
23474
  if (!this.locks) return;
@@ -23505,8 +23528,12 @@ var RemoteWatch = class {
23505
23528
  return `${this.name}:${tab}`;
23506
23529
  }
23507
23530
  receive(data) {
23531
+ const spoke = data.hello ?? data.here ?? data.tab ?? data.from;
23532
+ if (spoke !== void 0) this.silent.delete(spoke);
23508
23533
  const sender = data.hello ?? data.here ?? (data.paths !== void 0 ? data.tab : void 0);
23509
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);
23510
23537
  if (data.hello !== void 0) this.greeted(data.hello);
23511
23538
  if (data.renaming !== void 0 && data.tab !== void 0) this.heard(data);
23512
23539
  if (data.renamed !== void 0) this.renamed?.(data.renamed);
@@ -23517,6 +23544,7 @@ var RemoteWatch = class {
23517
23544
  this.met?.();
23518
23545
  }
23519
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);
23520
23548
  if (data.ack !== void 0 && data.to === this.tab && data.from !== void 0) {
23521
23549
  this.acked(data.ack, data.from);
23522
23550
  }
@@ -23543,8 +23571,10 @@ var RemoteWatch = class {
23543
23571
  void this.locks.request(name2, async () => {
23544
23572
  this.mourned.delete(peer);
23545
23573
  this.others.delete(peer);
23574
+ this.peerHolds.delete(peer);
23546
23575
  this.peers.delete(peer);
23547
23576
  this.ackers.delete(peer);
23577
+ this.holders.delete(peer);
23548
23578
  this.flushedAt(peer);
23549
23579
  this.rebuild();
23550
23580
  this.recount();
@@ -23557,8 +23587,9 @@ var RemoteWatch = class {
23557
23587
  greeted(peer) {
23558
23588
  this.arrived(peer);
23559
23589
  const answer2 = () => {
23560
- this.channel.postMessage({ here: this.tab, to: peer, renames: true });
23590
+ this.channel.postMessage({ here: this.tab, to: peer, renames: true, keeps: true });
23561
23591
  if (this.mine.length > 0) void this.announce(this.mine);
23592
+ if (this.myHolds.size > 0) this.sendHolds([...this.myHolds], []);
23562
23593
  };
23563
23594
  if (!this.quiet) {
23564
23595
  answer2();
@@ -23581,6 +23612,69 @@ var RemoteWatch = class {
23581
23612
  this.rebuild();
23582
23613
  this.channel.postMessage({ ack: seq2, from: this.tab, to: from });
23583
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
+ }
23584
23678
  acked(seq2, from) {
23585
23679
  const wait2 = this.waiting.get(seq2);
23586
23680
  if (!wait2) return;
@@ -23595,11 +23689,13 @@ var RemoteWatch = class {
23595
23689
  if (!this.locks) return;
23596
23690
  const held = new Set(((await this.locks.query()).held ?? []).map((lock) => lock.name));
23597
23691
  let left = false;
23598
- 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()])) {
23599
23693
  if (!held.has(this.lockOf(tab))) {
23600
23694
  if (this.peers.delete(tab)) left = true;
23601
23695
  this.others.delete(tab);
23696
+ this.peerHolds.delete(tab);
23602
23697
  this.ackers.delete(tab);
23698
+ this.holders.delete(tab);
23603
23699
  }
23604
23700
  }
23605
23701
  this.rebuild();
@@ -23647,8 +23743,9 @@ var RemoteWatch = class {
23647
23743
  renamedTree(lock) {
23648
23744
  this.channel.postMessage({ renamed: lock });
23649
23745
  }
23650
- acks(seq2, from) {
23746
+ acks(seq2, from, missed) {
23651
23747
  if (from.size === 0) return Promise.resolve();
23748
+ const left = new Set(from);
23652
23749
  return new Promise((resolve2) => {
23653
23750
  const done4 = () => {
23654
23751
  clearTimeout(timer);
@@ -23656,10 +23753,11 @@ var RemoteWatch = class {
23656
23753
  resolve2();
23657
23754
  };
23658
23755
  const timer = setTimeout(() => {
23756
+ missed?.(left);
23659
23757
  done4();
23660
23758
  void this.prune();
23661
23759
  }, ANNOUNCE_WAIT_MS);
23662
- this.waiting.set(seq2, { left: new Set(from), done: done4 });
23760
+ this.waiting.set(seq2, { left, done: done4 });
23663
23761
  });
23664
23762
  }
23665
23763
  emit(change) {
@@ -25340,6 +25438,16 @@ var OpfsFs = class {
25340
25438
  return this.remote?.listen(listener) ?? (() => {
25341
25439
  });
25342
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
+ }
25343
25451
  announceWatch(paths) {
25344
25452
  return this.remote?.announce(paths) ?? Promise.resolve();
25345
25453
  }
@@ -30032,7 +30140,12 @@ var Launcher = class {
30032
30140
  identities = { asked: 0, timedOut: 0 };
30033
30141
  nodes;
30034
30142
  unlinked;
30035
- 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
+ );
30036
30149
  processMounts;
30037
30150
  booting = new AbortController();
30038
30151
  fstab = Promise.resolve([]);
@@ -31250,7 +31363,8 @@ var Launcher = class {
31250
31363
  cwdChecks: this.cwds.checks,
31251
31364
  renameAcks: this.rootFs.renameWaits?.(),
31252
31365
  staleFds: staleFdCount(),
31253
- fileIds: this.rootFs.fileIdWrites?.() ?? 0
31366
+ fileIds: this.rootFs.fileIdWrites?.() ?? 0,
31367
+ holds: this.rootFs.holdCounts?.()
31254
31368
  }),
31255
31369
  sudo: (call, signal) => this.sudo(pid, call, signal),
31256
31370
  crontab: (call) => this.crontab(pid, call),
@@ -31262,6 +31376,7 @@ var Launcher = class {
31262
31376
  statfs: (path) => this.mounts.statfs(path),
31263
31377
  renames: (since2, held) => this.renameLog.since(since2, held),
31264
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,
31265
31380
  renameSeq: (from, to) => this.renameLog.seqOf(from, to),
31266
31381
  mounts: () => this.mounts.list(),
31267
31382
  mount: (call, signal) => this.processMount(pid, call, signal),
@@ -31703,6 +31818,8 @@ var Launcher = class {
31703
31818
  const at = normalizePath(path);
31704
31819
  this.unlinked.closed(at);
31705
31820
  this.writers?.unlinked.closed(at);
31821
+ if (![...this.held].some((holds2) => holds2.holding(at)))
31822
+ void this.rootFs.announceHolds?.([], [at], false);
31706
31823
  const open = [...this.openFiles].some((nodes) => nodes.writes(at)) || heldUnder(this.held, at);
31707
31824
  if (!open) void this.mounts.commit(at).catch(() => void 0);
31708
31825
  }
@@ -34877,12 +34994,72 @@ function workerEnv() {
34877
34994
  const { NODE_COMPILE_CACHE: _inherited, ...env } = process.env;
34878
34995
  return env;
34879
34996
  }
34997
+ var CACHE_PREFIX = "slicc-kernel-cc-";
34880
34998
  function cacheDirOf(dir) {
34881
- if (dir === void 0) return void 0;
34999
+ if (dir === false) return void 0;
35000
+ if (dir === void 0) return ownCacheDir();
34882
35001
  if (typeof dir !== "string" || !isAbsolute(dir)) {
34883
- throw new TypeError("createNodeKernel: compileCache must be an absolute directory path");
35002
+ throw new TypeError(
35003
+ "createNodeKernel: compileCache must be an absolute directory path or false"
35004
+ );
35005
+ }
35006
+ return { dir, own: false };
35007
+ }
35008
+ function cacheData(cache) {
35009
+ if (!cache) return void 0;
35010
+ return { compileCache: cache.dir, ...cache.own ? { ownedCache: true } : {} };
35011
+ }
35012
+ function dropCache(cache) {
35013
+ if (!cache?.own) return;
35014
+ try {
35015
+ rmSync(cache.dir, { recursive: true, force: true });
35016
+ } catch {
35017
+ }
35018
+ }
35019
+ function ownCacheDir(make = privateCacheDir) {
35020
+ try {
35021
+ return { dir: make(), own: true };
35022
+ } catch {
35023
+ return void 0;
35024
+ }
35025
+ }
35026
+ var swept = false;
35027
+ function privateCacheDir(base = tmpdir(), alive = pidAlive) {
35028
+ if (!swept) {
35029
+ swept = true;
35030
+ sweepCacheDirs(base, alive);
35031
+ }
35032
+ return mkdtempSync(join(base, `${CACHE_PREFIX}${process.pid}-`));
35033
+ }
35034
+ function sweepCacheDirs(base, alive = pidAlive, uid = process.getuid?.()) {
35035
+ let names2;
35036
+ try {
35037
+ names2 = readdirSync(base);
35038
+ } catch {
35039
+ return;
35040
+ }
35041
+ for (const name2 of names2) {
35042
+ if (!name2.startsWith(CACHE_PREFIX)) continue;
35043
+ const pid = Number(name2.slice(CACHE_PREFIX.length).split("-")[0]);
35044
+ if (!Number.isInteger(pid) || pid <= 0 || alive(pid)) continue;
35045
+ removeOurs(join(base, name2), uid);
35046
+ }
35047
+ }
35048
+ function removeOurs(path, uid) {
35049
+ try {
35050
+ const st = lstatSync(path);
35051
+ if (!st.isDirectory() || uid !== void 0 && st.uid !== uid) return;
35052
+ rmSync(path, { recursive: true, force: true });
35053
+ } catch {
35054
+ }
35055
+ }
35056
+ function pidAlive(pid) {
35057
+ try {
35058
+ process.kill(pid, 0);
35059
+ return true;
35060
+ } catch (err) {
35061
+ return err.code === "EPERM";
34884
35062
  }
34885
- return dir;
34886
35063
  }
34887
35064
  var nodeSessions = 0;
34888
35065
  function nodeClient(launcher, clients, { user, tag, requests }) {
@@ -34918,8 +35095,8 @@ async function createNodeKernel(options = {}) {
34918
35095
  const clients = /* @__PURE__ */ new Set();
34919
35096
  let terminated = false;
34920
35097
  const file = options.worker ?? new URL("./node-process-worker.js", import.meta.url);
34921
- const compileCache = cacheDirOf(options.compileCache);
34922
- const workerData = compileCache ? { compileCache } : void 0;
35098
+ const cache = cacheDirOf(options.compileCache);
35099
+ const workerData = cacheData(cache);
34923
35100
  const warm = warmPoolOf(options, file, workerData, live);
34924
35101
  const transport = options.network?.transport;
34925
35102
  const launcher = new Launcher({
@@ -35057,6 +35234,7 @@ async function createNodeKernel(options = {}) {
35057
35234
  for (const kill of [...live]) kill();
35058
35235
  launcher.cdp.close();
35059
35236
  launcher.unmountAll();
35237
+ dropCache(cache);
35060
35238
  }
35061
35239
  };
35062
35240
  }
@@ -35070,9 +35248,12 @@ export {
35070
35248
  fetchTransport,
35071
35249
  memoryRoot,
35072
35250
  nodeTransport,
35251
+ ownCacheDir,
35252
+ privateCacheDir,
35073
35253
  serveHostfsPort,
35074
35254
  sourceModule,
35075
35255
  sparesOf,
35256
+ sweepCacheDirs,
35076
35257
  warmPool
35077
35258
  };
35078
35259
  //# sourceMappingURL=node.js.map