@ai-ecoverse/slicc-kernel 1.147.4 → 1.147.6

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.
@@ -1091,7 +1091,7 @@ var RemoteWatch = class {
1091
1091
  if (data.ack !== void 0 && data.to === this.tab && data.from !== void 0) {
1092
1092
  this.acked(data.ack, data.from);
1093
1093
  }
1094
- if (data.changed !== void 0) this.emit({ paths: data.changed, trees: [] });
1094
+ if (data.changed !== void 0) this.emit({ paths: data.changed, trees: [], content: true });
1095
1095
  }
1096
1096
  arrived(peer) {
1097
1097
  this.peers.add(peer);
@@ -1400,6 +1400,18 @@ var Extent = class {
1400
1400
  };
1401
1401
  var LOCKED = /* @__PURE__ */ new Set(["NotReadableError", "NoModificationAllowedError", "InvalidStateError"]);
1402
1402
  var SYNC_BACKOFF_MS = [5, 10, 20, 40, 80];
1403
+ async function unlocked(name2, op) {
1404
+ for (let attempt = 0; ; attempt++) {
1405
+ try {
1406
+ return await op();
1407
+ } catch (err) {
1408
+ if (!LOCKED.has(err?.name)) throw err;
1409
+ const delay = SYNC_BACKOFF_MS[attempt];
1410
+ if (delay === void 0) throw fsError("EBUSY", name2);
1411
+ await new Promise((resolve2) => setTimeout(resolve2, delay));
1412
+ }
1413
+ }
1414
+ }
1403
1415
  async function openSync(handle) {
1404
1416
  const sync = handle.createSyncAccessHandle;
1405
1417
  if (!sync) return void 0;
@@ -1526,7 +1538,12 @@ var OpfsFs = class {
1526
1538
  meta.listen?.((c) => {
1527
1539
  for (const path of [...c.paths ?? [], ...c.trees ?? []]) this.forget(path);
1528
1540
  const moved2 = movedOf(c.moved);
1529
- remote?.emit({ paths: c.paths ?? [], trees: c.trees ?? [], ...moved2 ? { moved: moved2 } : {} });
1541
+ remote?.emit({
1542
+ paths: c.paths ?? [],
1543
+ trees: c.trees ?? [],
1544
+ content: true,
1545
+ ...moved2 ? { moved: moved2 } : {}
1546
+ });
1530
1547
  });
1531
1548
  remote?.listen((c) => {
1532
1549
  for (const path of [...c.paths, ...c.trees]) this.forget(path);
@@ -2594,7 +2611,10 @@ var OpfsFs = class {
2594
2611
  try {
2595
2612
  await this.inDir(
2596
2613
  dir,
2597
- (parent) => this.io(parent.removeEntry(name2, { recursive: options.recursive === true }))
2614
+ (parent) => unlocked(
2615
+ name2,
2616
+ () => this.io(parent.removeEntry(name2, { recursive: options.recursive === true }))
2617
+ )
2598
2618
  );
2599
2619
  } catch (err) {
2600
2620
  throw translate(err, path);
@@ -7785,7 +7805,7 @@ function satisfies(version, range2) {
7785
7805
  }
7786
7806
 
7787
7807
  // src/version.ts
7788
- var KERNEL_VERSION = true ? "1.147.4" : "0.0.0-dev";
7808
+ var KERNEL_VERSION = true ? "1.147.6" : "0.0.0-dev";
7789
7809
  var OS_RELEASE = "6.0.0-slicc";
7790
7810
  function procVersion() {
7791
7811
  return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
@@ -10829,13 +10849,14 @@ var FsWatchers = class {
10829
10849
  this.watchers.delete(watcher);
10830
10850
  };
10831
10851
  }
10832
- typedWatch(root, recursive, alias) {
10852
+ typedWatch(root, recursive, alias, directory = recursive) {
10833
10853
  const main = normalizePath(root);
10834
10854
  const other = alias === void 0 ? main : normalizePath(alias);
10835
10855
  const watch = {
10836
10856
  roots: other === main ? [main] : [main, other],
10837
10857
  names: /* @__PURE__ */ new Map(),
10838
10858
  recursive,
10859
+ directory,
10839
10860
  notes: [],
10840
10861
  overflowed: false,
10841
10862
  ended: false,
@@ -10923,6 +10944,19 @@ var FsWatchers = class {
10923
10944
  if (!followed2.has(watch)) route(watch, "rename", at, seq2);
10924
10945
  }
10925
10946
  }
10947
+ heard(type, paths) {
10948
+ if (this.typed.size === 0) return;
10949
+ for (const path of paths) {
10950
+ const at = normalizePath(path);
10951
+ const seq2 = ++this.seq;
10952
+ for (const watch of [...this.typed]) {
10953
+ if (type === "rename" && watch.roots.some((root) => at === root || under3(root, at)))
10954
+ continue;
10955
+ if (type === "change" && watch.directory && watch.roots.includes(at)) continue;
10956
+ route(watch, type, at, seq2);
10957
+ }
10958
+ }
10959
+ }
10926
10960
  changed(...paths) {
10927
10961
  this.report(paths);
10928
10962
  this.emit("change", paths);
@@ -22314,6 +22348,17 @@ var VfsNode = class {
22314
22348
  this.queue = next3.catch(() => void 0);
22315
22349
  return next3;
22316
22350
  }
22351
+ named = 0;
22352
+ byName(op) {
22353
+ return this.serial(async () => {
22354
+ this.named++;
22355
+ try {
22356
+ return await op();
22357
+ } finally {
22358
+ this.named--;
22359
+ }
22360
+ });
22361
+ }
22317
22362
  revoke() {
22318
22363
  this.revoked = true;
22319
22364
  clearTimeout(this.writeBack);
@@ -22321,7 +22366,7 @@ var VfsNode = class {
22321
22366
  this.data = void 0;
22322
22367
  this.ranged = void 0;
22323
22368
  }
22324
- async prepare() {
22369
+ async prepare(onFd = this.named === 0) {
22325
22370
  if (this.revoked) throw new KernelError("EIO");
22326
22371
  if (this.ranged || this.data) return this.ranged;
22327
22372
  const io = rangedOps(this.fs);
@@ -22336,15 +22381,15 @@ var VfsNode = class {
22336
22381
  this.ranged = new AsyncRangedFile(io, this.path, st.size ?? 0, st.version);
22337
22382
  return this.ranged;
22338
22383
  }
22339
- await this.load();
22384
+ await this.load(onFd);
22340
22385
  return void 0;
22341
22386
  }
22342
22387
  async keep() {
22343
- const ranged2 = await this.prepare();
22344
- if (ranged2) await this.followed(() => ranged2.pin());
22388
+ const ranged2 = await this.prepare(false);
22389
+ if (ranged2) await this.followed(() => ranged2.pin(), false);
22345
22390
  }
22346
22391
  moving = /* @__PURE__ */ new Set();
22347
- async followed(op) {
22392
+ async followed(op, onFd = this.named === 0) {
22348
22393
  for (; ; ) {
22349
22394
  const at = this.path;
22350
22395
  try {
@@ -22352,11 +22397,11 @@ var VfsNode = class {
22352
22397
  } catch (err) {
22353
22398
  if (!isMissing(err)) throw err;
22354
22399
  while (this.moving.size > 0) await Promise.all(this.moving);
22355
- if (this.path === at) throw err;
22400
+ if (this.path === at) throw onFd && !this.made ? new KernelError("EIO") : err;
22356
22401
  }
22357
22402
  }
22358
22403
  }
22359
- async load() {
22404
+ async load(onFd = this.named === 0) {
22360
22405
  if (this.revoked) throw new KernelError("EIO");
22361
22406
  while (!this.data) {
22362
22407
  const at = this.path;
@@ -22366,7 +22411,7 @@ var VfsNode = class {
22366
22411
  if (!isMissing(err)) throw err;
22367
22412
  while (this.moving.size > 0) await Promise.all(this.moving);
22368
22413
  if (this.path !== at) continue;
22369
- if (!this.made) throw new KernelError("ENOENT");
22414
+ if (!this.made) throw new KernelError(onFd ? "EIO" : "ENOENT");
22370
22415
  this.data = new Uint8Array(0);
22371
22416
  this.missing = true;
22372
22417
  }
@@ -22871,7 +22916,7 @@ function heldIo(fs, nodes, changed) {
22871
22916
  const write = async (path, op, fallback) => {
22872
22917
  const held = await node(path);
22873
22918
  if (!held) return fallback();
22874
- const out = await held.serial(async () => {
22919
+ const out = await held.byName(async () => {
22875
22920
  const done5 = await op(held);
22876
22921
  await held.flush();
22877
22922
  return done5;
@@ -22903,22 +22948,22 @@ function heldIo(fs, nodes, changed) {
22903
22948
  async stat(path) {
22904
22949
  const st = await fs.stat(path);
22905
22950
  const held = st.isFile ? await node(path) : void 0;
22906
- return held ? { ...st, size: await held.serial(() => held.size()) } : st;
22951
+ return held ? { ...st, size: await held.byName(() => held.size()) } : st;
22907
22952
  },
22908
22953
  async lstat(path) {
22909
22954
  const st = await fs.lstat(path);
22910
22955
  const held = st.isFile && !st.isSymbolicLink ? await node(path) : void 0;
22911
- return held ? { ...st, size: await held.serial(() => held.size()) } : st;
22956
+ return held ? { ...st, size: await held.byName(() => held.size()) } : st;
22912
22957
  },
22913
22958
  async readFileBuffer(path) {
22914
22959
  const held = await node(path);
22915
22960
  if (!held) return fs.readFileBuffer(path);
22916
- return held.serial(async () => held.pread(await held.size(), 0));
22961
+ return held.byName(async () => held.pread(await held.size(), 0));
22917
22962
  },
22918
22963
  ...ranged2 ? {
22919
22964
  pread: async (path, at, n, version) => {
22920
22965
  const held = await node(path);
22921
- return held ? held.serial(() => held.pread(n, at)) : ranged2.pread(path, at, n, version);
22966
+ return held ? held.byName(() => held.pread(n, at)) : ranged2.pread(path, at, n, version);
22922
22967
  },
22923
22968
  pwrite: (path, at, bytes, transfer) => write(
22924
22969
  path,
@@ -22971,7 +23016,7 @@ function keepingOpen(fs, nodes, changed = () => {
22971
23016
  const held = await heldAt(fs, nodes, at);
22972
23017
  if (!held) return nodes.onEntry(at, () => fs.writeFile(path, content, owner));
22973
23018
  const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
22974
- return held.serial(async () => {
23019
+ return held.byName(async () => {
22975
23020
  await held.truncate(0);
22976
23021
  await held.pwrite(bytes, 0);
22977
23022
  await held.flush();
@@ -29267,6 +29312,8 @@ var Launcher = class {
29267
29312
  this.changes.flush();
29268
29313
  this.cwds.touched(change.paths, change.trees);
29269
29314
  this.rewritten(change.paths, change.trees);
29315
+ this.watchers.heard(change.content ? "change" : "rename", change.paths);
29316
+ this.watchers.heard("rename", change.trees ?? []);
29270
29317
  });
29271
29318
  const holders = [this.held, this.openFiles];
29272
29319
  this.unlinked = new UnlinkedKeeper(
@@ -30945,7 +30992,12 @@ var Launcher = class {
30945
30992
  if (g) await readable(g, "watch", at);
30946
30993
  const st = await this.fs.stat(at);
30947
30994
  const real = await this.fs.realpath?.(at, true).catch(() => at) ?? at;
30948
- const watch = this.watchers.typedWatch(real, recursive && st.isDirectory, at);
30995
+ const watch = this.watchers.typedWatch(
30996
+ real,
30997
+ recursive && st.isDirectory,
30998
+ at,
30999
+ st.isDirectory
31000
+ );
30949
31001
  if (!g || g.cred.euid === 0) return watch;
30950
31002
  return visibleTo2(watch, real, async (dir) => {
30951
31003
  const walked = await access(g.fs, g.cred, dir, R_OK | X_OK, { directory: true });