@ai-ecoverse/slicc-kernel 1.26.6 → 1.27.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 +26 -3
- package/dist/driver-worker.js +1 -1
- package/dist/driver-worker.js.map +1 -1
- package/dist/index.js +66 -12
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +297 -17
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +1 -1
- package/dist/node-driver-worker.js.map +1 -1
- package/dist/node-process-worker.js +82 -19
- package/dist/node-process-worker.js.map +4 -4
- package/dist/node.js +243 -11
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +82 -19
- package/dist/process-worker.js.map +4 -4
- package/dist/testing.js +27 -0
- package/dist/testing.js.map +7 -0
- package/package.json +4 -3
package/dist/kernel-worker.js
CHANGED
|
@@ -883,7 +883,7 @@ function portCdpHook(ask, gone) {
|
|
|
883
883
|
}
|
|
884
884
|
|
|
885
885
|
// src/client/protocol.ts
|
|
886
|
-
var PROTOCOL = [1,
|
|
886
|
+
var PROTOCOL = [1, 6];
|
|
887
887
|
var FS_METHODS = [
|
|
888
888
|
"readFile",
|
|
889
889
|
"writeFile",
|
|
@@ -2086,6 +2086,7 @@ function serveClient(port, host) {
|
|
|
2086
2086
|
|
|
2087
2087
|
// src/kernel/net/loopback-names.ts
|
|
2088
2088
|
var HOST_LOOPBACK = "host.slicc.internal";
|
|
2089
|
+
var HOST_LOOPBACK_ADDRESS = [10, 0, 2, 2];
|
|
2089
2090
|
var PAGE_LOOPBACK = "kernel.localhost";
|
|
2090
2091
|
var PAGE_LOOPBACK_URL = `http://{port}.${PAGE_LOOPBACK}`;
|
|
2091
2092
|
function toHostLoopback(href) {
|
|
@@ -3569,6 +3570,51 @@ var RemoteTransport = class {
|
|
|
3569
3570
|
}
|
|
3570
3571
|
};
|
|
3571
3572
|
|
|
3573
|
+
// src/kernel/net/uplink.ts
|
|
3574
|
+
function answerOf(result) {
|
|
3575
|
+
const answer = Array.isArray(result) ? { addresses: result } : result;
|
|
3576
|
+
const addresses = Array.isArray(answer?.addresses) ? answer.addresses.filter((a) => typeof a === "string") : [];
|
|
3577
|
+
return {
|
|
3578
|
+
addresses,
|
|
3579
|
+
...typeof answer?.ttl === "number" && answer.ttl >= 0 ? { ttl: answer.ttl } : {}
|
|
3580
|
+
};
|
|
3581
|
+
}
|
|
3582
|
+
var RemoteUplink = class {
|
|
3583
|
+
traits;
|
|
3584
|
+
routes;
|
|
3585
|
+
port;
|
|
3586
|
+
waiting = /* @__PURE__ */ new Map();
|
|
3587
|
+
nextId = 0;
|
|
3588
|
+
constructor(port, traits, routes) {
|
|
3589
|
+
this.port = port;
|
|
3590
|
+
this.traits = traits;
|
|
3591
|
+
this.routes = routes;
|
|
3592
|
+
}
|
|
3593
|
+
receive(reply) {
|
|
3594
|
+
const waiter = this.waiting.get(reply.uid);
|
|
3595
|
+
if (!waiter) return;
|
|
3596
|
+
this.waiting.delete(reply.uid);
|
|
3597
|
+
if (reply.uplink === "error") {
|
|
3598
|
+
waiter.reject(Object.assign(new Error(reply.message), { code: reply.code }));
|
|
3599
|
+
} else waiter.resolve(answerOf(reply));
|
|
3600
|
+
}
|
|
3601
|
+
resolve(name2, family, signal) {
|
|
3602
|
+
const uid = ++this.nextId;
|
|
3603
|
+
const waiter = Promise.withResolvers();
|
|
3604
|
+
this.waiting.set(uid, waiter);
|
|
3605
|
+
const abort = () => {
|
|
3606
|
+
this.waiting.delete(uid);
|
|
3607
|
+
this.port.postMessage({ uplink: "cancel", uid });
|
|
3608
|
+
waiter.reject(signal?.reason);
|
|
3609
|
+
};
|
|
3610
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
3611
|
+
const settled = () => signal?.removeEventListener("abort", abort);
|
|
3612
|
+
waiter.promise.then(settled, settled);
|
|
3613
|
+
this.port.postMessage({ uplink: "resolve", uid, name: name2, family });
|
|
3614
|
+
return waiter.promise;
|
|
3615
|
+
}
|
|
3616
|
+
};
|
|
3617
|
+
|
|
3572
3618
|
// src/cdp/types.ts
|
|
3573
3619
|
var CDP_PORT = 9222;
|
|
3574
3620
|
var NO_CDP_HOST = "slicc-kernel: no CDP host is attached (createKernel({ cdp }) or client.serveCdp)";
|
|
@@ -5897,6 +5943,204 @@ var HttpHandles = class {
|
|
|
5897
5943
|
}
|
|
5898
5944
|
};
|
|
5899
5945
|
|
|
5946
|
+
// src/kernel/net/routes.ts
|
|
5947
|
+
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
5948
|
+
function ipv4Bytes(text) {
|
|
5949
|
+
const parts = text.split(".");
|
|
5950
|
+
if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
|
|
5951
|
+
const bytes = parts.map(Number);
|
|
5952
|
+
return bytes.every((b) => b <= 255) ? bytes : void 0;
|
|
5953
|
+
}
|
|
5954
|
+
function ipv6Groups(text) {
|
|
5955
|
+
if (!text.includes(":")) return void 0;
|
|
5956
|
+
let canonical;
|
|
5957
|
+
try {
|
|
5958
|
+
canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
|
|
5959
|
+
} catch {
|
|
5960
|
+
return void 0;
|
|
5961
|
+
}
|
|
5962
|
+
const [head, tail] = canonical.split("::");
|
|
5963
|
+
const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
|
|
5964
|
+
const front = part(head);
|
|
5965
|
+
const back = part(tail);
|
|
5966
|
+
return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
|
|
5967
|
+
}
|
|
5968
|
+
function toBits(values, width) {
|
|
5969
|
+
return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
|
|
5970
|
+
}
|
|
5971
|
+
function addressBits(host) {
|
|
5972
|
+
const v4 = ipv4Bytes(host);
|
|
5973
|
+
if (v4) return { v6: false, bits: toBits(v4, 8) };
|
|
5974
|
+
const v6 = ipv6Groups(host);
|
|
5975
|
+
return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
|
|
5976
|
+
}
|
|
5977
|
+
function parsePrefix(text) {
|
|
5978
|
+
const parts = text.trim().split("/");
|
|
5979
|
+
if (parts.length > 2) return void 0;
|
|
5980
|
+
const [address = "", size] = parts;
|
|
5981
|
+
const parsed = addressBits(address);
|
|
5982
|
+
if (!parsed) return void 0;
|
|
5983
|
+
const max = parsed.v6 ? 128 : 32;
|
|
5984
|
+
const length2 = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
|
|
5985
|
+
if (length2 < 0 || length2 > max) return void 0;
|
|
5986
|
+
return { ...parsed, length: length2 };
|
|
5987
|
+
}
|
|
5988
|
+
function within3(prefix, addr) {
|
|
5989
|
+
if (prefix.v6 !== addr.v6) return false;
|
|
5990
|
+
const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);
|
|
5991
|
+
return addr.bits >> shift === prefix.bits >> shift;
|
|
5992
|
+
}
|
|
5993
|
+
var RESERVED = [
|
|
5994
|
+
"0.0.0.0/8",
|
|
5995
|
+
"127.0.0.0/8",
|
|
5996
|
+
"169.254.0.0/16",
|
|
5997
|
+
"224.0.0.0/4",
|
|
5998
|
+
"240.0.0.0/4",
|
|
5999
|
+
"::/96",
|
|
6000
|
+
"::ffff:0:0/96",
|
|
6001
|
+
"fe80::/10",
|
|
6002
|
+
"ff00::/8"
|
|
6003
|
+
].map((p) => parsePrefix(p));
|
|
6004
|
+
var Routes = class {
|
|
6005
|
+
table = [];
|
|
6006
|
+
exit = false;
|
|
6007
|
+
ipv6;
|
|
6008
|
+
constructor(ipv62 = false) {
|
|
6009
|
+
this.ipv6 = ipv62;
|
|
6010
|
+
}
|
|
6011
|
+
set(table) {
|
|
6012
|
+
const parsed = (table.prefixes ?? []).map(parsePrefix);
|
|
6013
|
+
const bad = (table.prefixes ?? []).find((_, i) => !parsed[i]);
|
|
6014
|
+
if (bad !== void 0) throw new Error(`not an address prefix: ${bad}`);
|
|
6015
|
+
this.table = parsed;
|
|
6016
|
+
this.exit = table.exit === true;
|
|
6017
|
+
}
|
|
6018
|
+
classify(host) {
|
|
6019
|
+
const name2 = host.toLowerCase().replace(/\.$/, "");
|
|
6020
|
+
if (name2 === "localhost" || name2.endsWith(".localhost") || name2 === "0.0.0.0") {
|
|
6021
|
+
return "loopback";
|
|
6022
|
+
}
|
|
6023
|
+
if (name2 === HOST_LOOPBACK || name2 === HOST_ADDRESS) return "host";
|
|
6024
|
+
const addr = addressBits(name2);
|
|
6025
|
+
if (!addr) return "unreachable";
|
|
6026
|
+
if (addr.v6 && addr.bits === 1n) return "loopback";
|
|
6027
|
+
if (!addr.v6 && addr.bits >> 24n === 127n) return "loopback";
|
|
6028
|
+
if (RESERVED.some((p) => within3(p, addr))) return "reserved";
|
|
6029
|
+
if (addr.v6 && !this.ipv6) return "unreachable";
|
|
6030
|
+
if (this.exit || this.table.some((p) => within3(p, addr))) return "uplink";
|
|
6031
|
+
return "unreachable";
|
|
6032
|
+
}
|
|
6033
|
+
};
|
|
6034
|
+
|
|
6035
|
+
// src/kernel/net/resolver.ts
|
|
6036
|
+
var RESOLVE_TTL_MAX = 60;
|
|
6037
|
+
var RESOLVE_TIMEOUT_MS = 1e4;
|
|
6038
|
+
var RESOLVE_CACHE_MAX = 256;
|
|
6039
|
+
var LOOPBACK_NAMES2 = /* @__PURE__ */ new Set(["localhost", "localhost.localdomain", "ip6-localhost", "::1"]);
|
|
6040
|
+
function hostsEntry(name2) {
|
|
6041
|
+
if (LOOPBACK_NAMES2.has(name2) || name2.endsWith(".localhost")) return "127.0.0.1";
|
|
6042
|
+
if (name2 === HOST_LOOPBACK) return HOST_LOOPBACK_ADDRESS.join(".");
|
|
6043
|
+
return ipv4Bytes(name2) ? name2 : void 0;
|
|
6044
|
+
}
|
|
6045
|
+
var Resolver = class {
|
|
6046
|
+
uplink;
|
|
6047
|
+
routes;
|
|
6048
|
+
now;
|
|
6049
|
+
timeoutMs;
|
|
6050
|
+
log;
|
|
6051
|
+
cache = /* @__PURE__ */ new Map();
|
|
6052
|
+
pending = /* @__PURE__ */ new Map();
|
|
6053
|
+
constructor(options) {
|
|
6054
|
+
this.uplink = options.uplink;
|
|
6055
|
+
this.routes = options.routes;
|
|
6056
|
+
this.now = options.now ?? Date.now;
|
|
6057
|
+
this.timeoutMs = options.timeoutMs ?? RESOLVE_TIMEOUT_MS;
|
|
6058
|
+
this.log = options.log ?? ((message2) => console.warn(message2));
|
|
6059
|
+
}
|
|
6060
|
+
async resolve(name2, family, blocking) {
|
|
6061
|
+
const key = name2.toLowerCase().replace(/\.$/, "");
|
|
6062
|
+
const local = hostsEntry(key);
|
|
6063
|
+
if (ipv6Groups(key)) {
|
|
6064
|
+
const v4 = family !== 6 && local ? [local] : [];
|
|
6065
|
+
return family === 4 ? v4 : [...v4, key];
|
|
6066
|
+
}
|
|
6067
|
+
if (local) {
|
|
6068
|
+
const six = LOOPBACK_NAMES2.has(key) || key.endsWith(".localhost") ? ["::1"] : [];
|
|
6069
|
+
return family === 6 ? six : family === 4 ? [local] : [local, ...six];
|
|
6070
|
+
}
|
|
6071
|
+
if (!this.uplink || key === "") return [];
|
|
6072
|
+
const asked = this.uplink.traits.ipv6 ? family : 4;
|
|
6073
|
+
if (family === 6 && asked !== 6) return [];
|
|
6074
|
+
const id = `${asked}:${key}`;
|
|
6075
|
+
const hit = this.cache.get(id);
|
|
6076
|
+
if (hit && hit.expires > this.now()) return hit.addresses;
|
|
6077
|
+
const signal = blocking?.();
|
|
6078
|
+
if (signal?.aborted) throw new KernelError("EINTR");
|
|
6079
|
+
let lookup = this.pending.get(id);
|
|
6080
|
+
if (!lookup) {
|
|
6081
|
+
const abort = new AbortController();
|
|
6082
|
+
lookup = { work: this.lookup(key, asked, id, abort.signal), abort, waiters: 0 };
|
|
6083
|
+
this.pending.set(id, lookup);
|
|
6084
|
+
void lookup.work.then(() => this.pending.delete(id));
|
|
6085
|
+
}
|
|
6086
|
+
return waitFor(lookup, signal);
|
|
6087
|
+
}
|
|
6088
|
+
async lookup(name2, family, id, abandoned) {
|
|
6089
|
+
const uplink = this.uplink;
|
|
6090
|
+
const timeout = AbortSignal.any([AbortSignal.timeout(this.timeoutMs), abandoned]);
|
|
6091
|
+
let answer;
|
|
6092
|
+
try {
|
|
6093
|
+
answer = answerOf(
|
|
6094
|
+
await Promise.race([
|
|
6095
|
+
uplink.resolve(name2, family, timeout),
|
|
6096
|
+
new Promise(
|
|
6097
|
+
(_, reject) => timeout.addEventListener("abort", () => reject(timeout.reason), { once: true })
|
|
6098
|
+
)
|
|
6099
|
+
])
|
|
6100
|
+
);
|
|
6101
|
+
} catch {
|
|
6102
|
+
return [];
|
|
6103
|
+
}
|
|
6104
|
+
const addresses = answer.addresses.filter((a) => this.usable(name2, a, family));
|
|
6105
|
+
if (addresses.length > 0) this.remember(id, addresses, answer.ttl);
|
|
6106
|
+
return addresses;
|
|
6107
|
+
}
|
|
6108
|
+
usable(name2, address, family) {
|
|
6109
|
+
const v4 = ipv4Bytes(address) !== void 0;
|
|
6110
|
+
if (!v4 && (family === 4 || !ipv6Groups(address))) return false;
|
|
6111
|
+
if (v4 && family === 6) return false;
|
|
6112
|
+
const kind = this.routes.classify(address);
|
|
6113
|
+
if (kind !== "loopback" && kind !== "host" && kind !== "reserved") return true;
|
|
6114
|
+
this.log(`slicc-kernel: dropped the uplink's answer ${address} for ${name2}: it is ${kind}`);
|
|
6115
|
+
return false;
|
|
6116
|
+
}
|
|
6117
|
+
remember(id, addresses, ttl) {
|
|
6118
|
+
const seconds = Math.min(ttl ?? RESOLVE_TTL_MAX, RESOLVE_TTL_MAX);
|
|
6119
|
+
if (seconds <= 0) return;
|
|
6120
|
+
this.cache.delete(id);
|
|
6121
|
+
this.cache.set(id, { addresses, expires: this.now() + seconds * 1e3 });
|
|
6122
|
+
if (this.cache.size > RESOLVE_CACHE_MAX) {
|
|
6123
|
+
this.cache.delete(this.cache.keys().next().value);
|
|
6124
|
+
}
|
|
6125
|
+
}
|
|
6126
|
+
};
|
|
6127
|
+
function waitFor(lookup, signal) {
|
|
6128
|
+
lookup.waiters++;
|
|
6129
|
+
return new Promise((resolve, reject) => {
|
|
6130
|
+
const abort = () => {
|
|
6131
|
+
if (--lookup.waiters === 0) lookup.abort.abort(new KernelError("EINTR"));
|
|
6132
|
+
reject(new KernelError("EINTR"));
|
|
6133
|
+
};
|
|
6134
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
6135
|
+
void lookup.work.then((value) => {
|
|
6136
|
+
if (signal?.aborted) return;
|
|
6137
|
+
lookup.waiters--;
|
|
6138
|
+
signal?.removeEventListener("abort", abort);
|
|
6139
|
+
resolve(value);
|
|
6140
|
+
});
|
|
6141
|
+
});
|
|
6142
|
+
}
|
|
6143
|
+
|
|
5900
6144
|
// src/kernel/tty.ts
|
|
5901
6145
|
var ICRNL = 256;
|
|
5902
6146
|
var IUTF8 = 16384;
|
|
@@ -6400,7 +6644,8 @@ var SOCKET_OPS = [
|
|
|
6400
6644
|
"sock-shutdown",
|
|
6401
6645
|
"sock-name",
|
|
6402
6646
|
"sock-getopt",
|
|
6403
|
-
"sock-setopt"
|
|
6647
|
+
"sock-setopt",
|
|
6648
|
+
"sock-resolve"
|
|
6404
6649
|
];
|
|
6405
6650
|
function socketAt(fds, fd) {
|
|
6406
6651
|
const file = fds.get(fd).file;
|
|
@@ -6449,6 +6694,11 @@ async function socketSyscall(req, proc) {
|
|
|
6449
6694
|
case "sock-setopt":
|
|
6450
6695
|
socketAt(fds, req.fd).setOption(req.level, req.name, req.value);
|
|
6451
6696
|
return ok();
|
|
6697
|
+
case "sock-resolve": {
|
|
6698
|
+
const addresses = await proc.resolve(req.name, req.family, () => proc.blocking());
|
|
6699
|
+
if (addresses.length === 0) throw new KernelError("ENOENT");
|
|
6700
|
+
return ok(addresses);
|
|
6701
|
+
}
|
|
6452
6702
|
}
|
|
6453
6703
|
}
|
|
6454
6704
|
function unnamed(domain) {
|
|
@@ -6700,7 +6950,7 @@ function isMissing(err) {
|
|
|
6700
6950
|
if (err?.code === "ENOENT") return true;
|
|
6701
6951
|
return err instanceof Error && err.message.startsWith("ENOENT");
|
|
6702
6952
|
}
|
|
6703
|
-
function
|
|
6953
|
+
function within4(path, root) {
|
|
6704
6954
|
return path === root || path.startsWith(root.endsWith("/") ? root : `${root}/`);
|
|
6705
6955
|
}
|
|
6706
6956
|
var VfsNode = class {
|
|
@@ -6908,7 +7158,7 @@ var VfsNodes = class {
|
|
|
6908
7158
|
return node;
|
|
6909
7159
|
}
|
|
6910
7160
|
holds(prefix) {
|
|
6911
|
-
for (const path of this.byPath.keys()) if (
|
|
7161
|
+
for (const path of this.byPath.keys()) if (within4(path, prefix)) return true;
|
|
6912
7162
|
return false;
|
|
6913
7163
|
}
|
|
6914
7164
|
closed(node) {
|
|
@@ -6916,24 +7166,24 @@ var VfsNodes = class {
|
|
|
6916
7166
|
if (node.opens === 0 && this.byPath.get(node.path) === node) this.byPath.delete(node.path);
|
|
6917
7167
|
}
|
|
6918
7168
|
async flush(path) {
|
|
6919
|
-
for (const [p, node] of this.byPath) if (
|
|
7169
|
+
for (const [p, node] of this.byPath) if (within4(p, path)) await node.serial(() => node.flush());
|
|
6920
7170
|
}
|
|
6921
7171
|
async unlinking(path) {
|
|
6922
7172
|
for (const [held, node] of [...this.byPath]) {
|
|
6923
|
-
if (!
|
|
7173
|
+
if (!within4(held, path)) continue;
|
|
6924
7174
|
await node.serial(async () => void await Promise.all([node.keep(), node.limit()]));
|
|
6925
7175
|
}
|
|
6926
7176
|
}
|
|
6927
7177
|
revoke(prefix) {
|
|
6928
7178
|
for (const [path, node] of this.byPath) {
|
|
6929
|
-
if (!
|
|
7179
|
+
if (!within4(path, prefix)) continue;
|
|
6930
7180
|
node.revoke();
|
|
6931
7181
|
this.byPath.delete(path);
|
|
6932
7182
|
}
|
|
6933
7183
|
}
|
|
6934
7184
|
unlinked(path) {
|
|
6935
7185
|
for (const [held, node] of [...this.byPath]) {
|
|
6936
|
-
if (!
|
|
7186
|
+
if (!within4(held, path)) continue;
|
|
6937
7187
|
node.orphaned = true;
|
|
6938
7188
|
this.byPath.delete(held);
|
|
6939
7189
|
}
|
|
@@ -6942,8 +7192,8 @@ var VfsNodes = class {
|
|
|
6942
7192
|
if (from === to) return;
|
|
6943
7193
|
const moved2 = [];
|
|
6944
7194
|
for (const [p, node] of this.byPath) {
|
|
6945
|
-
if (
|
|
6946
|
-
else if (
|
|
7195
|
+
if (within4(p, from)) moved2.push(node);
|
|
7196
|
+
else if (within4(p, to)) {
|
|
6947
7197
|
node.orphaned = true;
|
|
6948
7198
|
this.byPath.delete(p);
|
|
6949
7199
|
}
|
|
@@ -7197,6 +7447,7 @@ function isWasmSyscall(req) {
|
|
|
7197
7447
|
return typeof op === "string" && SYSCALL_OPS.has(op);
|
|
7198
7448
|
}
|
|
7199
7449
|
var MAX_READ = 1024 * 1024;
|
|
7450
|
+
var HOSTS_ONLY = new Resolver({ routes: new Routes() });
|
|
7200
7451
|
var WasmProcess = class {
|
|
7201
7452
|
exited = false;
|
|
7202
7453
|
children;
|
|
@@ -7588,10 +7839,12 @@ var WasmProcess = class {
|
|
|
7588
7839
|
}
|
|
7589
7840
|
socketSyscall(req) {
|
|
7590
7841
|
this.net ??= this.options.net ?? new LoopbackNet();
|
|
7842
|
+
const resolver = this.options.resolver ?? HOSTS_ONLY;
|
|
7591
7843
|
return socketSyscall(req, {
|
|
7592
7844
|
fds: this.fds,
|
|
7593
7845
|
net: this.net,
|
|
7594
|
-
blocking: () => this.blockingSignal()
|
|
7846
|
+
blocking: () => this.blockingSignal(),
|
|
7847
|
+
resolve: (name2, family, blocking) => resolver.resolve(name2, family, blocking)
|
|
7595
7848
|
});
|
|
7596
7849
|
}
|
|
7597
7850
|
tty(fd) {
|
|
@@ -7786,6 +8039,7 @@ function spawnWasmProcess(opts) {
|
|
|
7786
8039
|
http: opts.http,
|
|
7787
8040
|
locks: opts.locks,
|
|
7788
8041
|
onReap: opts.onReap,
|
|
8042
|
+
resolver: opts.resolver,
|
|
7789
8043
|
onPending: (sig) => void Atomics.or(header2, SAB_I_SIGNALS, sigbit(sig)),
|
|
7790
8044
|
onTimer: (which) => void Atomics.or(header2, SAB_I_TIMERS, 1 << which),
|
|
7791
8045
|
hasPending: () => Atomics.load(header2, SAB_I_SIGNALS) !== 0 || Atomics.load(header2, SAB_I_TIMERS) !== 0,
|
|
@@ -9325,6 +9579,9 @@ var Launcher = class {
|
|
|
9325
9579
|
cdp;
|
|
9326
9580
|
ca;
|
|
9327
9581
|
transport;
|
|
9582
|
+
uplink;
|
|
9583
|
+
routes;
|
|
9584
|
+
resolver;
|
|
9328
9585
|
watchers = new FsWatchers();
|
|
9329
9586
|
pnpmHome;
|
|
9330
9587
|
mounts;
|
|
@@ -9364,6 +9621,10 @@ var Launcher = class {
|
|
|
9364
9621
|
this.env = { ...networkEnv(), SLICC_CDP_URL: this.cdp.url, ...options.env };
|
|
9365
9622
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
9366
9623
|
this.transport = options.transport ?? missingTransport();
|
|
9624
|
+
this.uplink = options.uplink;
|
|
9625
|
+
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
9626
|
+
if (options.uplink?.routes) this.routes.set(options.uplink.routes);
|
|
9627
|
+
this.resolver = new Resolver({ uplink: options.uplink, routes: this.routes });
|
|
9367
9628
|
enableNetwork(this.net, {
|
|
9368
9629
|
transport: this.transport,
|
|
9369
9630
|
engine: kernelTlsEngine(packageTlsEngine(options.fs, this.modulesDir)),
|
|
@@ -9378,6 +9639,9 @@ var Launcher = class {
|
|
|
9378
9639
|
this.catalog = void 0;
|
|
9379
9640
|
});
|
|
9380
9641
|
}
|
|
9642
|
+
setRoutes(table) {
|
|
9643
|
+
this.routes.set(table);
|
|
9644
|
+
}
|
|
9381
9645
|
commands() {
|
|
9382
9646
|
this.catalog ??= this.roots().then((roots) => scanCommands(this.base, roots));
|
|
9383
9647
|
return this.catalog;
|
|
@@ -9557,6 +9821,7 @@ var Launcher = class {
|
|
|
9557
9821
|
net: this.net,
|
|
9558
9822
|
http: new HttpHandles(this.transport),
|
|
9559
9823
|
locks: this.locks,
|
|
9824
|
+
resolver: this.resolver,
|
|
9560
9825
|
onReap: (child) => this.reaped(child),
|
|
9561
9826
|
...req.fork ? { fork: req.fork } : {},
|
|
9562
9827
|
...this.shownIds(req)
|
|
@@ -9959,9 +10224,22 @@ function cdpOption(req, port) {
|
|
|
9959
10224
|
)
|
|
9960
10225
|
};
|
|
9961
10226
|
}
|
|
10227
|
+
function remotes(port, req) {
|
|
10228
|
+
return {
|
|
10229
|
+
...req.transport ? { transport: new RemoteTransport(port, req.transport) } : {},
|
|
10230
|
+
...req.uplink ? { uplink: new RemoteUplink(port, req.uplink.traits, req.uplink.routes) } : {}
|
|
10231
|
+
};
|
|
10232
|
+
}
|
|
10233
|
+
function answered(data, remote, uplink) {
|
|
10234
|
+
if (data.net !== void 0) remote?.receive(data);
|
|
10235
|
+
else if (typeof data.uplink === "string") uplink?.receive(data);
|
|
10236
|
+
else return false;
|
|
10237
|
+
return true;
|
|
10238
|
+
}
|
|
9962
10239
|
function serveKernel(port, deps) {
|
|
9963
10240
|
let launcher;
|
|
9964
10241
|
let remote;
|
|
10242
|
+
let uplink;
|
|
9965
10243
|
const terminals = /* @__PURE__ */ new Map();
|
|
9966
10244
|
const reply = (id, body, transfer) => port.postMessage({ id, ...body }, transfer);
|
|
9967
10245
|
const clients = /* @__PURE__ */ new Set();
|
|
@@ -10017,7 +10295,8 @@ function serveKernel(port, deps) {
|
|
|
10017
10295
|
launcher = (req.root ? Promise.resolve(req.root) : deps.storage()).then(async (root) => {
|
|
10018
10296
|
const name2 = req.metadata ?? META_DB;
|
|
10019
10297
|
const { meta, media } = await stores(deps, name2, req.media);
|
|
10020
|
-
|
|
10298
|
+
const net = remotes(port, req);
|
|
10299
|
+
({ transport: remote, uplink } = net);
|
|
10021
10300
|
const ranged2 = await inOpfs(deps, root);
|
|
10022
10301
|
const fs = new OpfsFs(root, meta, dirsChannel(name2), { ranged: ranged2 });
|
|
10023
10302
|
await fs.reconcile();
|
|
@@ -10027,7 +10306,7 @@ function serveKernel(port, deps) {
|
|
|
10027
10306
|
...deps.createDriverWorker ? { createDriverWorker: deps.createDriverWorker } : {},
|
|
10028
10307
|
...req.modules ? { modules: req.modules } : {},
|
|
10029
10308
|
...req.env ? { env: req.env } : {},
|
|
10030
|
-
...
|
|
10309
|
+
...net,
|
|
10031
10310
|
...media ? { media } : {},
|
|
10032
10311
|
onMountPending: (medium) => port.postMessage({ medium }),
|
|
10033
10312
|
...req.hostfs ? { hostfs: askGrant } : {},
|
|
@@ -10052,6 +10331,10 @@ function serveKernel(port, deps) {
|
|
|
10052
10331
|
if (req.op === "init") return init(req);
|
|
10053
10332
|
if (req.op === "open-terminal") return terminal(req);
|
|
10054
10333
|
if (req.op === "connect") return connect();
|
|
10334
|
+
if (req.op === "routes") {
|
|
10335
|
+
(await ready2()).setRoutes(req.routes);
|
|
10336
|
+
return true;
|
|
10337
|
+
}
|
|
10055
10338
|
if (req.op === "dial") return dial(req);
|
|
10056
10339
|
if (req.op === "mount" || req.op === "umount" || req.op === "mounts" || req.op === "insert")
|
|
10057
10340
|
return mountOp(req);
|
|
@@ -10100,10 +10383,7 @@ function serveKernel(port, deps) {
|
|
|
10100
10383
|
policies.delete(answer.id);
|
|
10101
10384
|
return;
|
|
10102
10385
|
}
|
|
10103
|
-
if (event.data
|
|
10104
|
-
remote?.receive(event.data);
|
|
10105
|
-
return;
|
|
10106
|
-
}
|
|
10386
|
+
if (answered(event.data, remote, uplink)) return;
|
|
10107
10387
|
const req = event.data;
|
|
10108
10388
|
handle(req).then(
|
|
10109
10389
|
(result) => reply(req.id, { result }, result instanceof MessagePort ? [result] : void 0),
|