@ai-ecoverse/slicc-kernel 1.85.1 → 1.86.0
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 +13 -7
- package/dist/index.js +1 -0
- package/dist/index.js.map +2 -2
- package/dist/kernel-worker.js +88 -12
- package/dist/kernel-worker.js.map +2 -2
- package/dist/meta.js +384 -0
- package/dist/meta.js.map +7 -0
- package/dist/node-process-worker.js +69 -15
- package/dist/node-process-worker.js.map +3 -3
- package/dist/node.js +65 -12
- package/dist/node.js.map +2 -2
- package/dist/process-worker.js +69 -15
- package/dist/process-worker.js.map +3 -3
- package/package.json +3 -2
package/dist/kernel-worker.js
CHANGED
|
@@ -97,6 +97,9 @@ var MemoryMeta = class {
|
|
|
97
97
|
async get(paths) {
|
|
98
98
|
return paths.map((path) => this.entries.get(path));
|
|
99
99
|
}
|
|
100
|
+
async fresh(path) {
|
|
101
|
+
return this.entries.get(path);
|
|
102
|
+
}
|
|
100
103
|
async update(path, change) {
|
|
101
104
|
this.set(path, change(this.entries.get(path)));
|
|
102
105
|
}
|
|
@@ -193,6 +196,16 @@ var IndexedDbMeta = class {
|
|
|
193
196
|
}
|
|
194
197
|
return paths.map((path) => this.cache.get(path) ?? void 0);
|
|
195
198
|
}
|
|
199
|
+
async fresh(path) {
|
|
200
|
+
const [transaction, store] = this.transaction("readonly");
|
|
201
|
+
const request2 = store.get(path);
|
|
202
|
+
let entry;
|
|
203
|
+
request2.onsuccess = () => {
|
|
204
|
+
entry = request2.result ?? void 0;
|
|
205
|
+
};
|
|
206
|
+
await settle(transaction, () => void 0);
|
|
207
|
+
return entry;
|
|
208
|
+
}
|
|
196
209
|
async update(path, change) {
|
|
197
210
|
this.settleRemoves();
|
|
198
211
|
const [transaction, store] = this.transaction("readwrite");
|
|
@@ -207,6 +220,19 @@ var IndexedDbMeta = class {
|
|
|
207
220
|
this.changed({ paths: [path] });
|
|
208
221
|
this.cache.set(path, next2 ?? null);
|
|
209
222
|
}
|
|
223
|
+
async updateMany(changes) {
|
|
224
|
+
const [transaction, store] = this.transaction("readwrite");
|
|
225
|
+
for (const { path, change } of changes) {
|
|
226
|
+
const request2 = store.get(path);
|
|
227
|
+
request2.onsuccess = () => store.put(change(request2.result));
|
|
228
|
+
}
|
|
229
|
+
await settle(transaction, () => void 0);
|
|
230
|
+
this.changed({ paths: changes.map(({ path }) => path) });
|
|
231
|
+
}
|
|
232
|
+
close() {
|
|
233
|
+
this.channel.close();
|
|
234
|
+
this.db.close();
|
|
235
|
+
}
|
|
210
236
|
async move(from, to, root) {
|
|
211
237
|
this.settleRemoves();
|
|
212
238
|
const [transaction, store] = this.transaction("readwrite");
|
|
@@ -326,6 +352,12 @@ async function lutimesOf(fs, path, atime, mtime) {
|
|
|
326
352
|
function mayLink(fs, path) {
|
|
327
353
|
return fs.links?.(path) ?? true;
|
|
328
354
|
}
|
|
355
|
+
function modeOption(mode) {
|
|
356
|
+
if (!Number.isInteger(mode) || mode < 0 || mode > 4095) {
|
|
357
|
+
throw fsError("EINVAL", `not a mode: ${String(mode)}`);
|
|
358
|
+
}
|
|
359
|
+
return mode;
|
|
360
|
+
}
|
|
329
361
|
function fsError(code, path) {
|
|
330
362
|
return Object.assign(new Error(`${code}: ${path}`), { code });
|
|
331
363
|
}
|
|
@@ -857,7 +889,8 @@ function sidecar(meta) {
|
|
|
857
889
|
const guarded2 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
858
890
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
859
891
|
});
|
|
860
|
-
const
|
|
892
|
+
const names = meta.fresh ? [...META_OPS, "fresh"] : META_OPS;
|
|
893
|
+
const ops = Object.fromEntries(names.map((op) => [op, guarded2(op)]));
|
|
861
894
|
if (meta.absent) ops.absent = meta.absent.bind(meta);
|
|
862
895
|
const { removeFile } = meta;
|
|
863
896
|
if (removeFile)
|
|
@@ -985,6 +1018,24 @@ var OpfsFs = class {
|
|
|
985
1018
|
committed(target) {
|
|
986
1019
|
if (this.remote?.watched()) this.remote.wrote(target);
|
|
987
1020
|
}
|
|
1021
|
+
counted = [];
|
|
1022
|
+
async stamp(path) {
|
|
1023
|
+
const entry = this.meta.fresh ? await this.meta.fresh(path) : (await this.meta.get([path]))[0];
|
|
1024
|
+
return String(entry?.writes ?? 0);
|
|
1025
|
+
}
|
|
1026
|
+
async counting(target) {
|
|
1027
|
+
if (!isProtected(this.counted, target)) return;
|
|
1028
|
+
await this.meta.update(target, (entry) => ({
|
|
1029
|
+
...entry,
|
|
1030
|
+
path: target,
|
|
1031
|
+
writes: (entry?.writes ?? 0) + 1
|
|
1032
|
+
}));
|
|
1033
|
+
}
|
|
1034
|
+
async recounting(handle, target) {
|
|
1035
|
+
if (this.counted.length === 0) return;
|
|
1036
|
+
const where = await this.root.resolve(handle).catch(() => null);
|
|
1037
|
+
await this.counting(where ? `/${where.join("/")}` : target);
|
|
1038
|
+
}
|
|
988
1039
|
resolvePath(base, path) {
|
|
989
1040
|
return resolvePath(base, path);
|
|
990
1041
|
}
|
|
@@ -1043,6 +1094,7 @@ var OpfsFs = class {
|
|
|
1043
1094
|
guarded = [];
|
|
1044
1095
|
protect(prefixes2) {
|
|
1045
1096
|
this.guarded = prefixes2;
|
|
1097
|
+
this.counted = prefixes2;
|
|
1046
1098
|
}
|
|
1047
1099
|
unguarded() {
|
|
1048
1100
|
return Object.create(this, { guarded: { value: [] } });
|
|
@@ -1379,9 +1431,10 @@ var OpfsFs = class {
|
|
|
1379
1431
|
return this.retrying(
|
|
1380
1432
|
path,
|
|
1381
1433
|
async () => {
|
|
1434
|
+
const stamp = await this.stamp(path);
|
|
1382
1435
|
const file = await handle.getFile();
|
|
1383
1436
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
1384
|
-
return { bytes, version: `${file.lastModified}:${file.size}` };
|
|
1437
|
+
return { bytes, version: `${file.lastModified}:${file.size}:${stamp}` };
|
|
1385
1438
|
},
|
|
1386
1439
|
false
|
|
1387
1440
|
);
|
|
@@ -1391,8 +1444,9 @@ var OpfsFs = class {
|
|
|
1391
1444
|
return this.retrying(
|
|
1392
1445
|
path,
|
|
1393
1446
|
async () => {
|
|
1447
|
+
const stamp = await this.stamp(path);
|
|
1394
1448
|
const file = await handle.getFile();
|
|
1395
|
-
return `${file.lastModified}:${file.size}`;
|
|
1449
|
+
return `${file.lastModified}:${file.size}:${stamp}`;
|
|
1396
1450
|
},
|
|
1397
1451
|
false
|
|
1398
1452
|
);
|
|
@@ -1407,14 +1461,24 @@ var OpfsFs = class {
|
|
|
1407
1461
|
}
|
|
1408
1462
|
async pwrite(path, offset, bytes) {
|
|
1409
1463
|
const [handle, , target] = await this.fileFor(path);
|
|
1410
|
-
await this.
|
|
1464
|
+
await this.counting(target);
|
|
1465
|
+
try {
|
|
1466
|
+
await this.retrying(path, () => positioned(handle, (io) => io.write(offset, bytes)), true);
|
|
1467
|
+
} finally {
|
|
1468
|
+
await this.recounting(handle, target);
|
|
1469
|
+
}
|
|
1411
1470
|
this.written(target);
|
|
1412
1471
|
}
|
|
1413
1472
|
async truncate(path, size) {
|
|
1414
1473
|
const handle = await this.existing(path, true);
|
|
1415
1474
|
const resolve2 = this.ranged || this.remote?.watched();
|
|
1416
|
-
const target = resolve2 ? (await this.locate(path, true)).path : path;
|
|
1417
|
-
await this.
|
|
1475
|
+
const target = resolve2 || this.counted.length > 0 ? (await this.locate(path, true)).path : path;
|
|
1476
|
+
await this.counting(target);
|
|
1477
|
+
try {
|
|
1478
|
+
await this.retrying(path, () => positioned(handle, (io) => io.truncate(size)), true);
|
|
1479
|
+
} finally {
|
|
1480
|
+
await this.recounting(handle, target);
|
|
1481
|
+
}
|
|
1418
1482
|
this.written(target);
|
|
1419
1483
|
}
|
|
1420
1484
|
async writeSession(path, truncate) {
|
|
@@ -2339,7 +2403,9 @@ function id(value) {
|
|
|
2339
2403
|
return value;
|
|
2340
2404
|
}
|
|
2341
2405
|
function changeCred(cur, change) {
|
|
2342
|
-
if (typeof change !== "object" || change === null
|
|
2406
|
+
if (typeof change !== "object" || change === null || Array.isArray(change)) {
|
|
2407
|
+
throw fsError("EINVAL", "not a change");
|
|
2408
|
+
}
|
|
2343
2409
|
const privileged = cur.euid === 0;
|
|
2344
2410
|
const next2 = copyCred(cur);
|
|
2345
2411
|
for (const keys of [UIDS, GIDS]) {
|
|
@@ -18613,17 +18679,21 @@ var Launcher = class {
|
|
|
18613
18679
|
const real = await this.realLayoutPath("/tmp");
|
|
18614
18680
|
const st = real === void 0 ? void 0 : await this.base.lstat(real).catch(() => void 0);
|
|
18615
18681
|
if (real !== void 0 && st?.isDirectory && this.base.hasOwner && !await this.base.hasOwner(real)) {
|
|
18682
|
+
const names = await this.base.readdir(real).catch(() => void 0);
|
|
18616
18683
|
let removed = 0;
|
|
18617
|
-
|
|
18684
|
+
let left = names === void 0 ? 1 : 0;
|
|
18685
|
+
for (const name2 of names ?? []) {
|
|
18618
18686
|
const path = joinName(real, name2);
|
|
18619
|
-
if (await this.base.hasOwner(path)
|
|
18620
|
-
const failed3 = await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
18687
|
+
if (await this.base.hasOwner(path)) continue;
|
|
18688
|
+
const failed3 = this.inUse(path) ? "busy" : await this.base.rm(path, { recursive: true, force: true }).catch(String);
|
|
18621
18689
|
if (failed3 === void 0) removed++;
|
|
18690
|
+
else left++;
|
|
18622
18691
|
}
|
|
18623
18692
|
if (removed > 0) {
|
|
18624
18693
|
console.warn(`slicc-kernel users: removed ${removed} entries from /tmp that had no owner`);
|
|
18625
18694
|
}
|
|
18626
|
-
|
|
18695
|
+
if (left === 0)
|
|
18696
|
+
await this.base.chown?.(real, { uid: 0, gid: 0, mode: 1023, follow: false });
|
|
18627
18697
|
}
|
|
18628
18698
|
if (st?.isDirectory) await this.base.chmod(real, 1023);
|
|
18629
18699
|
}
|
|
@@ -19076,7 +19146,12 @@ var USERS_OPS = /* @__PURE__ */ new Set([
|
|
|
19076
19146
|
"groups-add-member",
|
|
19077
19147
|
"groups-remove-member"
|
|
19078
19148
|
]);
|
|
19079
|
-
var ATTEST_OPS = /* @__PURE__ */ new Set([
|
|
19149
|
+
var ATTEST_OPS = /* @__PURE__ */ new Set([
|
|
19150
|
+
"attest",
|
|
19151
|
+
"watch-files",
|
|
19152
|
+
"unwatch-files",
|
|
19153
|
+
"chmod"
|
|
19154
|
+
]);
|
|
19080
19155
|
function isAttestRequest(req) {
|
|
19081
19156
|
return ATTEST_OPS.has(req.op);
|
|
19082
19157
|
}
|
|
@@ -19092,6 +19167,7 @@ function attestOps(port) {
|
|
|
19092
19167
|
const watches = /* @__PURE__ */ new Map();
|
|
19093
19168
|
return async (l, req) => {
|
|
19094
19169
|
if (req.op === "attest") return l.attest(req.path);
|
|
19170
|
+
if (req.op === "chmod") return l.fs.chmod(req.path, modeOption(req.mode)).then(() => true);
|
|
19095
19171
|
if (req.op === "unwatch-files") {
|
|
19096
19172
|
watches.get(req.watch)?.();
|
|
19097
19173
|
return watches.delete(req.watch);
|