@ai-ecoverse/slicc-kernel 1.171.0 → 1.172.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/README.md +25 -8
- package/dist/driver-worker.js +4 -2
- package/dist/driver-worker.js.map +2 -2
- package/dist/index.js +260 -42
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +602 -230
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +4 -2
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +462 -233
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/testing.js +498 -3
- package/dist/testing.js.map +4 -4
- package/dist/types/fs/attest.d.ts +12 -2
- package/dist/types/fs/portable.d.ts +11 -0
- package/dist/types/fs/roots.d.ts +1 -1
- package/dist/types/index.d.ts +12 -4
- package/dist/types/kernel/net/http-syscalls.d.ts +3 -1
- package/dist/types/kernel/net/loopback-transport.d.ts +1 -1
- package/dist/types/kernel/net/placeholder-floor.d.ts +9 -3
- package/dist/types/kernel/net/remote-transport.d.ts +4 -1
- package/dist/types/kernel/net/sealed-fetch.d.ts +27 -0
- package/dist/types/kernel/net/transport.d.ts +2 -1
- package/dist/types/kernel/socket.d.ts +4 -1
- package/dist/types/launcher.d.ts +12 -2
- package/dist/types/mount/media.d.ts +3 -1
- package/dist/types/node.d.ts +12 -4
- package/dist/types/sealed-relay.d.ts +12 -2
- package/dist/types/serve.d.ts +14 -5
- package/dist/types/testing.d.ts +3 -0
- package/dist/types/transport.d.ts +2 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -546,6 +546,32 @@ function integrityUnknown(options) {
|
|
|
546
546
|
return unknown;
|
|
547
547
|
}
|
|
548
548
|
|
|
549
|
+
// src/fs/portable.ts
|
|
550
|
+
var privateTop = () => navigator.storage.getDirectory();
|
|
551
|
+
function clonable(handle) {
|
|
552
|
+
const { port1, port2 } = new MessageChannel();
|
|
553
|
+
try {
|
|
554
|
+
port1.postMessage(handle);
|
|
555
|
+
return true;
|
|
556
|
+
} catch (err) {
|
|
557
|
+
if (err?.name === "DataCloneError") return false;
|
|
558
|
+
throw err;
|
|
559
|
+
} finally {
|
|
560
|
+
port1.close();
|
|
561
|
+
port2.close();
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
async function portable(handle, top = privateTop) {
|
|
565
|
+
if (clonable(handle)) return { handle };
|
|
566
|
+
const path = await (await top()).resolve(handle);
|
|
567
|
+
if (path === null) {
|
|
568
|
+
throw new Error(
|
|
569
|
+
"this browser cannot hand a folder to a worker unless it is in the origin private file system"
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
return { path };
|
|
573
|
+
}
|
|
574
|
+
|
|
549
575
|
// src/integrity-relay.ts
|
|
550
576
|
function integrityAnswerer(port, lookup) {
|
|
551
577
|
const ask = async ({ id, path }) => {
|
|
@@ -598,6 +624,54 @@ function isHostname(name) {
|
|
|
598
624
|
return name.split(".").every((l) => LABEL.test(l));
|
|
599
625
|
}
|
|
600
626
|
|
|
627
|
+
// src/body-idle.ts
|
|
628
|
+
var BODY_IDLE_MS = 5 * 60 * 1e3;
|
|
629
|
+
function idleFailure(ms) {
|
|
630
|
+
return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
|
|
631
|
+
code: "ETIMEDOUT"
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
async function readWithin(reader, ms) {
|
|
635
|
+
if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
|
|
636
|
+
let timer;
|
|
637
|
+
const idle = new Promise((_, reject) => {
|
|
638
|
+
timer = setTimeout(() => reject(idleFailure(ms)), ms);
|
|
639
|
+
});
|
|
640
|
+
try {
|
|
641
|
+
return await Promise.race([reader.read(), idle]);
|
|
642
|
+
} finally {
|
|
643
|
+
clearTimeout(timer);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/kernel/net/sealed-fetch.ts
|
|
648
|
+
var SEALED_FETCH_VERSION = 1;
|
|
649
|
+
var UNSAFE_FIELD = /[\r\n\0]/;
|
|
650
|
+
function sealedHooks(option) {
|
|
651
|
+
if (!option) return {};
|
|
652
|
+
if (typeof option === "function") return { request: option };
|
|
653
|
+
const { request, fetch } = option;
|
|
654
|
+
if (typeof request !== "function" || fetch !== void 0 && typeof fetch !== "function") {
|
|
655
|
+
throw new TypeError("sealed takes a function or { request, fetch? }");
|
|
656
|
+
}
|
|
657
|
+
return { request, ...fetch ? { fetch } : {} };
|
|
658
|
+
}
|
|
659
|
+
function headerList(headers) {
|
|
660
|
+
return Array.isArray(headers) && headers.every(
|
|
661
|
+
(field) => Array.isArray(field) && field.length === 2 && field.every((text) => typeof text === "string" && !UNSAFE_FIELD.test(text))
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
function sealedReplyValid(reply) {
|
|
665
|
+
if (typeof reply !== "object" || reply === null) return false;
|
|
666
|
+
const { redirects, redirected, status, statusText, headers, url, body, cancel } = reply;
|
|
667
|
+
return redirects === void 0 && redirected !== true && Number.isInteger(status) && status >= 100 && status <= 599 && typeof statusText === "string" && !UNSAFE_FIELD.test(statusText) && headerList(headers) && (url === void 0 || typeof url === "string") && typeof body?.[Symbol.asyncIterator] === "function" && typeof cancel === "function";
|
|
668
|
+
}
|
|
669
|
+
function dropSealedReply(reply) {
|
|
670
|
+
const { cancel } = reply ?? {};
|
|
671
|
+
if (typeof cancel !== "function") return;
|
|
672
|
+
void Promise.resolve().then(() => cancel.call(reply)).catch(() => void 0);
|
|
673
|
+
}
|
|
674
|
+
|
|
601
675
|
// src/kernel/net/routes.ts
|
|
602
676
|
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
603
677
|
function ipv4Bytes(text) {
|
|
@@ -917,8 +991,129 @@ var KERNEL_SIGINFO = Object.freeze({
|
|
|
917
991
|
});
|
|
918
992
|
|
|
919
993
|
// src/sealed-relay.ts
|
|
920
|
-
function
|
|
994
|
+
function textOf(err) {
|
|
995
|
+
return err instanceof Error ? err.message : String(err);
|
|
996
|
+
}
|
|
997
|
+
function sendBytes(port, bytes) {
|
|
998
|
+
const copy = fresh(bytes);
|
|
999
|
+
port.postMessage({ t: "chunk", bytes: copy }, [copy.buffer]);
|
|
1000
|
+
}
|
|
1001
|
+
function uploadOf(far) {
|
|
1002
|
+
let waiting;
|
|
1003
|
+
let failure2;
|
|
1004
|
+
const next = () => {
|
|
1005
|
+
if (failure2) return Promise.reject(failure2);
|
|
1006
|
+
waiting = Promise.withResolvers();
|
|
1007
|
+
far.postMessage({ t: "pull" });
|
|
1008
|
+
return waiting.promise;
|
|
1009
|
+
};
|
|
1010
|
+
return {
|
|
1011
|
+
stream: {
|
|
1012
|
+
[Symbol.asyncIterator]: () => ({
|
|
1013
|
+
next,
|
|
1014
|
+
return: async () => {
|
|
1015
|
+
far.postMessage({ t: "stop" });
|
|
1016
|
+
return { value: void 0, done: true };
|
|
1017
|
+
}
|
|
1018
|
+
})
|
|
1019
|
+
},
|
|
1020
|
+
answer(message) {
|
|
1021
|
+
if (message.t === "chunk") waiting?.resolve({ value: message.bytes, done: false });
|
|
1022
|
+
else if (message.t === "end") waiting?.resolve({ value: void 0, done: true });
|
|
1023
|
+
else {
|
|
1024
|
+
failure2 = new Error(message.message);
|
|
1025
|
+
waiting?.reject(failure2);
|
|
1026
|
+
}
|
|
1027
|
+
waiting = void 0;
|
|
1028
|
+
},
|
|
1029
|
+
fail(reason) {
|
|
1030
|
+
failure2 = reason;
|
|
1031
|
+
waiting?.reject(reason);
|
|
1032
|
+
waiting = void 0;
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
function answerFetch(hook, { req, port: far }, live) {
|
|
1037
|
+
const control = new AbortController();
|
|
1038
|
+
const { streamed, ...fields } = req;
|
|
1039
|
+
const upload = uploadOf(far);
|
|
1040
|
+
let source;
|
|
1041
|
+
let reply;
|
|
1042
|
+
let closed = false;
|
|
1043
|
+
const settle = () => {
|
|
1044
|
+
closed = true;
|
|
1045
|
+
live.delete(answer);
|
|
1046
|
+
upload.fail(new Error("the request ended"));
|
|
1047
|
+
};
|
|
1048
|
+
const answer = {
|
|
1049
|
+
close(reason) {
|
|
1050
|
+
if (closed) return;
|
|
1051
|
+
settle();
|
|
1052
|
+
control.abort(reason);
|
|
1053
|
+
dropSealedReply(reply);
|
|
1054
|
+
far.close();
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
const finish = (message) => {
|
|
1058
|
+
if (closed) return;
|
|
1059
|
+
settle();
|
|
1060
|
+
far.postMessage(message);
|
|
1061
|
+
};
|
|
1062
|
+
const failWith = (err) => {
|
|
1063
|
+
dropSealedReply(reply);
|
|
1064
|
+
finish({ t: "error", message: textOf(err) });
|
|
1065
|
+
};
|
|
1066
|
+
const read = async () => {
|
|
1067
|
+
try {
|
|
1068
|
+
const next = await source.next();
|
|
1069
|
+
if (closed) return;
|
|
1070
|
+
if (next.done) finish({ t: "end" });
|
|
1071
|
+
else if (next.value instanceof Uint8Array) sendBytes(far, next.value);
|
|
1072
|
+
else failWith("a body chunk is not bytes");
|
|
1073
|
+
} catch (err) {
|
|
1074
|
+
failWith(err);
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
const ask = async () => {
|
|
1078
|
+
try {
|
|
1079
|
+
if (!hook) throw new Error("no vault is connected");
|
|
1080
|
+
const request = {
|
|
1081
|
+
...fields,
|
|
1082
|
+
...streamed ? { bodyStream: upload.stream } : {}
|
|
1083
|
+
};
|
|
1084
|
+
const answered = await hook(request, { signal: control.signal });
|
|
1085
|
+
if (!sealedReplyValid(answered)) {
|
|
1086
|
+
dropSealedReply(answered);
|
|
1087
|
+
throw new Error("the reply is not a scrubbed response");
|
|
1088
|
+
}
|
|
1089
|
+
if (closed) return dropSealedReply(answered);
|
|
1090
|
+
reply = answered;
|
|
1091
|
+
source = answered.body[Symbol.asyncIterator]();
|
|
1092
|
+
const { status, statusText, headers, url } = answered;
|
|
1093
|
+
far.postMessage({
|
|
1094
|
+
t: "head",
|
|
1095
|
+
status,
|
|
1096
|
+
statusText,
|
|
1097
|
+
headers,
|
|
1098
|
+
...url !== void 0 ? { url } : {}
|
|
1099
|
+
});
|
|
1100
|
+
} catch (err) {
|
|
1101
|
+
failWith(err);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
far.addEventListener("message", ({ data }) => {
|
|
1105
|
+
if (data.t === "read") void read();
|
|
1106
|
+
else if (data.t === "cancel") answer.close(data.reason);
|
|
1107
|
+
else upload.answer(data);
|
|
1108
|
+
});
|
|
1109
|
+
far.addEventListener("close", () => answer.close("withdrawn"));
|
|
1110
|
+
far.start();
|
|
1111
|
+
live.add(answer);
|
|
1112
|
+
void ask();
|
|
1113
|
+
}
|
|
1114
|
+
function sealedAnswerer(port, hook, fetchHook) {
|
|
921
1115
|
const asked = /* @__PURE__ */ new Map();
|
|
1116
|
+
const fetches = /* @__PURE__ */ new Set();
|
|
922
1117
|
const ask = async ({ id, req }) => {
|
|
923
1118
|
const control = new AbortController();
|
|
924
1119
|
asked.set(id, control);
|
|
@@ -942,36 +1137,18 @@ function sealedAnswerer(port, hook) {
|
|
|
942
1137
|
const message = data;
|
|
943
1138
|
if (message?.sealedAsk) void ask(message.sealedAsk);
|
|
944
1139
|
else if (message?.sealedAbort) abort(message.sealedAbort);
|
|
1140
|
+
else if (message?.sealedFetch) answerFetch(fetchHook, message.sealedFetch, fetches);
|
|
945
1141
|
else return false;
|
|
946
1142
|
return true;
|
|
947
1143
|
},
|
|
948
1144
|
close() {
|
|
949
1145
|
for (const control of asked.values()) control.abort("withdrawn");
|
|
950
1146
|
asked.clear();
|
|
1147
|
+
for (const answer of [...fetches]) answer.close("withdrawn");
|
|
951
1148
|
}
|
|
952
1149
|
};
|
|
953
1150
|
}
|
|
954
1151
|
|
|
955
|
-
// src/body-idle.ts
|
|
956
|
-
var BODY_IDLE_MS = 5 * 60 * 1e3;
|
|
957
|
-
function idleFailure(ms) {
|
|
958
|
-
return Object.assign(new Error(`the response body sent no data for ${ms} ms`), {
|
|
959
|
-
code: "ETIMEDOUT"
|
|
960
|
-
});
|
|
961
|
-
}
|
|
962
|
-
async function readWithin(reader, ms) {
|
|
963
|
-
if (!(ms > 0 && ms < Number.POSITIVE_INFINITY)) return reader.read();
|
|
964
|
-
let timer;
|
|
965
|
-
const idle = new Promise((_, reject) => {
|
|
966
|
-
timer = setTimeout(() => reject(idleFailure(ms)), ms);
|
|
967
|
-
});
|
|
968
|
-
try {
|
|
969
|
-
return await Promise.race([reader.read(), idle]);
|
|
970
|
-
} finally {
|
|
971
|
-
clearTimeout(timer);
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
|
-
|
|
975
1152
|
// src/kernel/net/ws-queue.ts
|
|
976
1153
|
var INBOUND_LIMIT = 16 * 1024 * 1024;
|
|
977
1154
|
var MESSAGE_LIMIT = 64 * 1024 * 1024;
|
|
@@ -1163,6 +1340,11 @@ async function* chunks(body, idleMs) {
|
|
|
1163
1340
|
await reader.cancel().catch(() => void 0);
|
|
1164
1341
|
}
|
|
1165
1342
|
}
|
|
1343
|
+
function sentHeaders(headers, inPage) {
|
|
1344
|
+
const out = joinHeaders(headers);
|
|
1345
|
+
if (inPage) out.delete("user-agent");
|
|
1346
|
+
return out;
|
|
1347
|
+
}
|
|
1166
1348
|
function streamOf(body) {
|
|
1167
1349
|
const it = body[Symbol.asyncIterator]();
|
|
1168
1350
|
return new ReadableStream(
|
|
@@ -1190,6 +1372,7 @@ function fetchTransport(options = {}) {
|
|
|
1190
1372
|
const Socket = options.webSocket === true ? globalThis.WebSocket : options.webSocket || void 0;
|
|
1191
1373
|
const headers = options.webSocketHeaders === true;
|
|
1192
1374
|
const instance = options.redirect ?? "follow";
|
|
1375
|
+
const inPage = !options.fetch && "location" in globalThis;
|
|
1193
1376
|
return {
|
|
1194
1377
|
traits: {
|
|
1195
1378
|
manualRedirects: instance === "manual",
|
|
@@ -1206,7 +1389,7 @@ function fetchTransport(options = {}) {
|
|
|
1206
1389
|
try {
|
|
1207
1390
|
response = await send(request.url, {
|
|
1208
1391
|
method: request.method,
|
|
1209
|
-
headers:
|
|
1392
|
+
headers: sentHeaders(request.headers, inPage),
|
|
1210
1393
|
...requestBody(request),
|
|
1211
1394
|
signal: request.signal,
|
|
1212
1395
|
redirect: request.redirect ?? instance,
|
|
@@ -1282,7 +1465,21 @@ function headOf(nid, response) {
|
|
|
1282
1465
|
headers: response.headers
|
|
1283
1466
|
};
|
|
1284
1467
|
}
|
|
1285
|
-
function
|
|
1468
|
+
function requestOf(call, signal, uploads) {
|
|
1469
|
+
const { url, method, headers, streamed, body, redirect, nid } = call;
|
|
1470
|
+
return {
|
|
1471
|
+
url,
|
|
1472
|
+
method,
|
|
1473
|
+
headers,
|
|
1474
|
+
...streamed ? { bodyStream: uploads.of(nid, signal) } : body ? { body } : {},
|
|
1475
|
+
...redirect !== void 0 ? { redirect } : {},
|
|
1476
|
+
signal
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
function serveTransport(peer, transport, {
|
|
1480
|
+
closeWaitMs = CLOSE_WAIT_MS,
|
|
1481
|
+
attributed = false
|
|
1482
|
+
} = {}) {
|
|
1286
1483
|
const open = /* @__PURE__ */ new Map();
|
|
1287
1484
|
const fail = (nid, e) => {
|
|
1288
1485
|
open.delete(nid);
|
|
@@ -1302,14 +1499,11 @@ function serveTransport(peer, transport, { closeWaitMs = CLOSE_WAIT_MS } = {}) {
|
|
|
1302
1499
|
const entry = { abort };
|
|
1303
1500
|
open.set(call.nid, entry);
|
|
1304
1501
|
try {
|
|
1305
|
-
const response = await transport.fetch(
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
...call.redirect !== void 0 ? { redirect: call.redirect } : {},
|
|
1311
|
-
signal: abort.signal
|
|
1312
|
-
});
|
|
1502
|
+
const response = await transport.fetch(
|
|
1503
|
+
requestOf(call, abort.signal, uploads),
|
|
1504
|
+
attributed ? call.owner : void 0,
|
|
1505
|
+
attributed ? call.stamp : void 0
|
|
1506
|
+
);
|
|
1313
1507
|
if (!open.has(call.nid)) {
|
|
1314
1508
|
await response.cancel();
|
|
1315
1509
|
return;
|
|
@@ -1564,7 +1758,7 @@ var RemoteTransport = class {
|
|
|
1564
1758
|
waiter?.reject(new TransportError("the request was cancelled"));
|
|
1565
1759
|
this.port.postMessage({ net: "cancel", nid });
|
|
1566
1760
|
}
|
|
1567
|
-
async fetch(request) {
|
|
1761
|
+
async fetch(request, owner, stamp) {
|
|
1568
1762
|
const nid = ++this.nextId;
|
|
1569
1763
|
const { signal, redirect } = request;
|
|
1570
1764
|
signal.throwIfAborted();
|
|
@@ -1594,7 +1788,9 @@ var RemoteTransport = class {
|
|
|
1594
1788
|
method: request.method,
|
|
1595
1789
|
headers: request.headers,
|
|
1596
1790
|
...request.bodyStream ? { streamed: true } : request.body ? { body: request.body } : {},
|
|
1597
|
-
...redirect !== void 0 ? { redirect } : {}
|
|
1791
|
+
...redirect !== void 0 ? { redirect } : {},
|
|
1792
|
+
...owner !== void 0 ? { owner } : {},
|
|
1793
|
+
...stamp ? { stamp } : {}
|
|
1598
1794
|
});
|
|
1599
1795
|
} catch (e) {
|
|
1600
1796
|
finish();
|
|
@@ -2278,10 +2474,17 @@ function uplinkInit(uplink) {
|
|
|
2278
2474
|
const nameserver = typeof uplink.nameserver === "string" ? { nameserver: uplink.nameserver } : {};
|
|
2279
2475
|
return { uplink: { traits, ...uplink.routes ? { routes: uplink.routes } : {}, ...nameserver } };
|
|
2280
2476
|
}
|
|
2281
|
-
function
|
|
2477
|
+
function rootField(at) {
|
|
2478
|
+
return "path" in at ? { rootPath: at.path } : { root: at.handle };
|
|
2479
|
+
}
|
|
2480
|
+
async function insertCall(target, handle, source) {
|
|
2481
|
+
return { op: "insert", target, source, ...await portable(handle) };
|
|
2482
|
+
}
|
|
2483
|
+
async function initCall(options, transport) {
|
|
2484
|
+
const hooks = sealedHooks(options.sealed);
|
|
2282
2485
|
return {
|
|
2283
2486
|
op: "init",
|
|
2284
|
-
...options.root ?
|
|
2487
|
+
...options.root ? rootField(await portable(options.root)) : {},
|
|
2285
2488
|
...options.modules ? { modules: options.modules } : {},
|
|
2286
2489
|
...options.commands ? { commands: options.commands } : {},
|
|
2287
2490
|
...options.env ? { env: options.env } : {},
|
|
@@ -2297,7 +2500,8 @@ function initCall(options, transport) {
|
|
|
2297
2500
|
...options.hostname !== void 0 ? { hostname: options.hostname } : {},
|
|
2298
2501
|
users: options.users === void 0 ? DEFAULT_USERS : options.users,
|
|
2299
2502
|
...options.onDenial ? { denials: true } : {},
|
|
2300
|
-
...
|
|
2503
|
+
...hooks.request ? { sealed: true } : {},
|
|
2504
|
+
...hooks.fetch ? { sealedFetch: true } : {},
|
|
2301
2505
|
...options.clipboard ? { clipboard: true } : {},
|
|
2302
2506
|
...options.requests ? { requests: kindsOf(options.requests) } : {},
|
|
2303
2507
|
...options.approve ? { approve: true } : {},
|
|
@@ -2458,6 +2662,7 @@ function checkOptions(options) {
|
|
|
2458
2662
|
if (options.protect) protectInit(options.protect);
|
|
2459
2663
|
integrityOptions(options.protect?.integrity);
|
|
2460
2664
|
facadesInit(options.facades);
|
|
2665
|
+
sealedHooks(options.sealed);
|
|
2461
2666
|
}
|
|
2462
2667
|
function connector(call, bound) {
|
|
2463
2668
|
return async (connectOptions = {}) => {
|
|
@@ -2474,7 +2679,8 @@ function connector(call, bound) {
|
|
|
2474
2679
|
};
|
|
2475
2680
|
}
|
|
2476
2681
|
function hookRelays(worker, options, bound) {
|
|
2477
|
-
const
|
|
2682
|
+
const hooks = sealedHooks(options.sealed);
|
|
2683
|
+
const sealed = sealedAnswerer(worker, hooks.request, hooks.fetch);
|
|
2478
2684
|
const clipboard = clipboardAnswerer(worker, options.clipboard);
|
|
2479
2685
|
const integrity = integrityAnswerer(worker, options.protect?.integrity?.lookup);
|
|
2480
2686
|
const requests = embedderAnswerer(
|
|
@@ -2509,6 +2715,17 @@ function traitsUpdater(transport, call) {
|
|
|
2509
2715
|
return await call({ op: "transport-traits", ...traits }) === true;
|
|
2510
2716
|
};
|
|
2511
2717
|
}
|
|
2718
|
+
function transportBridge(worker, transport) {
|
|
2719
|
+
return transport ? serveTransport(worker, transport, { attributed: true }) : void 0;
|
|
2720
|
+
}
|
|
2721
|
+
function pageOnly(call) {
|
|
2722
|
+
return {
|
|
2723
|
+
sealed: {
|
|
2724
|
+
setPlaceholders: async (list) => void await call({ op: "sealed-placeholders", list })
|
|
2725
|
+
},
|
|
2726
|
+
attest: ((path, options) => call({ op: "attest", path, ...options ? { options } : {} }))
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2512
2729
|
async function createKernel(options = {}) {
|
|
2513
2730
|
checkOptions(options);
|
|
2514
2731
|
const url = options.worker ?? new URL("./kernel-worker.js", import.meta.url);
|
|
@@ -2539,7 +2756,7 @@ async function createKernel(options = {}) {
|
|
|
2539
2756
|
pending.clear();
|
|
2540
2757
|
};
|
|
2541
2758
|
const transport = options.network?.transport;
|
|
2542
|
-
const bridge =
|
|
2759
|
+
const bridge = transportBridge(worker, transport);
|
|
2543
2760
|
const uplinks = uplinkServer(worker, options.network?.uplink);
|
|
2544
2761
|
async function chosen(handle) {
|
|
2545
2762
|
if (handle) {
|
|
@@ -2563,7 +2780,7 @@ async function createKernel(options = {}) {
|
|
|
2563
2780
|
const pendingMedium = ({ target, source, handle }) => options.onMountPending?.({
|
|
2564
2781
|
target,
|
|
2565
2782
|
source,
|
|
2566
|
-
insert: async () => void await call(
|
|
2783
|
+
insert: async () => void await call(await insertCall(target, await chosen(handle), source))
|
|
2567
2784
|
});
|
|
2568
2785
|
const aside = (data) => {
|
|
2569
2786
|
if (files.event(data)) return true;
|
|
@@ -2636,7 +2853,7 @@ async function createKernel(options = {}) {
|
|
|
2636
2853
|
};
|
|
2637
2854
|
}
|
|
2638
2855
|
const { dial } = dials;
|
|
2639
|
-
await call(initCall(options, transport));
|
|
2856
|
+
await call(await initCall(options, transport));
|
|
2640
2857
|
return {
|
|
2641
2858
|
async run(argv, runOptions = {}) {
|
|
2642
2859
|
const { onStdout, onStderr, stdin, ...rest } = runOptions;
|
|
@@ -2662,8 +2879,8 @@ async function createKernel(options = {}) {
|
|
|
2662
2879
|
mount: async (spec) => await call({ op: "mount", spec }),
|
|
2663
2880
|
umount: async (target) => void await call({ op: "umount", target }),
|
|
2664
2881
|
mounts: async () => await call({ op: "mounts" }),
|
|
2665
|
-
insert: async (target, handle) => void await call(
|
|
2666
|
-
|
|
2882
|
+
insert: async (target, handle) => void await call(await insertCall(target, handle)),
|
|
2883
|
+
...pageOnly(call),
|
|
2667
2884
|
watch: files.watch,
|
|
2668
2885
|
terminate() {
|
|
2669
2886
|
fail(new Error("slicc-kernel terminated"));
|
|
@@ -2674,6 +2891,7 @@ async function createKernel(options = {}) {
|
|
|
2674
2891
|
export {
|
|
2675
2892
|
KernelCallError,
|
|
2676
2893
|
KernelGoneError,
|
|
2894
|
+
SEALED_FETCH_VERSION,
|
|
2677
2895
|
attachKernel,
|
|
2678
2896
|
createKernel,
|
|
2679
2897
|
fetchTransport,
|