@ai-ecoverse/slicc-kernel 1.84.0 → 1.85.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 +2 -2
- package/dist/index.js.map +1 -1
- package/dist/kernel-worker.js +123 -7
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +14 -5
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +75 -7
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +14 -5
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -117,6 +117,9 @@ var MemoryMeta = class {
|
|
|
117
117
|
async remove(paths) {
|
|
118
118
|
for (const path of paths) this.entries.deleteTree(path);
|
|
119
119
|
}
|
|
120
|
+
absent(path) {
|
|
121
|
+
return !this.entries.has(path);
|
|
122
|
+
}
|
|
120
123
|
async links(dir) {
|
|
121
124
|
return [...this.entries.entries()].map(([, e]) => e).filter((entry) => entry.dir === dir);
|
|
122
125
|
}
|
|
@@ -136,6 +139,8 @@ function settle(transaction, value) {
|
|
|
136
139
|
transaction.onabort = () => reject(transaction.error ?? new Error("metadata transaction aborted"));
|
|
137
140
|
});
|
|
138
141
|
}
|
|
142
|
+
var REMOVE_BATCH = 256;
|
|
143
|
+
var REMOVE_WAIT_MS = 5;
|
|
139
144
|
var IndexedDbMeta = class {
|
|
140
145
|
db;
|
|
141
146
|
cache = new PathMap();
|
|
@@ -171,6 +176,7 @@ var IndexedDbMeta = class {
|
|
|
171
176
|
async get(paths) {
|
|
172
177
|
const missing4 = paths.filter((path) => !this.cache.has(path));
|
|
173
178
|
if (missing4.length > 0) {
|
|
179
|
+
this.settleRemoves();
|
|
174
180
|
const generation = this.generation;
|
|
175
181
|
const [transaction, store] = this.transaction("readonly");
|
|
176
182
|
const found = /* @__PURE__ */ new Map();
|
|
@@ -188,6 +194,7 @@ var IndexedDbMeta = class {
|
|
|
188
194
|
return paths.map((path) => this.cache.get(path) ?? void 0);
|
|
189
195
|
}
|
|
190
196
|
async update(path, change) {
|
|
197
|
+
this.settleRemoves();
|
|
191
198
|
const [transaction, store] = this.transaction("readwrite");
|
|
192
199
|
const request2 = store.get(path);
|
|
193
200
|
let next2;
|
|
@@ -201,6 +208,7 @@ var IndexedDbMeta = class {
|
|
|
201
208
|
this.cache.set(path, next2 ?? null);
|
|
202
209
|
}
|
|
203
210
|
async move(from, to, root) {
|
|
211
|
+
this.settleRemoves();
|
|
204
212
|
const [transaction, store] = this.transaction("readwrite");
|
|
205
213
|
store.delete(to);
|
|
206
214
|
store.delete(descendants(to));
|
|
@@ -217,7 +225,28 @@ var IndexedDbMeta = class {
|
|
|
217
225
|
await settle(transaction, () => void 0);
|
|
218
226
|
this.changed({ trees: [from, to] });
|
|
219
227
|
}
|
|
228
|
+
absent(path) {
|
|
229
|
+
return this.cache.has(path) && this.cache.get(path) === null;
|
|
230
|
+
}
|
|
231
|
+
removing = /* @__PURE__ */ new Map();
|
|
232
|
+
removeTimer;
|
|
220
233
|
async remove(paths) {
|
|
234
|
+
this.settleRemoves();
|
|
235
|
+
return this.removeNow(paths);
|
|
236
|
+
}
|
|
237
|
+
async removeFile(path) {
|
|
238
|
+
const known = this.cache.get(path);
|
|
239
|
+
if (!known) return this.remove([path]);
|
|
240
|
+
this.generation++;
|
|
241
|
+
this.cache.set(path, null);
|
|
242
|
+
this.removing.set(path, JSON.stringify(known));
|
|
243
|
+
if (this.removing.size >= REMOVE_BATCH) return this.flushRemoves();
|
|
244
|
+
this.removeTimer ??= setTimeout(
|
|
245
|
+
() => void this.flushRemoves().catch(() => void 0),
|
|
246
|
+
REMOVE_WAIT_MS
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
async removeNow(paths) {
|
|
221
250
|
const [transaction, store] = this.transaction("readwrite");
|
|
222
251
|
for (const path of paths) {
|
|
223
252
|
store.delete(path);
|
|
@@ -226,12 +255,33 @@ var IndexedDbMeta = class {
|
|
|
226
255
|
await settle(transaction, () => void 0);
|
|
227
256
|
this.changed({ trees: paths });
|
|
228
257
|
}
|
|
258
|
+
settleRemoves() {
|
|
259
|
+
if (this.removing.size > 0) void this.flushRemoves().catch(() => void 0);
|
|
260
|
+
}
|
|
261
|
+
flushRemoves() {
|
|
262
|
+
clearTimeout(this.removeTimer);
|
|
263
|
+
this.removeTimer = void 0;
|
|
264
|
+
const batch = this.removing;
|
|
265
|
+
if (batch.size === 0) return Promise.resolve();
|
|
266
|
+
this.removing = /* @__PURE__ */ new Map();
|
|
267
|
+
const [transaction, store] = this.transaction("readwrite");
|
|
268
|
+
for (const [path, seen] of batch) {
|
|
269
|
+
const request2 = store.get(path);
|
|
270
|
+
request2.onsuccess = () => {
|
|
271
|
+
if (request2.result && JSON.stringify(request2.result) === seen) store.delete(path);
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const paths = [...batch.keys()];
|
|
275
|
+
return settle(transaction, () => void this.channel.postMessage({ paths }));
|
|
276
|
+
}
|
|
229
277
|
async links(dir) {
|
|
278
|
+
this.settleRemoves();
|
|
230
279
|
const [transaction, store] = this.transaction("readonly");
|
|
231
280
|
const request2 = store.index("dir").getAll(dir);
|
|
232
281
|
return settle(transaction, () => request2.result);
|
|
233
282
|
}
|
|
234
283
|
async under(path) {
|
|
284
|
+
this.settleRemoves();
|
|
235
285
|
const [transaction, store] = this.transaction("readonly");
|
|
236
286
|
const self = store.get(path);
|
|
237
287
|
const below = store.getAll(descendants(path));
|
|
@@ -243,6 +293,7 @@ var IndexedDbMeta = class {
|
|
|
243
293
|
);
|
|
244
294
|
}
|
|
245
295
|
async all() {
|
|
296
|
+
this.settleRemoves();
|
|
246
297
|
const [transaction, store] = this.transaction("readonly");
|
|
247
298
|
const request2 = store.getAll();
|
|
248
299
|
return settle(transaction, () => request2.result);
|
|
@@ -806,7 +857,14 @@ function sidecar(meta) {
|
|
|
806
857
|
const guarded2 = (op) => (...args) => meta[op].apply(meta, args).catch((err) => {
|
|
807
858
|
throw translate(err, pathOf(args), "sidecar", false);
|
|
808
859
|
});
|
|
809
|
-
|
|
860
|
+
const ops = Object.fromEntries(META_OPS.map((op) => [op, guarded2(op)]));
|
|
861
|
+
if (meta.absent) ops.absent = meta.absent.bind(meta);
|
|
862
|
+
const { removeFile } = meta;
|
|
863
|
+
if (removeFile)
|
|
864
|
+
ops.removeFile = (path) => removeFile.call(meta, path).catch((err) => {
|
|
865
|
+
throw translate(err, path, "sidecar", false);
|
|
866
|
+
});
|
|
867
|
+
return ops;
|
|
810
868
|
}
|
|
811
869
|
function missing2(err) {
|
|
812
870
|
const code = err?.code;
|
|
@@ -1503,6 +1561,7 @@ var OpfsFs = class {
|
|
|
1503
1561
|
throw error;
|
|
1504
1562
|
}
|
|
1505
1563
|
this.refuse(found.path, true);
|
|
1564
|
+
if (options.file && found.handle?.kind === "directory") throw fsError("EISDIR", path);
|
|
1506
1565
|
if (found.handle) {
|
|
1507
1566
|
const [dir, name2] = await this.parent(found.path);
|
|
1508
1567
|
try {
|
|
@@ -1513,8 +1572,19 @@ var OpfsFs = class {
|
|
|
1513
1572
|
} catch (err) {
|
|
1514
1573
|
throw translate(err, path);
|
|
1515
1574
|
}
|
|
1516
|
-
|
|
1575
|
+
const file = found.handle.kind === "file";
|
|
1576
|
+
if (!file || this.remote?.watched()) this.changed(found.path);
|
|
1577
|
+
else this.forget(found.path);
|
|
1517
1578
|
this.movePending(found.path);
|
|
1579
|
+
if (file && this.meta.absent?.(found.path)) {
|
|
1580
|
+
this.touch(parentOf3(found.path));
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
if (file && this.meta.removeFile) {
|
|
1584
|
+
await this.meta.removeFile(found.path);
|
|
1585
|
+
this.touch(parentOf3(found.path));
|
|
1586
|
+
return;
|
|
1587
|
+
}
|
|
1518
1588
|
}
|
|
1519
1589
|
await this.meta.remove([found.path]);
|
|
1520
1590
|
this.touch(parentOf3(found.path));
|
|
@@ -8634,6 +8704,10 @@ var MountTable = class {
|
|
|
8634
8704
|
...error ? { error } : {}
|
|
8635
8705
|
});
|
|
8636
8706
|
}
|
|
8707
|
+
under(path) {
|
|
8708
|
+
for (const mount of this.mounts.values()) if (within6(mount.target, path)) return true;
|
|
8709
|
+
return false;
|
|
8710
|
+
}
|
|
8637
8711
|
locate(path) {
|
|
8638
8712
|
let best;
|
|
8639
8713
|
for (const mount of this.mounts.values()) {
|
|
@@ -9203,9 +9277,12 @@ var MountFs = class {
|
|
|
9203
9277
|
}
|
|
9204
9278
|
async rm(path, options = {}) {
|
|
9205
9279
|
const found = this.at(path);
|
|
9280
|
+
if (!found && options.recursive && this.table.under(normalizePath(path)))
|
|
9281
|
+
return this.rmAround(normalizePath(path), options);
|
|
9206
9282
|
if (!found) return this.base.rm(path, options);
|
|
9207
9283
|
const { mount, rel: rel2 } = found;
|
|
9208
9284
|
const real = normalizePath(path);
|
|
9285
|
+
if (rel2 === "/" && options.recursive) await this.rmEach(real, mount, rel2, options);
|
|
9209
9286
|
if (rel2 === "/") throw errnoError("EBUSY", `${real} is a mount point`);
|
|
9210
9287
|
this.writable(mount, real);
|
|
9211
9288
|
await this.table.commitUnder(real);
|
|
@@ -9216,16 +9293,33 @@ var MountFs = class {
|
|
|
9216
9293
|
if (options.force && err.code === "ENOENT") return;
|
|
9217
9294
|
throw err;
|
|
9218
9295
|
}
|
|
9296
|
+
if (options.file && attr2.kind === "directory") throw errnoError("EISDIR", real);
|
|
9219
9297
|
this.table.forget(mount, real);
|
|
9220
9298
|
if (attr2.kind === "directory" && options.recursive) {
|
|
9221
|
-
|
|
9222
|
-
await this.rm(`${real}/${entry.name}`, { recursive: true, force: options.force ?? false });
|
|
9223
|
-
}
|
|
9299
|
+
await this.rmEach(real, mount, rel2, { recursive: true, force: options.force ?? false });
|
|
9224
9300
|
this.table.forget(mount, real);
|
|
9225
9301
|
}
|
|
9226
9302
|
await mount.conn.call({ op: attr2.kind === "directory" ? "rmdir" : "unlink", path: rel2 });
|
|
9227
9303
|
this.table.forget(mount, real);
|
|
9228
9304
|
}
|
|
9305
|
+
async rmEach(real, mount, rel2, options) {
|
|
9306
|
+
let first;
|
|
9307
|
+
for (const entry of await this.table.readdir(mount, real, rel2)) {
|
|
9308
|
+
await this.rm(joinName(real, entry.name), options).catch((err) => {
|
|
9309
|
+
first ??= err;
|
|
9310
|
+
});
|
|
9311
|
+
}
|
|
9312
|
+
if (first) throw first;
|
|
9313
|
+
}
|
|
9314
|
+
async rmAround(path, options) {
|
|
9315
|
+
let first;
|
|
9316
|
+
for (const name2 of await this.base.readdir(path)) {
|
|
9317
|
+
await this.rm(joinName(path, name2), options).catch((err) => {
|
|
9318
|
+
first ??= err;
|
|
9319
|
+
});
|
|
9320
|
+
}
|
|
9321
|
+
throw first ?? errnoError("EBUSY", `${path} holds a mount point`);
|
|
9322
|
+
}
|
|
9229
9323
|
async rename(from, to) {
|
|
9230
9324
|
const a = this.at(from);
|
|
9231
9325
|
const b = this.at(to);
|
|
@@ -9529,8 +9623,7 @@ async function run(entry, path, req) {
|
|
|
9529
9623
|
await fs.link(path, fs.resolvePath(cwd, req.arg2 ?? ""), req.mode === 1);
|
|
9530
9624
|
return done;
|
|
9531
9625
|
case "unlink":
|
|
9532
|
-
|
|
9533
|
-
await fs.rm(path);
|
|
9626
|
+
await fs.rm(path, { file: true });
|
|
9534
9627
|
return done;
|
|
9535
9628
|
case "rmdir":
|
|
9536
9629
|
if (!(await fs.lstat(path)).isDirectory) throw syncError("ENOTDIR", path);
|
|
@@ -9764,6 +9857,26 @@ async function dispatchSyncFs(req) {
|
|
|
9764
9857
|
return toErrno(err);
|
|
9765
9858
|
}
|
|
9766
9859
|
}
|
|
9860
|
+
var DENIED = /* @__PURE__ */ new Set(["EACCES", "EPERM"]);
|
|
9861
|
+
async function rmPermitted(entry, path, req, refused2) {
|
|
9862
|
+
const st = await entry.fs.lstat(path).catch(() => void 0);
|
|
9863
|
+
if (!st?.isDirectory) return refused2;
|
|
9864
|
+
const unlisted = await guarded(entry, path, { ...req, op: "readdir" });
|
|
9865
|
+
if (unlisted) return unlisted;
|
|
9866
|
+
const names = await entry.fs.readdir(path).catch(() => void 0);
|
|
9867
|
+
if (!names) return refused2;
|
|
9868
|
+
let first;
|
|
9869
|
+
for (const name2 of names) {
|
|
9870
|
+
const child = await dispatchOne(entry, {
|
|
9871
|
+
...req,
|
|
9872
|
+
path: joinName(path, name2)
|
|
9873
|
+
});
|
|
9874
|
+
if (!child.ok) first ??= child;
|
|
9875
|
+
}
|
|
9876
|
+
if (first) return first;
|
|
9877
|
+
const again = await guarded(entry, path, req);
|
|
9878
|
+
return again ?? await run(entry, path, req);
|
|
9879
|
+
}
|
|
9767
9880
|
async function dispatchOne(entry, req) {
|
|
9768
9881
|
const { fs, cwd } = entry;
|
|
9769
9882
|
try {
|
|
@@ -9773,6 +9886,9 @@ async function dispatchOne(entry, req) {
|
|
|
9773
9886
|
if (req.op === "access") return await accessOp(entry, path, req);
|
|
9774
9887
|
if (req.op === "hold") return await holdOp(entry, path, req);
|
|
9775
9888
|
const refused2 = await guarded(entry, path, req);
|
|
9889
|
+
if (refused2 && req.op === "rm" && !refused2.ok && DENIED.has(refused2.errno)) {
|
|
9890
|
+
return await rmPermitted(entry, path, req, refused2);
|
|
9891
|
+
}
|
|
9776
9892
|
if (refused2) return refused2;
|
|
9777
9893
|
if (req.op === "statfs") return json2(await usageAt(entry, path) ?? await storageUsage());
|
|
9778
9894
|
if (entry.revoked?.(path)) return { ok: false, errno: "EIO", message: `${path} was unmounted` };
|