@ai-ecoverse/slicc-kernel 1.124.3 → 1.124.5

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
@@ -4505,9 +4505,13 @@ var OpfsFs = class {
4505
4505
  if (this.remote) this.remote.quiet = () => this.quiet().then(() => this.settle?.());
4506
4506
  if (this.channel) {
4507
4507
  const remote = this.remote;
4508
- meta.listen?.(
4509
- (c) => remote?.emit({ paths: c.paths ?? [], trees: c.trees ?? [] })
4510
- );
4508
+ meta.listen?.((c) => {
4509
+ for (const path of [...c.paths ?? [], ...c.trees ?? []]) this.forget(path);
4510
+ remote?.emit({ paths: c.paths ?? [], trees: c.trees ?? [] });
4511
+ });
4512
+ remote?.listen((c) => {
4513
+ for (const path of [...c.paths, ...c.trees]) this.forget(path);
4514
+ });
4511
4515
  this.channel.onmessage = ({ data }) => {
4512
4516
  for (const path of data) this.forget(path);
4513
4517
  remote?.emit({ paths: data, trees: [] });
@@ -4668,9 +4672,13 @@ var OpfsFs = class {
4668
4672
  joined: () => remote.peered(),
4669
4673
  crowded: () => remote.crowded(),
4670
4674
  watch: (listener) => {
4671
- remote.crowd = listener;
4675
+ remote.crowd = (crowded) => {
4676
+ this.fresh();
4677
+ listener(crowded);
4678
+ };
4672
4679
  listener(remote.crowded());
4673
- }
4680
+ },
4681
+ fresh: () => this.fresh()
4674
4682
  };
4675
4683
  }
4676
4684
  quiet() {
@@ -4723,6 +4731,7 @@ var OpfsFs = class {
4723
4731
  async walk(parts2, from, start2) {
4724
4732
  let dir = start2;
4725
4733
  for (let at = from; at < parts2.length; at++) {
4734
+ this.calls++;
4726
4735
  dir = await dir.getDirectoryHandle(parts2[at]);
4727
4736
  this.dirs.set(`/${parts2.slice(0, at + 1).join("/")}`, dir);
4728
4737
  this.checked.set(dir, performance.now());
@@ -4751,11 +4760,29 @@ var OpfsFs = class {
4751
4760
  async current(path, dir) {
4752
4761
  if (dir === this.root) return path === "/";
4753
4762
  if (performance.now() - (this.checked.get(dir) ?? -CHECK_MS) < CHECK_MS) return true;
4763
+ this.calls++;
4754
4764
  const where = await this.root.resolve(dir).catch(() => null);
4755
4765
  if (where === null || `/${where.join("/")}` !== path) return false;
4756
4766
  this.checked.set(dir, performance.now());
4757
4767
  return true;
4758
4768
  }
4769
+ exact = 0;
4770
+ calls = 0;
4771
+ opfsCalls() {
4772
+ return this.calls;
4773
+ }
4774
+ fresh() {
4775
+ this.changes++;
4776
+ this.absent.clear();
4777
+ }
4778
+ async exactly(op) {
4779
+ this.exact++;
4780
+ try {
4781
+ return await op();
4782
+ } finally {
4783
+ this.exact--;
4784
+ }
4785
+ }
4759
4786
  forget(path) {
4760
4787
  this.changes++;
4761
4788
  this.dirs.deleteTree(path);
@@ -4790,6 +4817,7 @@ var OpfsFs = class {
4790
4817
  }
4791
4818
  }
4792
4819
  async child(parent, name2, kind) {
4820
+ this.calls++;
4793
4821
  return kind === "file" ? parent.getFileHandle(name2) : parent.getDirectoryHandle(name2);
4794
4822
  }
4795
4823
  async parent(path) {
@@ -4818,7 +4846,7 @@ var OpfsFs = class {
4818
4846
  const kept = this.dirs.get(path);
4819
4847
  if (kept && await this.current(path, kept)) return kept;
4820
4848
  const gone = this.absent.get(path);
4821
- if (gone !== void 0 && !this.shared() && performance.now() - gone < ABSENT_MS) {
4849
+ if (gone !== void 0 && this.exact === 0 && performance.now() - gone < ABSENT_MS) {
4822
4850
  throw translate({ name: "NotFoundError" }, path);
4823
4851
  }
4824
4852
  const seen = this.changes;
@@ -4979,6 +5007,7 @@ var OpfsFs = class {
4979
5007
  flushing = {};
4980
5008
  touch(now, ...dirs) {
4981
5009
  this.changes++;
5010
+ if (this.shared()) this.channel?.postMessage(dirs);
4982
5011
  for (const dir of dirs) {
4983
5012
  this.absent.deleteTree(dir);
4984
5013
  this.dirTimes.set(dir, now);
@@ -5010,7 +5039,7 @@ var OpfsFs = class {
5010
5039
  return this.remote?.crowded() === true;
5011
5040
  }
5012
5041
  glanced(handle) {
5013
- if (this.shared()) return void 0;
5042
+ if (this.exact > 0) return void 0;
5014
5043
  const seen = this.glances.get(handle);
5015
5044
  const fresh2 = seen && seen.changes === this.changes && performance.now() - seen.at < GLANCE_MS;
5016
5045
  return fresh2 ? seen.file : void 0;
@@ -5018,6 +5047,7 @@ var OpfsFs = class {
5018
5047
  async glance(handle) {
5019
5048
  const at = performance.now();
5020
5049
  const before = this.changes;
5050
+ this.calls++;
5021
5051
  const file = await handle.getFile();
5022
5052
  if (before === this.changes) this.glances.set(handle, { at, file, changes: before });
5023
5053
  else this.glances.delete(handle);
@@ -5303,7 +5333,7 @@ var OpfsFs = class {
5303
5333
  if (!options.recursive) return this.mkdirExcl(path, options.owner);
5304
5334
  let found;
5305
5335
  try {
5306
- found = await this.locate(path, true);
5336
+ found = await this.exactly(() => this.locate(path, true));
5307
5337
  } catch (err) {
5308
5338
  if (!missing2(err)) throw err;
5309
5339
  }
@@ -5376,6 +5406,7 @@ var OpfsFs = class {
5376
5406
  });
5377
5407
  }
5378
5408
  async handleExists(dir, name2) {
5409
+ this.calls++;
5379
5410
  try {
5380
5411
  await dir.getDirectoryHandle(name2);
5381
5412
  return true;
@@ -5430,7 +5461,7 @@ var OpfsFs = class {
5430
5461
  async link(from, to, follow2) {
5431
5462
  await (follow2 ? this.stat(from) : this.lstat(from));
5432
5463
  if (!(await this.stat(parentOf4(to))).isDirectory) throw fsError("ENOTDIR", to);
5433
- const taken = await this.lstat(to).then(
5464
+ const taken = await this.exactly(() => this.lstat(to)).then(
5434
5465
  () => true,
5435
5466
  (err) => {
5436
5467
  if (missing2(err)) return false;
@@ -5453,7 +5484,7 @@ var OpfsFs = class {
5453
5484
  async moveTo(source, parent, destination, to) {
5454
5485
  const sourceStat = await this.describe(source);
5455
5486
  if (sourceStat.isDirectory && within3(destination, source.path)) throw fsError("EINVAL", to);
5456
- const target = await this.locate(destination, false).catch((err) => {
5487
+ const target = await this.exactly(() => this.locate(destination, false)).catch((err) => {
5457
5488
  if (missing2(err)) return null;
5458
5489
  throw err;
5459
5490
  });
@@ -5572,7 +5603,7 @@ var OpfsFs = class {
5572
5603
  if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
5573
5604
  const at = resolvePath(parent.path, baseOf(path));
5574
5605
  this.refuse(at);
5575
- if (await this.locate(at, false).then(
5606
+ if (await this.exactly(() => this.locate(at, false)).then(
5576
5607
  () => true,
5577
5608
  (err) => !missing2(err)
5578
5609
  )) {
@@ -5825,15 +5856,21 @@ var UnlinkedKeeper = class {
5825
5856
  };
5826
5857
  const unreplaced = async (path, op) => {
5827
5858
  const at = fs.resolvePath("/", path);
5859
+ const pending = async () => {
5860
+ for (let p = at; replacing.size > 0; p = parentOf5(p)) {
5861
+ await replacing.get(p)?.done;
5862
+ if (p === "/") return;
5863
+ }
5864
+ };
5828
5865
  for (let attempt = 1; ; attempt++) {
5829
- await replacing.get(at)?.done;
5866
+ await pending();
5830
5867
  const seen = keeper.replaced;
5831
5868
  try {
5832
5869
  return await op();
5833
5870
  } catch (err) {
5834
5871
  const code = err?.code;
5835
5872
  if (attempt >= 3 || code !== "ENOENT") throw err;
5836
- await replacing.get(at)?.done;
5873
+ await pending();
5837
5874
  if (keeper.replaced === seen) throw err;
5838
5875
  }
5839
5876
  }
@@ -5858,9 +5895,11 @@ var UnlinkedKeeper = class {
5858
5895
  lstat: (path) => unreplaced(path, async () => counted3(await fs.lstat(path))),
5859
5896
  async rm(path, options) {
5860
5897
  const target = fs.resolvePath("/", path);
5861
- const pinned = await keeper.pin(target);
5862
- if (pinned.moved.has(target)) pinned.commit();
5863
- else await keeper.settle(pinned, () => fs.rm(path, options));
5898
+ await replace(target, async (gated) => {
5899
+ const pinned = await keeper.pin(target, gated);
5900
+ if (pinned.moved.has(target)) pinned.commit();
5901
+ else await keeper.settle(pinned, () => fs.rm(path, options));
5902
+ });
5864
5903
  },
5865
5904
  async rename(from, to) {
5866
5905
  const target = fs.resolvePath("/", to);
@@ -5895,9 +5934,22 @@ var UnlinkedKeeper = class {
5895
5934
  return held;
5896
5935
  }
5897
5936
  async pin(target, gated = () => void 0) {
5898
- const paths = [...this.heldWithin(target).keys()].sort();
5937
+ const paths = [];
5899
5938
  const releases = [];
5900
- for (const path of paths) releases.push(await this.gate.acquire(path));
5939
+ for (; ; ) {
5940
+ const fresh2 = [...this.heldWithin(target).keys()].filter((path) => !paths.includes(path));
5941
+ if (fresh2.length === 0) break;
5942
+ fresh2.sort();
5943
+ if (paths.some((path) => path > fresh2[0])) {
5944
+ for (const release of releases.splice(0)) release();
5945
+ fresh2.push(...paths.splice(0));
5946
+ fresh2.sort();
5947
+ }
5948
+ for (const path of fresh2) {
5949
+ paths.push(path);
5950
+ releases.push(await this.gate.acquire(path));
5951
+ }
5952
+ }
5901
5953
  gated();
5902
5954
  const now = this.heldWithin(target);
5903
5955
  const held = new Map(
@@ -6973,7 +7025,7 @@ function satisfies(version, range2) {
6973
7025
  }
6974
7026
 
6975
7027
  // src/version.ts
6976
- var KERNEL_VERSION = true ? "1.124.3" : "0.0.0-dev";
7028
+ var KERNEL_VERSION = true ? "1.124.5" : "0.0.0-dev";
6977
7029
  var OS_RELEASE = "6.0.0-slicc";
6978
7030
  function procVersion() {
6979
7031
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -12855,6 +12907,8 @@ var SYS_TREE = {
12855
12907
  slicc_shared_root: (listing) => `${listing.peers ?? 0}
12856
12908
  `,
12857
12909
  slicc_fs_calls: (listing) => `${listing.fsCalls ?? 0}
12910
+ `,
12911
+ slicc_opfs_calls: (listing) => `${listing.opfsCalls ?? 0}
12858
12912
  `
12859
12913
  }
12860
12914
  };
@@ -14026,9 +14080,13 @@ async function flock(req, ctx) {
14026
14080
  if (req.kind !== "unlock" && req.wait)
14027
14081
  await locks.flocks.wait(key, owner, req.kind, ctx.blocking);
14028
14082
  else if (!await locks.flocks.set(key, owner, req.kind)) throw new KernelError("EAGAIN");
14029
- if (shared && granted2) await ctx.settle?.(req.fd, true);
14083
+ if (shared && granted2) await grantedAcross(ctx, req.fd);
14030
14084
  return shared ? json3(true) : done2;
14031
14085
  }
14086
+ async function grantedAcross(ctx, fd) {
14087
+ ctx.locks?.fresh?.();
14088
+ if (fd !== void 0) await ctx.settle?.(fd, true);
14089
+ }
14032
14090
  async function recordLock2(req, ctx) {
14033
14091
  const { locks, fileKey } = ctx;
14034
14092
  if (!locks || !fileKey) throw new KernelError("ENOLCK");
@@ -14058,7 +14116,7 @@ async function recordLock2(req, ctx) {
14058
14116
  await locks.wait(key, owner, req.kind, range2, ctx.blocking);
14059
14117
  else if (!await locks.set(key, owner, req.kind, range2.start, range2.end))
14060
14118
  throw new KernelError("EAGAIN");
14061
- if (granted2 && fd !== void 0) await ctx.settle?.(fd, true);
14119
+ if (granted2 && shared) await grantedAcross(ctx, fd);
14062
14120
  return shared ? json3(true) : done2;
14063
14121
  }
14064
14122
 
@@ -20559,6 +20617,9 @@ var LockService = class {
20559
20617
  };
20560
20618
  }
20561
20619
  peers;
20620
+ fresh() {
20621
+ this.peers?.fresh?.();
20622
+ }
20562
20623
  shared() {
20563
20624
  if (!this.leader || this.ownerOf.size > 0 || this.tokens.size > 0) return true;
20564
20625
  return this.peers?.crowded() === true;
@@ -25359,7 +25420,8 @@ var Launcher = class {
25359
25420
  cpu: this.cpuTotal(),
25360
25421
  wasm: this.memories.count(),
25361
25422
  peers: Number(this.locks.shared?.() === true),
25362
- fsCalls: servedFsCalls()
25423
+ fsCalls: servedFsCalls(),
25424
+ opfsCalls: this.rootFs.opfsCalls?.() ?? 0
25363
25425
  }),
25364
25426
  sudo: (call, signal) => this.sudo(pid, call, signal),
25365
25427
  crontab: (call) => this.crontab(pid, call),