@ai-ecoverse/slicc-kernel 1.77.0 → 1.77.1
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/README.md +2 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel-worker.js +125 -2
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.js +24 -3
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +125 -2
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +24 -3
- package/dist/process-worker.js.map +3 -3
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -373,6 +373,9 @@ function writerTags(protection) {
|
|
|
373
373
|
return new Set(writers);
|
|
374
374
|
}
|
|
375
375
|
function protectedPrefixes(paths) {
|
|
376
|
+
if (!Array.isArray(paths) || paths.some((p) => typeof p !== "string" || !p.startsWith("/"))) {
|
|
377
|
+
throw new TypeError("protect.paths must be a list of absolute paths");
|
|
378
|
+
}
|
|
376
379
|
return [...new Set(paths.map((p) => normalizePath(p)))];
|
|
377
380
|
}
|
|
378
381
|
function within(path, prefix) {
|
|
@@ -476,6 +479,9 @@ var ProtectedFs = class {
|
|
|
476
479
|
await check(path, true);
|
|
477
480
|
return fs.utimes(path, atime, mtime);
|
|
478
481
|
},
|
|
482
|
+
async mayChange(path, follow2) {
|
|
483
|
+
await check(path, follow2);
|
|
484
|
+
},
|
|
479
485
|
async stat(path) {
|
|
480
486
|
return marked(path, await fs.stat(path));
|
|
481
487
|
},
|
|
@@ -1155,6 +1161,10 @@ var OpfsFs = class {
|
|
|
1155
1161
|
};
|
|
1156
1162
|
}
|
|
1157
1163
|
async describe(found) {
|
|
1164
|
+
const stat = await this.described(found);
|
|
1165
|
+
return isProtected(this.guarded, found.path) ? { ...stat, readonly: true } : stat;
|
|
1166
|
+
}
|
|
1167
|
+
async described(found) {
|
|
1158
1168
|
if (found.link) return this.owned(this.linkStat(found.link), found.path, found.link);
|
|
1159
1169
|
const touched = this.timesOf(found.path);
|
|
1160
1170
|
if (!this.owners) {
|
|
@@ -7318,6 +7328,83 @@ function withCommandDirs(fs, names, userDir = async () => void 0, owners = false
|
|
|
7318
7328
|
};
|
|
7319
7329
|
}
|
|
7320
7330
|
|
|
7331
|
+
// src/fs/fresh-modules.ts
|
|
7332
|
+
var MAGIC = [0, 97, 115, 109];
|
|
7333
|
+
var MAX_FRESH = 65536;
|
|
7334
|
+
function isModule(bytes) {
|
|
7335
|
+
return MAGIC.every((b, i) => bytes[i] === b);
|
|
7336
|
+
}
|
|
7337
|
+
var FreshModules = class {
|
|
7338
|
+
fresh = /* @__PURE__ */ new Map();
|
|
7339
|
+
add(path, umask, pid) {
|
|
7340
|
+
const key = normalizePath(path);
|
|
7341
|
+
this.fresh.delete(key);
|
|
7342
|
+
const oldest = this.fresh.size >= MAX_FRESH ? this.fresh.keys().next().value : void 0;
|
|
7343
|
+
if (oldest !== void 0) this.fresh.delete(oldest);
|
|
7344
|
+
this.fresh.set(key, { umask: umask & 511, pid, added: 0 });
|
|
7345
|
+
}
|
|
7346
|
+
forget(pid) {
|
|
7347
|
+
for (const [path, fresh2] of this.fresh) if (fresh2.pid === pid) this.fresh.delete(path);
|
|
7348
|
+
}
|
|
7349
|
+
wrap(fs) {
|
|
7350
|
+
const decide = async (given, bytes) => {
|
|
7351
|
+
const path = normalizePath(given);
|
|
7352
|
+
const fresh2 = this.fresh.get(path);
|
|
7353
|
+
if (!fresh2 || typeof bytes === "string" || bytes.length < MAGIC.length) return;
|
|
7354
|
+
const want = isModule(bytes) ? 73 & ~fresh2.umask : 0;
|
|
7355
|
+
if (want === fresh2.added) return;
|
|
7356
|
+
const mode = (await fs.stat(path)).mode & 4095;
|
|
7357
|
+
await fs.chmod(path, mode & ~fresh2.added | want);
|
|
7358
|
+
fresh2.added = want;
|
|
7359
|
+
};
|
|
7360
|
+
const overrides = {
|
|
7361
|
+
writeFile: async (path, content, owner) => {
|
|
7362
|
+
await fs.writeFile(path, content, owner);
|
|
7363
|
+
await decide(path, content);
|
|
7364
|
+
},
|
|
7365
|
+
chmod: async (path, mode) => {
|
|
7366
|
+
const fresh2 = this.fresh.get(normalizePath(path));
|
|
7367
|
+
const creating = fresh2?.added === 0 && (mode & 4095) === (438 & ~fresh2.umask);
|
|
7368
|
+
if (!creating) this.fresh.delete(normalizePath(path));
|
|
7369
|
+
await fs.chmod(path, mode);
|
|
7370
|
+
},
|
|
7371
|
+
rm: async (path, options) => {
|
|
7372
|
+
this.fresh.delete(normalizePath(path));
|
|
7373
|
+
await fs.rm(path, options);
|
|
7374
|
+
},
|
|
7375
|
+
rename: async (from, to) => {
|
|
7376
|
+
await fs.rename(from, to);
|
|
7377
|
+
const fresh2 = this.fresh.get(normalizePath(from));
|
|
7378
|
+
this.fresh.delete(normalizePath(from));
|
|
7379
|
+
this.fresh.delete(normalizePath(to));
|
|
7380
|
+
if (fresh2) this.fresh.set(normalizePath(to), fresh2);
|
|
7381
|
+
}
|
|
7382
|
+
};
|
|
7383
|
+
const ranged2 = rangedOps(fs);
|
|
7384
|
+
if (ranged2) {
|
|
7385
|
+
overrides.pwrite = async (path, at, bytes, transfer) => {
|
|
7386
|
+
const head = at === 0 && this.fresh.has(normalizePath(path)) ? bytes.slice(0, 4) : void 0;
|
|
7387
|
+
await ranged2.pwrite(path, at, bytes, transfer);
|
|
7388
|
+
if (head) await decide(path, head);
|
|
7389
|
+
};
|
|
7390
|
+
}
|
|
7391
|
+
const bound = /* @__PURE__ */ new WeakMap();
|
|
7392
|
+
return new Proxy(fs, {
|
|
7393
|
+
get(target, key, receiver) {
|
|
7394
|
+
if (Object.hasOwn(overrides, key)) return overrides[key];
|
|
7395
|
+
const value = Reflect.get(target, key, receiver);
|
|
7396
|
+
if (typeof value !== "function") return value;
|
|
7397
|
+
let method = bound.get(value);
|
|
7398
|
+
if (method === void 0) {
|
|
7399
|
+
method = value.bind(target);
|
|
7400
|
+
bound.set(value, method);
|
|
7401
|
+
}
|
|
7402
|
+
return method;
|
|
7403
|
+
}
|
|
7404
|
+
});
|
|
7405
|
+
}
|
|
7406
|
+
};
|
|
7407
|
+
|
|
7321
7408
|
// src/fs/physical-path.ts
|
|
7322
7409
|
var MAX_HOPS = 40;
|
|
7323
7410
|
function start(path) {
|
|
@@ -9194,6 +9281,7 @@ async function run(entry, path, req) {
|
|
|
9194
9281
|
case "create":
|
|
9195
9282
|
await createExclusive(fs, path, ownerFor2(entry, req.mode ?? 438));
|
|
9196
9283
|
entry.created?.add(path);
|
|
9284
|
+
entry.fresh?.(path);
|
|
9197
9285
|
return done;
|
|
9198
9286
|
case "readlink":
|
|
9199
9287
|
return json2(await fs.readlink(path));
|
|
@@ -9292,11 +9380,39 @@ async function accessOp(entry, path, req) {
|
|
|
9292
9380
|
await need({ ...g, cred }, open ? "open" : "access", path, req.mode ?? 0, options);
|
|
9293
9381
|
return done;
|
|
9294
9382
|
}
|
|
9383
|
+
var CHANGING = /* @__PURE__ */ new Set([
|
|
9384
|
+
"mkdir",
|
|
9385
|
+
"create",
|
|
9386
|
+
"symlink",
|
|
9387
|
+
"unlink",
|
|
9388
|
+
"rmdir",
|
|
9389
|
+
"rm",
|
|
9390
|
+
"rename",
|
|
9391
|
+
"link",
|
|
9392
|
+
"utimes",
|
|
9393
|
+
"lutimes",
|
|
9394
|
+
"chmod",
|
|
9395
|
+
"chown",
|
|
9396
|
+
"lchown"
|
|
9397
|
+
]);
|
|
9398
|
+
var CONTENT = /* @__PURE__ */ new Set(["write", "pwrite", "truncate"]);
|
|
9399
|
+
async function mayChange(entry, path, req) {
|
|
9400
|
+
const { mayChange: mayChange2 } = entry.fs;
|
|
9401
|
+
if (!mayChange2) return;
|
|
9402
|
+
const { op } = req;
|
|
9403
|
+
if (CONTENT.has(op) && req.handle === void 0) return mayChange2.call(entry.fs, path, true);
|
|
9404
|
+
if (!CHANGING.has(op)) return;
|
|
9405
|
+
await mayChange2.call(entry.fs, path, op === "utimes" || op === "chmod" || op === "chown");
|
|
9406
|
+
if (op === "rename" || op === "link") {
|
|
9407
|
+
await mayChange2.call(entry.fs, entry.fs.resolvePath(entry.cwd, req.arg2 ?? ""), false);
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
9295
9410
|
async function guarded(entry, path, req) {
|
|
9296
9411
|
const g = guardOf(entry);
|
|
9297
9412
|
if (!g) return void 0;
|
|
9298
9413
|
if (LOOKS.has(req.op) && await entry.holdsKept?.(path)) return void 0;
|
|
9299
9414
|
try {
|
|
9415
|
+
await mayChange(entry, path, req);
|
|
9300
9416
|
await guard(g, path, req, entry.cwd);
|
|
9301
9417
|
return void 0;
|
|
9302
9418
|
} catch (err) {
|
|
@@ -12613,6 +12729,7 @@ var WasmProcess = class {
|
|
|
12613
12729
|
throw Object.assign(new Error(alias.refused), { code: alias.refused });
|
|
12614
12730
|
if (alias !== void 0) return this.openProc(req, alias);
|
|
12615
12731
|
await refuseReadonly(this.options.fs, req.path, req.flags, req);
|
|
12732
|
+
if (this.writesAt(req)) await this.options.fs.mayChange?.(req.path, !req.exclusive);
|
|
12616
12733
|
await this.mayOpen(req);
|
|
12617
12734
|
const fd = this.fds.install(heldFile(), 3);
|
|
12618
12735
|
try {
|
|
@@ -13483,6 +13600,7 @@ function holdingToken(opts, holds, caller) {
|
|
|
13483
13600
|
return mintSyncFsToken({
|
|
13484
13601
|
...opts.owners ? caller : {},
|
|
13485
13602
|
...opts.dac ? { dac: opts.dac, pid: opts.pid, created: caller.created } : {},
|
|
13603
|
+
...opts.fresh ? { fresh: (path) => opts.fresh?.(path, caller.umask()) } : {},
|
|
13486
13604
|
fs: opts.fs,
|
|
13487
13605
|
cwd: opts.cwd,
|
|
13488
13606
|
...opts.statfs ? { statfs: opts.statfs } : {},
|
|
@@ -16321,6 +16439,7 @@ var Launcher = class {
|
|
|
16321
16439
|
described = /* @__PURE__ */ new Map();
|
|
16322
16440
|
creds = /* @__PURE__ */ new Map();
|
|
16323
16441
|
tags = /* @__PURE__ */ new Map();
|
|
16442
|
+
freshModules = new FreshModules();
|
|
16324
16443
|
granted = /* @__PURE__ */ new Map();
|
|
16325
16444
|
users;
|
|
16326
16445
|
sudoer;
|
|
@@ -16391,7 +16510,8 @@ var Launcher = class {
|
|
|
16391
16510
|
changed: this.watchers.changed.bind(this.watchers),
|
|
16392
16511
|
owners: this.owners
|
|
16393
16512
|
});
|
|
16394
|
-
|
|
16513
|
+
const watched = this.watchers.wrap(this.mounts.wrap(options.fs));
|
|
16514
|
+
this.base = this.owners ? this.freshModules.wrap(watched) : watched;
|
|
16395
16515
|
this.createWorker = options.createWorker;
|
|
16396
16516
|
this.createDriverWorker = options.createDriverWorker;
|
|
16397
16517
|
this.media = options.media ?? memoryMedia();
|
|
@@ -16794,6 +16914,7 @@ var Launcher = class {
|
|
|
16794
16914
|
...req.ignored ? { ignored: req.ignored } : {},
|
|
16795
16915
|
...req.umask !== void 0 ? { umask: req.umask } : {},
|
|
16796
16916
|
cred: req.cred,
|
|
16917
|
+
...this.owners && req.program.abi === "wasi" ? { fresh: (path, umask) => this.freshModules.add(path, umask, pid) } : {},
|
|
16797
16918
|
...this.owners ? { owners: true } : {},
|
|
16798
16919
|
sealed: this.sealed,
|
|
16799
16920
|
clipboard: this.clipboard,
|
|
@@ -16856,6 +16977,7 @@ var Launcher = class {
|
|
|
16856
16977
|
(state) => state === "stopped" ? this.stopped.add(pid) : this.stopped.delete(pid)
|
|
16857
16978
|
);
|
|
16858
16979
|
void handle.exited.then(() => {
|
|
16980
|
+
this.freshModules.forget(pid);
|
|
16859
16981
|
const spent = handle.times?.();
|
|
16860
16982
|
if (spent) this.spent.set(pid, spent);
|
|
16861
16983
|
if (spent) addTimes(this.imageTimes, this.jobs.shown(pid), spent);
|
|
@@ -17522,8 +17644,9 @@ var Launcher = class {
|
|
|
17522
17644
|
return this.writers;
|
|
17523
17645
|
}
|
|
17524
17646
|
writerStack() {
|
|
17647
|
+
const watched = this.watchers.wrap(this.mounts.wrap(this.unguardedRoot));
|
|
17525
17648
|
const fs = withCommandDirs(
|
|
17526
|
-
this.
|
|
17649
|
+
this.owners ? this.freshModules.wrap(watched) : watched,
|
|
17527
17650
|
async () => new Set((await this.commands()).keys()),
|
|
17528
17651
|
(dir) => this.userCommandDir(dir),
|
|
17529
17652
|
this.owners
|