@ai-ecoverse/slicc-kernel 1.53.4 → 1.54.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 +7 -1
- package/dist/index.js +76 -2
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +125 -5
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node.js +191 -6
- package/dist/node.js.map +3 -3
- package/package.json +2 -2
package/dist/node.js
CHANGED
|
@@ -11156,7 +11156,7 @@ function hostfsHandlers(current) {
|
|
|
11156
11156
|
const handles = /* @__PURE__ */ new Map();
|
|
11157
11157
|
let nextFh = 0;
|
|
11158
11158
|
const fresh = (remote) => {
|
|
11159
|
-
if (remote.client.token === remote.token) return remote;
|
|
11159
|
+
if (remote.client.token === remote.token && !remote.client.gone) return remote;
|
|
11160
11160
|
throw fsError2("ESTALE", "the folder was granted again, so this open file is gone");
|
|
11161
11161
|
};
|
|
11162
11162
|
const live = (fh) => {
|
|
@@ -11361,10 +11361,190 @@ function keepWatching(loop, signal) {
|
|
|
11361
11361
|
function invalidation(event) {
|
|
11362
11362
|
return event.paths ?? true;
|
|
11363
11363
|
}
|
|
11364
|
-
|
|
11364
|
+
var PORT_REQUEST_MS = 6e4;
|
|
11365
|
+
var PORT_MS_PER_MIB = 1e3;
|
|
11366
|
+
var nextPortToken = 0;
|
|
11367
|
+
var PortTransport = class {
|
|
11368
|
+
capabilities;
|
|
11369
|
+
token;
|
|
11370
|
+
port;
|
|
11371
|
+
requestMs;
|
|
11372
|
+
waiting = /* @__PURE__ */ new Map();
|
|
11373
|
+
next = 0;
|
|
11374
|
+
dead;
|
|
11375
|
+
constructor(grant, requestMs = PORT_REQUEST_MS) {
|
|
11376
|
+
this.port = grant.port;
|
|
11377
|
+
this.requestMs = requestMs;
|
|
11378
|
+
this.capabilities = grant.capabilities ?? {};
|
|
11379
|
+
this.token = grant.token ?? `port-${++nextPortToken}`;
|
|
11380
|
+
this.port.addEventListener("message", (event) => {
|
|
11381
|
+
this.waiting.get(event.data?.id)?.(event.data);
|
|
11382
|
+
});
|
|
11383
|
+
this.port.addEventListener("close", () => this.fail("the folder's port closed"));
|
|
11384
|
+
this.port.start();
|
|
11385
|
+
}
|
|
11386
|
+
get maxIo() {
|
|
11387
|
+
return this.capabilities.maxIo ?? HOSTFS_IO;
|
|
11388
|
+
}
|
|
11389
|
+
get gone() {
|
|
11390
|
+
return this.dead !== void 0;
|
|
11391
|
+
}
|
|
11392
|
+
fail(why) {
|
|
11393
|
+
if (this.dead === void 0) this.port.close();
|
|
11394
|
+
this.dead ??= why;
|
|
11395
|
+
for (const settle of [...this.waiting.values()])
|
|
11396
|
+
settle({ id: 0, error: { code: "ENOTCONN", message: why } });
|
|
11397
|
+
}
|
|
11398
|
+
ask(message3, bytes = 0, transfer = []) {
|
|
11399
|
+
const id2 = ++this.next;
|
|
11400
|
+
if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
|
|
11401
|
+
return new Promise((resolve, reject) => {
|
|
11402
|
+
const timer = setTimeout(
|
|
11403
|
+
() => {
|
|
11404
|
+
this.waiting.delete(id2);
|
|
11405
|
+
reject(fsError2("ETIMEDOUT", "the folder's port did not answer"));
|
|
11406
|
+
this.fail("the folder's port stopped answering");
|
|
11407
|
+
},
|
|
11408
|
+
this.requestMs + Math.ceil(bytes / 1048576) * PORT_MS_PER_MIB
|
|
11409
|
+
);
|
|
11410
|
+
this.waiting.set(id2, (reply) => {
|
|
11411
|
+
clearTimeout(timer);
|
|
11412
|
+
this.waiting.delete(id2);
|
|
11413
|
+
if (reply.error) reject(fsError2(reply.error.code ?? "EIO", reply.error.message ?? ""));
|
|
11414
|
+
else resolve(reply);
|
|
11415
|
+
});
|
|
11416
|
+
try {
|
|
11417
|
+
this.port.postMessage({ id: id2, ...message3 }, transfer);
|
|
11418
|
+
} catch (err) {
|
|
11419
|
+
this.fail(`the folder's port is closed: ${err.message}`);
|
|
11420
|
+
}
|
|
11421
|
+
});
|
|
11422
|
+
}
|
|
11423
|
+
async call(op, body = {}) {
|
|
11424
|
+
return (await this.ask({ op: "call", name: op, body })).result;
|
|
11425
|
+
}
|
|
11426
|
+
async read(fh, offset, size, ifMatch) {
|
|
11427
|
+
const reply = await this.ask(
|
|
11428
|
+
{ op: "read", fh, offset, size, ...ifMatch ? { ifMatch } : {} },
|
|
11429
|
+
size
|
|
11430
|
+
);
|
|
11431
|
+
return reply.bytes ?? new Uint8Array(0);
|
|
11432
|
+
}
|
|
11433
|
+
async write(fh, offset, bytes) {
|
|
11434
|
+
await this.ask({ op: "write", fh, offset, bytes }, bytes.length);
|
|
11435
|
+
}
|
|
11436
|
+
watch(signal, onEvent, onOpen = () => void 0) {
|
|
11437
|
+
const id2 = ++this.next;
|
|
11438
|
+
if (this.dead) return Promise.reject(fsError2("ENOTCONN", this.dead));
|
|
11439
|
+
if (signal.aborted) {
|
|
11440
|
+
this.fail("the folder's watch ended");
|
|
11441
|
+
return Promise.resolve();
|
|
11442
|
+
}
|
|
11443
|
+
return new Promise((resolve, reject) => {
|
|
11444
|
+
const finish = () => {
|
|
11445
|
+
this.waiting.delete(id2);
|
|
11446
|
+
signal.removeEventListener("abort", stop);
|
|
11447
|
+
};
|
|
11448
|
+
const stop = () => {
|
|
11449
|
+
finish();
|
|
11450
|
+
try {
|
|
11451
|
+
this.port.postMessage({ id: id2, op: "unwatch" });
|
|
11452
|
+
} catch {
|
|
11453
|
+
}
|
|
11454
|
+
resolve();
|
|
11455
|
+
};
|
|
11456
|
+
this.waiting.set(id2, (reply) => {
|
|
11457
|
+
if (reply.open) return onOpen();
|
|
11458
|
+
if (reply.event) return onEvent(reply.event);
|
|
11459
|
+
finish();
|
|
11460
|
+
if (reply.error) reject(fsError2(reply.error.code ?? "ENOTCONN", reply.error.message ?? ""));
|
|
11461
|
+
else resolve();
|
|
11462
|
+
});
|
|
11463
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
11464
|
+
try {
|
|
11465
|
+
this.port.postMessage({ id: id2, op: "watch" });
|
|
11466
|
+
} catch (err) {
|
|
11467
|
+
finish();
|
|
11468
|
+
reject(fsError2("ENOTCONN", `the folder's port is closed: ${err.message}`));
|
|
11469
|
+
}
|
|
11470
|
+
}).finally(() => this.fail("the folder's watch ended"));
|
|
11471
|
+
}
|
|
11472
|
+
};
|
|
11473
|
+
var errorOf = (err) => ({
|
|
11474
|
+
code: typeof codeOf4(err) === "string" ? codeOf4(err) : "EIO",
|
|
11475
|
+
message: err?.message ?? String(err)
|
|
11476
|
+
});
|
|
11477
|
+
function serveHostfsPort(port, transport) {
|
|
11478
|
+
const watches = /* @__PURE__ */ new Map();
|
|
11479
|
+
const send = (reply, transfer = []) => port.postMessage(reply, transfer);
|
|
11480
|
+
const listener = async ({
|
|
11481
|
+
data
|
|
11482
|
+
}) => {
|
|
11483
|
+
const { id: id2, op } = data;
|
|
11484
|
+
if (op === "unwatch") return watches.get(id2)?.abort();
|
|
11485
|
+
if (op === "watch") {
|
|
11486
|
+
const stop2 = new AbortController();
|
|
11487
|
+
watches.set(id2, stop2);
|
|
11488
|
+
try {
|
|
11489
|
+
await transport.watch(
|
|
11490
|
+
stop2.signal,
|
|
11491
|
+
(event) => send({ id: id2, event }),
|
|
11492
|
+
() => send({ id: id2, open: true })
|
|
11493
|
+
);
|
|
11494
|
+
send({ id: id2, end: true });
|
|
11495
|
+
} catch (err) {
|
|
11496
|
+
send({ id: id2, error: errorOf(err) });
|
|
11497
|
+
} finally {
|
|
11498
|
+
watches.delete(id2);
|
|
11499
|
+
}
|
|
11500
|
+
return;
|
|
11501
|
+
}
|
|
11502
|
+
try {
|
|
11503
|
+
if (op === "read") {
|
|
11504
|
+
const read = await transport.read(
|
|
11505
|
+
data.fh,
|
|
11506
|
+
data.offset,
|
|
11507
|
+
data.size,
|
|
11508
|
+
data.ifMatch
|
|
11509
|
+
);
|
|
11510
|
+
const bytes = read.slice();
|
|
11511
|
+
return send({ id: id2, bytes }, [bytes.buffer]);
|
|
11512
|
+
}
|
|
11513
|
+
if (op === "write") {
|
|
11514
|
+
await transport.write(data.fh, data.offset, data.bytes);
|
|
11515
|
+
return send({ id: id2 });
|
|
11516
|
+
}
|
|
11517
|
+
if (op !== "call") throw fsError2("EINVAL", `unknown hostfs port op ${op}`);
|
|
11518
|
+
send({
|
|
11519
|
+
id: id2,
|
|
11520
|
+
result: await transport.call(data.name, data.body)
|
|
11521
|
+
});
|
|
11522
|
+
} catch (err) {
|
|
11523
|
+
send({ id: id2, error: errorOf(err) });
|
|
11524
|
+
}
|
|
11525
|
+
};
|
|
11526
|
+
const stop = () => {
|
|
11527
|
+
port.removeEventListener("message", listener);
|
|
11528
|
+
port.removeEventListener("close", stop);
|
|
11529
|
+
for (const watch of watches.values()) watch.abort();
|
|
11530
|
+
port.close();
|
|
11531
|
+
};
|
|
11532
|
+
port.addEventListener("message", listener);
|
|
11533
|
+
port.addEventListener("close", stop);
|
|
11534
|
+
port.start();
|
|
11535
|
+
return stop;
|
|
11536
|
+
}
|
|
11537
|
+
function grantConnect(hook, fetch2, requestMs) {
|
|
11365
11538
|
return async (source, options) => {
|
|
11366
|
-
const
|
|
11367
|
-
return new
|
|
11539
|
+
const first = await hook(source, options);
|
|
11540
|
+
if ("port" in first) return new PortTransport(first, requestMs);
|
|
11541
|
+
const grant = async () => {
|
|
11542
|
+
const again = await hook(source, options);
|
|
11543
|
+
if ("port" in again)
|
|
11544
|
+
throw fsError2("ESTALE", "the folder moved to a port, so its open files are gone");
|
|
11545
|
+
return again;
|
|
11546
|
+
};
|
|
11547
|
+
return new HostfsClient(first, grant, fetch2);
|
|
11368
11548
|
};
|
|
11369
11549
|
}
|
|
11370
11550
|
async function openHostfs(spec, connect, timing = {}) {
|
|
@@ -12419,7 +12599,11 @@ var Launcher = class {
|
|
|
12419
12599
|
throw fsError("ENODEV", "this kernel has no hostfs hook (createKernel({ hostfs }))");
|
|
12420
12600
|
return openHostfs(
|
|
12421
12601
|
spec,
|
|
12422
|
-
grantConnect(
|
|
12602
|
+
grantConnect(
|
|
12603
|
+
hostfs,
|
|
12604
|
+
hostfsFetch ?? ((url, init) => fetch(url, init)),
|
|
12605
|
+
hostfsTiming?.requestMs
|
|
12606
|
+
),
|
|
12423
12607
|
hostfsTiming
|
|
12424
12608
|
);
|
|
12425
12609
|
}
|
|
@@ -13876,6 +14060,7 @@ export {
|
|
|
13876
14060
|
createNodeKernel,
|
|
13877
14061
|
fetchTransport,
|
|
13878
14062
|
memoryRoot,
|
|
13879
|
-
nodeTransport
|
|
14063
|
+
nodeTransport,
|
|
14064
|
+
serveHostfsPort
|
|
13880
14065
|
};
|
|
13881
14066
|
//# sourceMappingURL=node.js.map
|