@ai-ecoverse/slicc-kernel 1.77.0 → 1.77.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
@@ -3022,6 +3022,9 @@ function writerTags(protection) {
3022
3022
  return new Set(writers);
3023
3023
  }
3024
3024
  function protectedPrefixes(paths) {
3025
+ if (!Array.isArray(paths) || paths.some((p) => typeof p !== "string" || !p.startsWith("/"))) {
3026
+ throw new TypeError("protect.paths must be a list of absolute paths");
3027
+ }
3025
3028
  return [...new Set(paths.map((p) => normalizePath(p)))];
3026
3029
  }
3027
3030
  function within(path, prefix) {
@@ -3125,6 +3128,9 @@ var ProtectedFs = class {
3125
3128
  await check(path, true);
3126
3129
  return fs.utimes(path, atime, mtime);
3127
3130
  },
3131
+ async mayChange(path, follow2) {
3132
+ await check(path, follow2);
3133
+ },
3128
3134
  async stat(path) {
3129
3135
  return marked(path, await fs.stat(path));
3130
3136
  },
@@ -3599,6 +3605,7 @@ var OpfsFs = class {
3599
3605
  }
3600
3606
  }
3601
3607
  async current(path, dir) {
3608
+ if (dir === this.root) return path === "/";
3602
3609
  if (performance.now() - (this.checked.get(dir) ?? -CHECK_MS) < CHECK_MS) return true;
3603
3610
  const where = await this.root.resolve(dir).catch(() => null);
3604
3611
  if (where === null || `/${where.join("/")}` !== path) return false;
@@ -3800,6 +3807,10 @@ var OpfsFs = class {
3800
3807
  };
3801
3808
  }
3802
3809
  async describe(found) {
3810
+ const stat = await this.described(found);
3811
+ return isProtected(this.guarded, found.path) ? { ...stat, readonly: true } : stat;
3812
+ }
3813
+ async described(found) {
3803
3814
  if (found.link) return this.owned(this.linkStat(found.link), found.path, found.link);
3804
3815
  const touched = this.timesOf(found.path);
3805
3816
  if (!this.owners) {
@@ -5759,6 +5770,83 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
5759
5770
  };
5760
5771
  }
5761
5772
 
5773
+ // src/fs/fresh-modules.ts
5774
+ var MAGIC = [0, 97, 115, 109];
5775
+ var MAX_FRESH = 65536;
5776
+ function isModule(bytes) {
5777
+ return MAGIC.every((b, i) => bytes[i] === b);
5778
+ }
5779
+ var FreshModules = class {
5780
+ fresh = /* @__PURE__ */ new Map();
5781
+ add(path, umask, pid) {
5782
+ const key = normalizePath(path);
5783
+ this.fresh.delete(key);
5784
+ const oldest = this.fresh.size >= MAX_FRESH ? this.fresh.keys().next().value : void 0;
5785
+ if (oldest !== void 0) this.fresh.delete(oldest);
5786
+ this.fresh.set(key, { umask: umask & 511, pid, added: 0 });
5787
+ }
5788
+ forget(pid) {
5789
+ for (const [path, fresh2] of this.fresh) if (fresh2.pid === pid) this.fresh.delete(path);
5790
+ }
5791
+ wrap(fs) {
5792
+ const decide = async (given, bytes) => {
5793
+ const path = normalizePath(given);
5794
+ const fresh2 = this.fresh.get(path);
5795
+ if (!fresh2 || typeof bytes === "string" || bytes.length < MAGIC.length) return;
5796
+ const want = isModule(bytes) ? 73 & ~fresh2.umask : 0;
5797
+ if (want === fresh2.added) return;
5798
+ const mode = (await fs.stat(path)).mode & 4095;
5799
+ await fs.chmod(path, mode & ~fresh2.added | want);
5800
+ fresh2.added = want;
5801
+ };
5802
+ const overrides = {
5803
+ writeFile: async (path, content, owner) => {
5804
+ await fs.writeFile(path, content, owner);
5805
+ await decide(path, content);
5806
+ },
5807
+ chmod: async (path, mode) => {
5808
+ const fresh2 = this.fresh.get(normalizePath(path));
5809
+ const creating = fresh2?.added === 0 && (mode & 4095) === (438 & ~fresh2.umask);
5810
+ if (!creating) this.fresh.delete(normalizePath(path));
5811
+ await fs.chmod(path, mode);
5812
+ },
5813
+ rm: async (path, options) => {
5814
+ this.fresh.delete(normalizePath(path));
5815
+ await fs.rm(path, options);
5816
+ },
5817
+ rename: async (from, to) => {
5818
+ await fs.rename(from, to);
5819
+ const fresh2 = this.fresh.get(normalizePath(from));
5820
+ this.fresh.delete(normalizePath(from));
5821
+ this.fresh.delete(normalizePath(to));
5822
+ if (fresh2) this.fresh.set(normalizePath(to), fresh2);
5823
+ }
5824
+ };
5825
+ const ranged2 = rangedOps(fs);
5826
+ if (ranged2) {
5827
+ overrides.pwrite = async (path, at, bytes, transfer) => {
5828
+ const head = at === 0 && this.fresh.has(normalizePath(path)) ? bytes.slice(0, 4) : void 0;
5829
+ await ranged2.pwrite(path, at, bytes, transfer);
5830
+ if (head) await decide(path, head);
5831
+ };
5832
+ }
5833
+ const bound = /* @__PURE__ */ new WeakMap();
5834
+ return new Proxy(fs, {
5835
+ get(target, key, receiver) {
5836
+ if (Object.hasOwn(overrides, key)) return overrides[key];
5837
+ const value = Reflect.get(target, key, receiver);
5838
+ if (typeof value !== "function") return value;
5839
+ let method = bound.get(value);
5840
+ if (method === void 0) {
5841
+ method = value.bind(target);
5842
+ bound.set(value, method);
5843
+ }
5844
+ return method;
5845
+ }
5846
+ });
5847
+ }
5848
+ };
5849
+
5762
5850
  // src/fs/physical-path.ts
5763
5851
  var MAX_HOPS = 40;
5764
5852
  function start(path) {
@@ -7580,6 +7668,7 @@ async function run(entry, path, req) {
7580
7668
  case "create":
7581
7669
  await createExclusive(fs, path, ownerFor2(entry, req.mode ?? 438));
7582
7670
  entry.created?.add(path);
7671
+ entry.fresh?.(path);
7583
7672
  return done;
7584
7673
  case "readlink":
7585
7674
  return json2(await fs.readlink(path));
@@ -7678,11 +7767,39 @@ async function accessOp(entry, path, req) {
7678
7767
  await need({ ...g, cred }, open ? "open" : "access", path, req.mode ?? 0, options);
7679
7768
  return done;
7680
7769
  }
7770
+ var CHANGING = /* @__PURE__ */ new Set([
7771
+ "mkdir",
7772
+ "create",
7773
+ "symlink",
7774
+ "unlink",
7775
+ "rmdir",
7776
+ "rm",
7777
+ "rename",
7778
+ "link",
7779
+ "utimes",
7780
+ "lutimes",
7781
+ "chmod",
7782
+ "chown",
7783
+ "lchown"
7784
+ ]);
7785
+ var CONTENT = /* @__PURE__ */ new Set(["write", "pwrite", "truncate"]);
7786
+ async function mayChange(entry, path, req) {
7787
+ const { mayChange: mayChange2 } = entry.fs;
7788
+ if (!mayChange2) return;
7789
+ const { op } = req;
7790
+ if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
7791
+ if (!CHANGING.has(op)) return;
7792
+ await mayChange2.call(entry.fs, path, op === "utimes" || op === "chmod" || op === "chown");
7793
+ if (op === "rename" || op === "link") {
7794
+ await mayChange2.call(entry.fs, entry.fs.resolvePath(entry.cwd, req.arg2 ?? ""), false);
7795
+ }
7796
+ }
7681
7797
  async function guarded(entry, path, req) {
7682
7798
  const g = guardOf(entry);
7683
7799
  if (!g) return void 0;
7684
7800
  if (LOOKS.has(req.op) && await entry.holdsKept?.(path)) return void 0;
7685
7801
  try {
7802
+ await mayChange(entry, path, req);
7686
7803
  await guard(g, path, req, entry.cwd);
7687
7804
  return void 0;
7688
7805
  } catch (err) {
@@ -12347,6 +12464,7 @@ var WasmProcess = class {
12347
12464
  throw Object.assign(new Error(alias.refused), { code: alias.refused });
12348
12465
  if (alias !== void 0) return this.openProc(req, alias);
12349
12466
  await refuseReadonly(this.options.fs, req.path, req.flags, req);
12467
+ if (this.writesAt(req)) await this.options.fs.mayChange?.(req.path, !req.exclusive);
12350
12468
  await this.mayOpen(req);
12351
12469
  const fd = this.fds.install(heldFile(), 3);
12352
12470
  try {
@@ -13217,6 +13335,7 @@ function holdingToken(opts, holds, caller) {
13217
13335
  return mintSyncFsToken({
13218
13336
  ...opts.owners ? caller : {},
13219
13337
  ...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
13338
+ ...opts.fresh ? { fresh: (path) => opts.fresh?.(path, caller.umask()) } : {},
13220
13339
  fs: opts.fs,
13221
13340
  cwd: opts.cwd,
13222
13341
  ...opts.statfs ? { statfs: opts.statfs } : {},
@@ -16158,6 +16277,7 @@ var Launcher = class {
16158
16277
  described = /* @__PURE__ */ new Map();
16159
16278
  creds = /* @__PURE__ */ new Map();
16160
16279
  tags = /* @__PURE__ */ new Map();
16280
+ freshModules = new FreshModules();
16161
16281
  granted = /* @__PURE__ */ new Map();
16162
16282
  users;
16163
16283
  sudoer;
@@ -16228,7 +16348,8 @@ var Launcher = class {
16228
16348
  changed: this.watchers.changed.bind(this.watchers),
16229
16349
  owners: this.owners
16230
16350
  });
16231
- this.base = this.watchers.wrap(this.mounts.wrap(options.fs));
16351
+ const watched = this.watchers.wrap(this.mounts.wrap(options.fs));
16352
+ this.base = this.owners ? this.freshModules.wrap(watched) : watched;
16232
16353
  this.createWorker = options.createWorker;
16233
16354
  this.createDriverWorker = options.createDriverWorker;
16234
16355
  this.media = options.media ?? memoryMedia();
@@ -16631,6 +16752,7 @@ var Launcher = class {
16631
16752
  ...req.ignored ? { ignored: req.ignored } : {},
16632
16753
  ...req.umask !== void 0 ? { umask: req.umask } : {},
16633
16754
  cred: req.cred,
16755
+ ...this.owners && req.program.abi === "wasi" ? { fresh: (path, umask) => this.freshModules.add(path, umask, pid) } : {},
16634
16756
  ...this.owners ? { owners: true } : {},
16635
16757
  sealed: this.sealed,
16636
16758
  clipboard: this.clipboard,
@@ -16693,6 +16815,7 @@ var Launcher = class {
16693
16815
  (state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
16694
16816
  );
16695
16817
  void handle.exited.then(() => {
16818
+ this.freshModules.forget(pid);
16696
16819
  const spent = handle.times?.();
16697
16820
  if (spent) this.spent.set(pid, spent);
16698
16821
  if (spent) addTimes(this.imageTimes, this.jobs.shown(pid), spent);
@@ -17359,8 +17482,9 @@ var Launcher = class {
17359
17482
  return this.writers;
17360
17483
  }
17361
17484
  writerStack() {
17485
+ const watched = this.watchers.wrap(this.mounts.wrap(this.unguardedRoot));
17362
17486
  const fs = withCommandDirs(
17363
- this.watchers.wrap(this.mounts.wrap(this.unguardedRoot)),
17487
+ this.owners ? this.freshModules.wrap(watched) : watched,
17364
17488
  async () => new Set((await this.commands()).keys()),
17365
17489
  (dir) => this.userCommandDir(dir),
17366
17490
  this.owners