@ai-ecoverse/slicc-kernel 1.65.0 → 1.65.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
@@ -2848,18 +2848,99 @@ function serveClient(port, host) {
2848
2848
  return { detach, closed: ended.promise };
2849
2849
  }
2850
2850
 
2851
- // src/fs/meta.ts
2851
+ // src/fs/path-map.ts
2852
2852
  function parentOf2(path) {
2853
+ if (path === "/" || path === "") return void 0;
2854
+ const at = path.lastIndexOf("/");
2855
+ return at <= 0 ? "/" : path.slice(0, at);
2856
+ }
2857
+ var PathMap = class {
2858
+ values = /* @__PURE__ */ new Map();
2859
+ children = /* @__PURE__ */ new Map();
2860
+ get size() {
2861
+ return this.values.size;
2862
+ }
2863
+ has(path) {
2864
+ return this.values.has(path);
2865
+ }
2866
+ get(path) {
2867
+ return this.values.get(path);
2868
+ }
2869
+ keys() {
2870
+ return this.values.keys();
2871
+ }
2872
+ set(path, value) {
2873
+ if (!this.values.has(path)) this.link(path);
2874
+ this.values.set(path, value);
2875
+ return this;
2876
+ }
2877
+ delete(path) {
2878
+ if (!this.values.delete(path)) return false;
2879
+ this.prune(path);
2880
+ return true;
2881
+ }
2882
+ subtree(root) {
2883
+ const out = [];
2884
+ const stack = [root];
2885
+ for (let path = stack.pop(); path !== void 0; path = stack.pop()) {
2886
+ if (this.values.has(path)) out.push(path);
2887
+ const below = this.children.get(path);
2888
+ if (below) for (const child of below) stack.push(child);
2889
+ }
2890
+ return out;
2891
+ }
2892
+ entries() {
2893
+ return this.values.entries();
2894
+ }
2895
+ deleteTree(root) {
2896
+ const stack = [root];
2897
+ for (let path = stack.pop(); path !== void 0; path = stack.pop()) {
2898
+ this.values.delete(path);
2899
+ const below = this.children.get(path);
2900
+ if (below) for (const child of below) stack.push(child);
2901
+ this.children.delete(path);
2902
+ }
2903
+ this.prune(root);
2904
+ }
2905
+ clear() {
2906
+ this.values.clear();
2907
+ this.children.clear();
2908
+ }
2909
+ link(path) {
2910
+ for (let child = path, parent = parentOf2(path); parent !== void 0; ) {
2911
+ const set2 = this.children.get(parent);
2912
+ if (set2?.has(child)) return;
2913
+ if (set2) set2.add(child);
2914
+ else this.children.set(parent, /* @__PURE__ */ new Set([child]));
2915
+ child = parent;
2916
+ parent = parentOf2(parent);
2917
+ }
2918
+ }
2919
+ prune(path) {
2920
+ for (let child = path, parent = parentOf2(path); parent !== void 0; ) {
2921
+ if (this.values.has(child) || this.children.has(child)) return;
2922
+ const set2 = this.children.get(parent);
2923
+ set2?.delete(child);
2924
+ if (set2 && set2.size > 0) return;
2925
+ this.children.delete(parent);
2926
+ child = parent;
2927
+ parent = parentOf2(parent);
2928
+ }
2929
+ }
2930
+ };
2931
+
2932
+ // src/fs/meta.ts
2933
+ function parentOf3(path) {
2853
2934
  return path.slice(0, path.lastIndexOf("/")) || "/";
2854
2935
  }
2855
2936
  function moved(entry, path) {
2856
- return entry.link === void 0 ? { ...entry, path } : { ...entry, path, dir: parentOf2(path) };
2937
+ return entry.link === void 0 ? { ...entry, path } : { ...entry, path, dir: parentOf3(path) };
2857
2938
  }
2858
2939
  function under(path, root) {
2859
2940
  return path === root || path.startsWith(`${root}/`);
2860
2941
  }
2861
2942
  var MemoryMeta = class {
2862
- entries = /* @__PURE__ */ new Map();
2943
+ entries = new PathMap();
2863
2944
  async get(paths) {
2864
2945
  return paths.map((path) => this.entries.get(path));
2865
2946
  }
@@ -2872,7 +2953,7 @@ var MemoryMeta = class {
2872
2953
  }
2873
2954
  async move(from, to, root) {
2874
2955
  await this.remove([to]);
2875
- const carried = [...this.entries.values()].filter((entry) => under(entry.path, from));
2956
+ const carried = this.entries.subtree(from).map((path) => this.entries.get(path));
2876
2957
  for (const entry of carried) this.entries.delete(entry.path);
2877
2958
  for (const entry of carried) {
2878
2959
  const path = to + entry.path.slice(from.length);
@@ -2881,18 +2962,16 @@ var MemoryMeta = class {
2881
2962
  this.entries.set(to, moved(root(carried.find((entry) => entry.path === from)), to));
2882
2963
  }
2883
2964
  async remove(paths) {
2884
- for (const key of [...this.entries.keys()]) {
2885
- if (paths.some((path) => under(key, path))) this.entries.delete(key);
2886
- }
2965
+ for (const path of paths) this.entries.deleteTree(path);
2887
2966
  }
2888
2967
  async links(dir) {
2889
- return [...this.entries.values()].filter((entry) => entry.dir === dir);
2968
+ return [...this.entries.entries()].map(([, e]) => e).filter((entry) => entry.dir === dir);
2890
2969
  }
2891
2970
  async under(path) {
2892
- return [...this.entries.values()].filter((entry) => under(entry.path, path));
2971
+ return [...this.entries.entries()].map(([, e]) => e).filter((entry) => under(entry.path, path));
2893
2972
  }
2894
2973
  async all() {
2895
- return [...this.entries.values()];
2974
+ return [...this.entries.entries()].map(([, e]) => e);
2896
2975
  }
2897
2976
  };
2898
2977
 
@@ -2919,15 +2998,15 @@ function translate(err, path, op = "lookup", mapped = true) {
2919
2998
  if (typeof err?.code === "string") return err;
2920
2999
  const raw = err?.name;
2921
3000
  const name2 = typeof raw === "string" ? raw : "Error";
2922
- const code = mapped && ERRNO_BY_DOM_ERROR[name2] || "EIO";
3001
+ const code = name2 === "QuotaExceededError" ? "ENOSPC" : mapped && ERRNO_BY_DOM_ERROR[name2] || "EIO";
2923
3002
  const error = Object.assign(fsError(code, path), { domName: name2, op, cause: err });
2924
- if (code !== "EIO") return error;
3003
+ if (code !== "EIO" && code !== "ENOSPC") return error;
2925
3004
  const detail = err?.message;
2926
3005
  error.message += ` (OPFS ${op}: ${name2}${typeof detail === "string" && detail ? `: ${detail}` : ""})`;
2927
3006
  if (!reported.has(`${name2}/${op}`)) {
2928
3007
  reported.add(`${name2}/${op}`);
2929
3008
  console.warn(
2930
- `slicc-kernel: ${error.message}, reported as EIO; logged once per error and operation`
3009
+ `slicc-kernel: ${error.message}, reported as ${code}; logged once per error and operation`
2931
3010
  );
2932
3011
  }
2933
3012
  return error;
@@ -2947,7 +3026,7 @@ function missing(err) {
2947
3026
  function split(path) {
2948
3027
  return path.split("/").filter(Boolean);
2949
3028
  }
2950
- function parentOf3(path) {
3029
+ function parentOf4(path) {
2951
3030
  return path.slice(0, path.lastIndexOf("/")) || "/";
2952
3031
  }
2953
3032
  function baseOf(path) {
@@ -3016,7 +3095,7 @@ function isHandle(child) {
3016
3095
  var OpfsFs = class {
3017
3096
  root;
3018
3097
  meta;
3019
- dirs = /* @__PURE__ */ new Map();
3098
+ dirs = new PathMap();
3020
3099
  checked = /* @__PURE__ */ new WeakMap();
3021
3100
  channel;
3022
3101
  ranged;
@@ -3065,7 +3144,7 @@ var OpfsFs = class {
3065
3144
  async ownerAt(path, entry) {
3066
3145
  const own = ownOf(entry);
3067
3146
  if (own) return own;
3068
- return path === "/" ? { ...ROOT_OWNER } : this.handedTo(parentOf3(path));
3147
+ return path === "/" ? { ...ROOT_OWNER } : this.handedTo(parentOf4(path));
3069
3148
  }
3070
3149
  async owned(stat, path, entry) {
3071
3150
  return this.owners ? { ...stat, ...await this.ownerAt(path, entry) } : stat;
@@ -3095,7 +3174,7 @@ var OpfsFs = class {
3095
3174
  async chown(path, change) {
3096
3175
  if (!this.owners) return;
3097
3176
  if (change.kind === "new") {
3098
- const at = resolvePath((await this.locate(parentOf3(path), true)).path, baseOf(path));
3177
+ const at = resolvePath((await this.locate(parentOf4(path), true)).path, baseOf(path));
3099
3178
  const { uid = 0, gid = 0, mode } = change;
3100
3179
  return this.stampNew(at, { uid, gid, ...mode !== void 0 ? { mode } : {} }, false);
3101
3180
  }
@@ -3159,7 +3238,7 @@ var OpfsFs = class {
3159
3238
  return true;
3160
3239
  }
3161
3240
  forget(path) {
3162
- for (const key of [...this.dirs.keys()]) if (within(key, path)) this.dirs.delete(key);
3241
+ this.dirs.deleteTree(path);
3163
3242
  }
3164
3243
  async inDir(path, op) {
3165
3244
  const dir = await this.dir(path);
@@ -3206,7 +3285,7 @@ var OpfsFs = class {
3206
3285
  async linkAlong(path) {
3207
3286
  for (const entry of await this.meta.get(prefixes(path))) {
3208
3287
  if (entry?.link === void 0) continue;
3209
- if (!await this.real(entry.path) && await this.real(parentOf3(entry.path))) return entry;
3288
+ if (!await this.real(entry.path) && await this.real(parentOf4(entry.path))) return entry;
3210
3289
  }
3211
3290
  return void 0;
3212
3291
  }
@@ -3221,7 +3300,7 @@ var OpfsFs = class {
3221
3300
  if (!link2) throw err;
3222
3301
  if (link2.path === current && !follow2) return { path: current, link: link2 };
3223
3302
  const target = `${link2.link}${current.slice(link2.path.length)}`;
3224
- current = target.split("/").includes("..") ? await this.physical(parentOf3(link2.path), target, hops + 1) : resolvePath(parentOf3(link2.path), target);
3303
+ current = target.split("/").includes("..") ? await this.physical(parentOf4(link2.path), target, hops + 1) : resolvePath(parentOf4(link2.path), target);
3225
3304
  }
3226
3305
  }
3227
3306
  throw fsError("ELOOP", path);
@@ -3411,8 +3490,8 @@ var OpfsFs = class {
3411
3490
  if (!missing(err)) throw err;
3412
3491
  }
3413
3492
  const [entry] = await this.meta.get([path]);
3414
- const wanted = entry?.link === void 0 ? path : resolvePath(parentOf3(path), entry.link);
3415
- return [resolvePath((await this.locate(parentOf3(wanted), true)).path, baseOf(wanted)), false];
3493
+ const wanted = entry?.link === void 0 ? path : resolvePath(parentOf4(path), entry.link);
3494
+ return [resolvePath((await this.locate(parentOf4(wanted), true)).path, baseOf(wanted)), false];
3416
3495
  }
3417
3496
  async fileFor(path) {
3418
3497
  const [target, existed] = await this.writeTarget(path);
@@ -3422,7 +3501,7 @@ var OpfsFs = class {
3422
3501
  dir,
3423
3502
  (parent) => parent.getFileHandle(name2, { create: true })
3424
3503
  );
3425
- if (!existed) this.touch(parentOf3(target));
3504
+ if (!existed) this.touch(parentOf4(target));
3426
3505
  return [handle, existed, target];
3427
3506
  } catch (err) {
3428
3507
  const code = err?.name === "TypeMismatchError" ? "EISDIR" : null;
@@ -3433,11 +3512,13 @@ var OpfsFs = class {
3433
3512
  const [file, existed, target] = await this.fileFor(path);
3434
3513
  if (!existed) await this.stampNew(target, owner, false);
3435
3514
  if (!existed && content.length === 0) return;
3515
+ let writable2;
3436
3516
  try {
3437
- const writable2 = await file.createWritable();
3517
+ writable2 = await file.createWritable();
3438
3518
  await writable2.write(content);
3439
3519
  await writable2.close();
3440
3520
  } catch (err) {
3521
+ await writable2?.abort().catch(() => void 0);
3441
3522
  throw translate(err, path, "commit", false);
3442
3523
  }
3443
3524
  }
@@ -3492,9 +3573,9 @@ var OpfsFs = class {
3492
3573
  gid: owner.gid,
3493
3574
  ...mode ? { mode, parents: mode } : {}
3494
3575
  };
3495
- await this.mkdir(parentOf3(path), { recursive: true, ...above ? { owner: above } : {} });
3576
+ await this.mkdir(parentOf4(path), { recursive: true, ...above ? { owner: above } : {} });
3496
3577
  }
3497
- const parent = await this.locate(parentOf3(path), true);
3578
+ const parent = await this.locate(parentOf4(path), true);
3498
3579
  if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
3499
3580
  await parent.handle.getDirectoryHandle(baseOf(path), { create: true });
3500
3581
  const made2 = `${parent.path === "/" ? "" : parent.path}/${baseOf(path)}`;
@@ -3523,7 +3604,7 @@ var OpfsFs = class {
3523
3604
  this.changed(found.path);
3524
3605
  }
3525
3606
  await this.meta.remove([found.path]);
3526
- this.touch(parentOf3(found.path));
3607
+ this.touch(parentOf4(found.path));
3527
3608
  }
3528
3609
  links() {
3529
3610
  return false;
@@ -3535,7 +3616,7 @@ var OpfsFs = class {
3535
3616
  if (from === to) return;
3536
3617
  const source = await this.locate(from, false);
3537
3618
  this.forget(source.path);
3538
- const parent = await this.locate(parentOf3(to), true);
3619
+ const parent = await this.locate(parentOf4(to), true);
3539
3620
  const destination = resolvePath(parent.path, baseOf(to));
3540
3621
  const sourceStat = await this.describe(source);
3541
3622
  if (sourceStat.isDirectory && within(destination, source.path)) throw fsError("EINVAL", to);
@@ -3563,7 +3644,7 @@ var OpfsFs = class {
3563
3644
  if (source.link) {
3564
3645
  if (target?.handle) await this.rm(destination);
3565
3646
  await this.meta.move(source.path, destination, carry);
3566
- this.touch(parentOf3(source.path), parent.path);
3647
+ this.touch(parentOf4(source.path), parent.path);
3567
3648
  return;
3568
3649
  }
3569
3650
  const dir = parent.handle;
@@ -3585,7 +3666,7 @@ var OpfsFs = class {
3585
3666
  }
3586
3667
  if (copied) await this.restamp(destination, timed2);
3587
3668
  this.changed(source.path, destination);
3588
- this.touch(parentOf3(source.path), parent.path);
3669
+ this.touch(parentOf4(source.path), parent.path);
3589
3670
  }
3590
3671
  async modified(path) {
3591
3672
  const handle = await this.handle(path);
@@ -3631,7 +3712,7 @@ var OpfsFs = class {
3631
3712
  for await (const child of handle.values()) await this.copy(child, target, child.name);
3632
3713
  }
3633
3714
  async symlink(target, path, owner) {
3634
- const parent = await this.locate(parentOf3(path), true);
3715
+ const parent = await this.locate(parentOf4(path), true);
3635
3716
  if (parent.handle?.kind !== "directory") throw fsError("ENOTDIR", path);
3636
3717
  const at = resolvePath(parent.path, baseOf(path));
3637
3718
  if (await this.locate(at, false).then(
@@ -3707,7 +3788,7 @@ var OpfsFs = class {
3707
3788
  let removed = 0;
3708
3789
  for (const entry of await this.meta.all()) {
3709
3790
  const real = await this.real(entry.path);
3710
- const stale = entry.link === void 0 ? !real : real || !await this.real(parentOf3(entry.path));
3791
+ const stale = entry.link === void 0 ? !real : real || !await this.real(parentOf4(entry.path));
3711
3792
  if (!stale) continue;
3712
3793
  await this.meta.update(entry.path, () => void 0);
3713
3794
  removed++;
@@ -3778,7 +3859,7 @@ function webLocks() {
3778
3859
  return globalThis.navigator?.locks;
3779
3860
  }
3780
3861
  var within2 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
3781
- var parentOf4 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
3862
+ var parentOf5 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
3782
3863
  var lockName = (instance) => `slicc-unlinked:${instance}`;
3783
3864
  var dirOf = (root) => root === "/" ? `/${UNLINKED_DIR}` : `${root}/${UNLINKED_DIR}`;
3784
3865
  var PathGate = class {
@@ -3911,7 +3992,7 @@ var UnlinkedKeeper = class {
3911
3992
  await this.serial(async () => {
3912
3993
  await Promise.allSettled([this.fs.rename(file.hidden, path)]);
3913
3994
  this.unlinkedName(file.hidden);
3914
- await this.tidy(parentOf4(file.hidden));
3995
+ await this.tidy(parentOf5(file.hidden));
3915
3996
  });
3916
3997
  }
3917
3998
  done4();
@@ -3952,7 +4033,7 @@ var UnlinkedKeeper = class {
3952
4033
  }
3953
4034
  await this.fs.rm(hidden).catch(() => void 0);
3954
4035
  this.unlinkedName(hidden);
3955
- await this.tidy(parentOf4(hidden));
4036
+ await this.tidy(parentOf5(hidden));
3956
4037
  }
3957
4038
  async linkedName(hidden) {
3958
4039
  if (!mayLink(this.fs, hidden)) return;
@@ -5148,10 +5229,10 @@ async function physicalPathAsync(fs, path) {
5148
5229
  // src/fs/watch.ts
5149
5230
  var WATCH_BATCH_LIMIT = 1e3;
5150
5231
  var under2 = (path, dir) => dir === "/" || path.startsWith(`${dir}/`);
5151
- var parentOf5 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
5232
+ var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
5152
5233
  function touches(watcher, changed) {
5153
5234
  return watcher.paths.some(
5154
- (watched) => changed === watched || under2(watched, changed) || (watcher.recursive ? under2(changed, watched) : parentOf5(changed) === watched)
5235
+ (watched) => changed === watched || under2(watched, changed) || (watcher.recursive ? under2(changed, watched) : parentOf6(changed) === watched)
5155
5236
  );
5156
5237
  }
5157
5238
  var FsWatchers = class {
@@ -5728,7 +5809,7 @@ var HeldPaths = class extends Map {
5728
5809
  return this.revoked.has(path);
5729
5810
  }
5730
5811
  };
5731
- var parentOf6 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
5812
+ var parentOf7 = (path) => path.slice(0, path.lastIndexOf("/")) || "/";
5732
5813
  var readonly = (mount) => mount.caps.readonly === true || mount.options.ro !== void 0;
5733
5814
  function inodeless(mount, attr2) {
5734
5815
  if (attr2.ino !== void 0) return false;
@@ -6008,7 +6089,7 @@ var MountTable = class {
6008
6089
  mount.epoch++;
6009
6090
  for (const key of [...mount.attrs.keys()]) if (within3(key, path)) mount.attrs.delete(key);
6010
6091
  mount.lists.delete(path);
6011
- mount.lists.delete(parentOf6(path));
6092
+ mount.lists.delete(parentOf7(path));
6012
6093
  for (const key of [...mount.lists.keys()]) if (within3(key, path)) mount.lists.delete(key);
6013
6094
  }
6014
6095
  async getattr(mount, path, rel2, settled = false) {
@@ -6084,7 +6165,7 @@ var MountFs = class {
6084
6165
  if (attr2.kind !== "symlink") return real;
6085
6166
  if (hops >= MAX_LINKS6) throw errnoError("ELOOP", path);
6086
6167
  const target = await found.mount.conn.call({ op: "readlink", path: found.rel });
6087
- return this.follow(this.base.resolvePath(parentOf6(real), target), hops + 1, create);
6168
+ return this.follow(this.base.resolvePath(parentOf7(real), target), hops + 1, create);
6088
6169
  }
6089
6170
  async open(mount, rel2, write, owner) {
6090
6171
  return await mount.conn.call({
@@ -6100,8 +6181,8 @@ var MountFs = class {
6100
6181
  async driverOwner(found, real, owner, directory) {
6101
6182
  const { mount, rel: rel2 } = found;
6102
6183
  if (!owner || !mount.owners || !mount.caps.owners) return void 0;
6103
- const dir = parentOf6(real);
6104
- const above = statOf(await this.table.getattr(mount, dir, parentOf6(rel2)), dir, mount);
6184
+ const dir = parentOf7(real);
6185
+ const above = statOf(await this.table.getattr(mount, dir, parentOf7(rel2)), dir, mount);
6105
6186
  const setgid = (above.mode & S_ISGID4) !== 0;
6106
6187
  let mode = owner.mode;
6107
6188
  if (directory && setgid) mode = (mode ?? 493) | S_ISGID4;
@@ -6440,7 +6521,7 @@ var MountFs = class {
6440
6521
  }
6441
6522
  async named(path) {
6442
6523
  const at = normalizePath(path);
6443
- return joinName(await realDir(this, parentOf6(at)), at.slice(at.lastIndexOf("/") + 1));
6524
+ return joinName(await realDir(this, parentOf7(at)), at.slice(at.lastIndexOf("/") + 1));
6444
6525
  }
6445
6526
  async link(source, target, follow2 = false) {
6446
6527
  const from = follow2 ? await realTarget(this, normalizePath(source)) : await this.named(source);