@ai-ecoverse/slicc-kernel 1.22.1 → 1.23.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 +30 -3
- package/dist/driver-worker.js +87 -1
- package/dist/driver-worker.js.map +3 -3
- package/dist/index.js +126 -15
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +603 -40
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-driver-worker.js +87 -1
- package/dist/node-driver-worker.js.map +3 -3
- package/dist/node.js +923 -283
- package/dist/node.js.map +4 -4
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -224,8 +224,51 @@ function pinScript(url) {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
// src/cdp/port.ts
|
|
228
|
+
function portCdpHook(ask, gone) {
|
|
229
|
+
return (request2) => new Promise((resolve, reject) => {
|
|
230
|
+
const { port1, port2 } = new MessageChannel();
|
|
231
|
+
let closed = false;
|
|
232
|
+
const conn = {
|
|
233
|
+
send: (m) => {
|
|
234
|
+
if (!closed) port1.postMessage({ m });
|
|
235
|
+
},
|
|
236
|
+
onmessage: null,
|
|
237
|
+
onclose: null,
|
|
238
|
+
close: () => {
|
|
239
|
+
if (closed) return;
|
|
240
|
+
closed = true;
|
|
241
|
+
port1.postMessage({ close: true });
|
|
242
|
+
port1.close();
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
port1.addEventListener("message", ({ data }) => {
|
|
246
|
+
if ("m" in data) conn.onmessage?.(data.m);
|
|
247
|
+
else if ("open" in data) resolve(conn);
|
|
248
|
+
else if ("error" in data) {
|
|
249
|
+
closed = true;
|
|
250
|
+
port1.close();
|
|
251
|
+
reject(new Error(data.error));
|
|
252
|
+
} else if (!closed) {
|
|
253
|
+
closed = true;
|
|
254
|
+
port1.close();
|
|
255
|
+
conn.onclose?.(data.close ?? void 0);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
port1.start();
|
|
259
|
+
void gone?.then(() => {
|
|
260
|
+
if (closed) return;
|
|
261
|
+
closed = true;
|
|
262
|
+
port1.close();
|
|
263
|
+
reject(new Error("the CDP host is gone"));
|
|
264
|
+
conn.onclose?.("the CDP host is gone");
|
|
265
|
+
});
|
|
266
|
+
ask(request2, port2);
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
|
|
227
270
|
// src/client/protocol.ts
|
|
228
|
-
var PROTOCOL = [1,
|
|
271
|
+
var PROTOCOL = [1, 5];
|
|
229
272
|
var FS_METHODS = [
|
|
230
273
|
"readFile",
|
|
231
274
|
"writeFile",
|
|
@@ -887,7 +930,12 @@ function keyOf(addr) {
|
|
|
887
930
|
var LoopbackNet = class {
|
|
888
931
|
bound = /* @__PURE__ */ new Map();
|
|
889
932
|
activators = /* @__PURE__ */ new Map();
|
|
933
|
+
internal = /* @__PURE__ */ new Set();
|
|
890
934
|
nextEphemeral = EPHEMERAL_FIRST;
|
|
935
|
+
kernelOnly(port, reserve = false) {
|
|
936
|
+
if (reserve) this.internal.add(port);
|
|
937
|
+
return this.internal.has(port);
|
|
938
|
+
}
|
|
891
939
|
activate(addr, start) {
|
|
892
940
|
this.activators.set(keyOf(addr), start);
|
|
893
941
|
}
|
|
@@ -948,6 +996,14 @@ var LOOPBACK_NAMES = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1", "
|
|
|
948
996
|
function dialSocket(net, port, host = "127.0.0.1") {
|
|
949
997
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new KernelError("EINVAL");
|
|
950
998
|
const target = LOOPBACK_NAMES.has(host.toLowerCase()) ? "127.0.0.1" : host;
|
|
999
|
+
if (net.kernelOnly(port)) {
|
|
1000
|
+
throw Object.assign(
|
|
1001
|
+
new Error(`ECONNREFUSED: port ${port} only takes connections from inside the kernel`),
|
|
1002
|
+
{
|
|
1003
|
+
code: "ECONNREFUSED"
|
|
1004
|
+
}
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
951
1007
|
return net.connect({ family: "inet", host: target, port });
|
|
952
1008
|
}
|
|
953
1009
|
var codeOf = (err) => {
|
|
@@ -1236,6 +1292,43 @@ function joinable(l, pgid, ours) {
|
|
|
1236
1292
|
if (sid === void 0) throw fsError("ESRCH", `no process group ${pgid}`);
|
|
1237
1293
|
if (!ours(sid)) throw fsError("EPERM", `process group ${pgid} is in another session`);
|
|
1238
1294
|
}
|
|
1295
|
+
function cdpRegistry(send, gone) {
|
|
1296
|
+
const registered = /* @__PURE__ */ new Map();
|
|
1297
|
+
const drop = (id) => {
|
|
1298
|
+
registered.get(id)?.();
|
|
1299
|
+
return registered.delete(id);
|
|
1300
|
+
};
|
|
1301
|
+
return {
|
|
1302
|
+
serve(l, req) {
|
|
1303
|
+
const hook = portCdpHook(
|
|
1304
|
+
(request2, cdp) => send({ cdpOpen: { ...request2, registration: req.id }, port: cdp }, [
|
|
1305
|
+
cdp
|
|
1306
|
+
]),
|
|
1307
|
+
gone
|
|
1308
|
+
);
|
|
1309
|
+
registered.set(req.id, l.cdp.register(hook, req.runtime));
|
|
1310
|
+
return req.id;
|
|
1311
|
+
},
|
|
1312
|
+
drop,
|
|
1313
|
+
close: () => {
|
|
1314
|
+
for (const id of [...registered.keys()]) drop(id);
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
}
|
|
1318
|
+
function watchOp(l, req, watches, send) {
|
|
1319
|
+
if (req.op === "unwatch") {
|
|
1320
|
+
watches.get(req.watch)?.();
|
|
1321
|
+
watches.delete(req.watch);
|
|
1322
|
+
return { result: true };
|
|
1323
|
+
}
|
|
1324
|
+
const unwatch = l.watchers.watch(
|
|
1325
|
+
req.paths,
|
|
1326
|
+
{ recursive: req.recursive },
|
|
1327
|
+
(change) => send({ watch: req.id, change })
|
|
1328
|
+
);
|
|
1329
|
+
watches.set(req.id, unwatch);
|
|
1330
|
+
return { result: req.id };
|
|
1331
|
+
}
|
|
1239
1332
|
function serveClient(port, host) {
|
|
1240
1333
|
let state = "new";
|
|
1241
1334
|
const terminals = /* @__PURE__ */ new Map();
|
|
@@ -1248,6 +1341,7 @@ function serveClient(port, host) {
|
|
|
1248
1341
|
if (state !== "closed") port.postMessage(message2, transfer);
|
|
1249
1342
|
};
|
|
1250
1343
|
const reply = (id, body, transfer) => send({ id, ...body }, transfer);
|
|
1344
|
+
const cdps = cdpRegistry(send, ended.promise);
|
|
1251
1345
|
function detach(kill = false, bye = "the slicc-kernel detached this client") {
|
|
1252
1346
|
if (state === "closed") return;
|
|
1253
1347
|
send({ bye });
|
|
@@ -1255,6 +1349,7 @@ function serveClient(port, host) {
|
|
|
1255
1349
|
net?.close();
|
|
1256
1350
|
for (const unwatch of watches.values()) unwatch();
|
|
1257
1351
|
watches.clear();
|
|
1352
|
+
cdps.close();
|
|
1258
1353
|
for (const session of terminals.values()) session.close();
|
|
1259
1354
|
terminals.clear();
|
|
1260
1355
|
if (kill) killGroups(host, [...groups]);
|
|
@@ -1349,19 +1444,9 @@ function serveClient(port, host) {
|
|
|
1349
1444
|
throw new Error(`unknown file system call ${req.method}`);
|
|
1350
1445
|
}
|
|
1351
1446
|
return fsCall(l.fs, req.method, req.args);
|
|
1352
|
-
case "watch":
|
|
1353
|
-
const unwatch = l.watchers.watch(
|
|
1354
|
-
req.paths,
|
|
1355
|
-
{ recursive: req.recursive },
|
|
1356
|
-
(change) => send({ watch: req.id, change })
|
|
1357
|
-
);
|
|
1358
|
-
watches.set(req.id, unwatch);
|
|
1359
|
-
return { result: req.id };
|
|
1360
|
-
}
|
|
1447
|
+
case "watch":
|
|
1361
1448
|
case "unwatch":
|
|
1362
|
-
|
|
1363
|
-
watches.delete(req.watch);
|
|
1364
|
-
return { result: true };
|
|
1449
|
+
return watchOp(l, req, watches, send);
|
|
1365
1450
|
case "mount":
|
|
1366
1451
|
return { result: await l.mount(req.spec) };
|
|
1367
1452
|
case "umount":
|
|
@@ -1371,6 +1456,10 @@ function serveClient(port, host) {
|
|
|
1371
1456
|
return { result: l.mounts.list() };
|
|
1372
1457
|
case "dial":
|
|
1373
1458
|
return dialFor(l, req, watches);
|
|
1459
|
+
case "serve-cdp":
|
|
1460
|
+
return { result: cdps.serve(l, req) };
|
|
1461
|
+
case "unserve-cdp":
|
|
1462
|
+
return { result: cdps.drop(req.registration) };
|
|
1374
1463
|
case "detach":
|
|
1375
1464
|
return { result: true };
|
|
1376
1465
|
default:
|
|
@@ -1934,6 +2023,8 @@ var REASON = {
|
|
|
1934
2023
|
200: "OK",
|
|
1935
2024
|
400: "Bad Request",
|
|
1936
2025
|
403: "Forbidden",
|
|
2026
|
+
404: "Not Found",
|
|
2027
|
+
405: "Method Not Allowed",
|
|
1937
2028
|
408: "Request Timeout",
|
|
1938
2029
|
411: "Length Required",
|
|
1939
2030
|
413: "Content Too Large",
|
|
@@ -1943,6 +2034,7 @@ var REASON = {
|
|
|
1943
2034
|
501: "Not Implemented",
|
|
1944
2035
|
502: "Bad Gateway",
|
|
1945
2036
|
503: "Service Unavailable",
|
|
2037
|
+
504: "Gateway Timeout",
|
|
1946
2038
|
505: "HTTP Version Not Supported"
|
|
1947
2039
|
};
|
|
1948
2040
|
var Incoming = class {
|
|
@@ -3388,6 +3480,465 @@ var RemoteTransport = class {
|
|
|
3388
3480
|
}
|
|
3389
3481
|
};
|
|
3390
3482
|
|
|
3483
|
+
// src/cdp/types.ts
|
|
3484
|
+
var CDP_PORT = 9222;
|
|
3485
|
+
var NO_CDP_HOST = "slicc-kernel: no CDP host is attached (createKernel({ cdp }) or client.serveCdp)";
|
|
3486
|
+
|
|
3487
|
+
// src/cdp/websocket.ts
|
|
3488
|
+
var GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
3489
|
+
var MAX_MESSAGE = 256 * 1024 * 1024;
|
|
3490
|
+
var CLOSE = {
|
|
3491
|
+
normal: 1e3,
|
|
3492
|
+
protocol: 1002,
|
|
3493
|
+
unsupported: 1003,
|
|
3494
|
+
invalid: 1007,
|
|
3495
|
+
tooBig: 1009,
|
|
3496
|
+
error: 1011
|
|
3497
|
+
};
|
|
3498
|
+
var OP_TEXT = 1;
|
|
3499
|
+
var OP = { continuation: 0, text: OP_TEXT, binary: 2, close: 8, ping: 9, pong: 10 };
|
|
3500
|
+
var WsError = class extends Error {
|
|
3501
|
+
code;
|
|
3502
|
+
constructor(code, message2) {
|
|
3503
|
+
super(message2);
|
|
3504
|
+
this.code = code;
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3507
|
+
function field(headers, name2) {
|
|
3508
|
+
return headers.find(([n]) => n.toLowerCase() === name2)?.[1];
|
|
3509
|
+
}
|
|
3510
|
+
async function acceptKey(headers) {
|
|
3511
|
+
const tokens = (name2) => (field(headers, name2) ?? "").split(",").map((t) => t.trim().toLowerCase());
|
|
3512
|
+
if (!tokens("upgrade").includes("websocket") || !tokens("connection").includes("upgrade")) {
|
|
3513
|
+
throw new HttpError(400, "expected a WebSocket upgrade");
|
|
3514
|
+
}
|
|
3515
|
+
if (field(headers, "sec-websocket-version") !== "13") {
|
|
3516
|
+
throw new HttpError(400, "Sec-WebSocket-Version must be 13");
|
|
3517
|
+
}
|
|
3518
|
+
const key = field(headers, "sec-websocket-key") ?? "";
|
|
3519
|
+
if (!/^[A-Za-z0-9+/]{22}==$/.test(key)) throw new HttpError(400, "bad Sec-WebSocket-Key");
|
|
3520
|
+
const digest = await crypto.subtle.digest("SHA-1", new TextEncoder().encode(key + GUID));
|
|
3521
|
+
return btoa(String.fromCharCode(...new Uint8Array(digest)));
|
|
3522
|
+
}
|
|
3523
|
+
function isUpgrade(headers) {
|
|
3524
|
+
return (field(headers, "upgrade") ?? "").toLowerCase().includes("websocket");
|
|
3525
|
+
}
|
|
3526
|
+
function frame(opcode, payload) {
|
|
3527
|
+
const n = payload.length;
|
|
3528
|
+
const size = n < 126 ? 2 : n < 65536 ? 4 : 10;
|
|
3529
|
+
const out = new Uint8Array(size + n);
|
|
3530
|
+
const view = new DataView(out.buffer);
|
|
3531
|
+
out[0] = 128 | opcode;
|
|
3532
|
+
if (n < 126) out[1] = n;
|
|
3533
|
+
else if (n < 65536) {
|
|
3534
|
+
out[1] = 126;
|
|
3535
|
+
view.setUint16(2, n);
|
|
3536
|
+
} else {
|
|
3537
|
+
out[1] = 127;
|
|
3538
|
+
view.setBigUint64(2, BigInt(n));
|
|
3539
|
+
}
|
|
3540
|
+
out.set(payload, size);
|
|
3541
|
+
return out;
|
|
3542
|
+
}
|
|
3543
|
+
function closeFrame(code, reason = "") {
|
|
3544
|
+
let bytes = new TextEncoder().encode(reason);
|
|
3545
|
+
if (bytes.length > 123) bytes = bytes.subarray(0, 123);
|
|
3546
|
+
const payload = new Uint8Array(2 + bytes.length);
|
|
3547
|
+
new DataView(payload.buffer).setUint16(0, code);
|
|
3548
|
+
payload.set(bytes, 2);
|
|
3549
|
+
return frame(OP.close, payload);
|
|
3550
|
+
}
|
|
3551
|
+
function pongFrame(payload) {
|
|
3552
|
+
return frame(OP.pong, payload);
|
|
3553
|
+
}
|
|
3554
|
+
async function fill(incoming, out, signal) {
|
|
3555
|
+
for (let at = 0; at < out.length; ) {
|
|
3556
|
+
const piece = await incoming.some(out.length - at, signal);
|
|
3557
|
+
if (piece.length === 0) throw new WsError(CLOSE.protocol, "the connection closed mid-frame");
|
|
3558
|
+
out.set(piece, at);
|
|
3559
|
+
at += piece.length;
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
var fatal = new TextDecoder("utf-8", { fatal: true });
|
|
3563
|
+
function decode(bytes) {
|
|
3564
|
+
try {
|
|
3565
|
+
return fatal.decode(bytes);
|
|
3566
|
+
} catch {
|
|
3567
|
+
throw new WsError(CLOSE.invalid, "a text message is not UTF-8");
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
var WsReader = class {
|
|
3571
|
+
incoming;
|
|
3572
|
+
max;
|
|
3573
|
+
parts = [];
|
|
3574
|
+
size = 0;
|
|
3575
|
+
continuing = false;
|
|
3576
|
+
constructor(incoming, max = MAX_MESSAGE) {
|
|
3577
|
+
this.incoming = incoming;
|
|
3578
|
+
this.max = max;
|
|
3579
|
+
}
|
|
3580
|
+
async next(signal) {
|
|
3581
|
+
for (; ; ) {
|
|
3582
|
+
const first = await this.incoming.some(1, signal);
|
|
3583
|
+
if (first.length === 0) return null;
|
|
3584
|
+
const head = new Uint8Array(2);
|
|
3585
|
+
head[0] = first[0];
|
|
3586
|
+
await fill(this.incoming, head.subarray(1), signal);
|
|
3587
|
+
const fin = (head[0] & 128) !== 0;
|
|
3588
|
+
const opcode = head[0] & 15;
|
|
3589
|
+
if ((head[0] & 112) !== 0) throw new WsError(CLOSE.protocol, "reserved bits are set");
|
|
3590
|
+
if ((head[1] & 128) === 0) throw new WsError(CLOSE.protocol, "client frames must be masked");
|
|
3591
|
+
const length2 = await this.length(head[1] & 127, signal);
|
|
3592
|
+
const control = opcode >= 8;
|
|
3593
|
+
if (control && (length2 > 125 || !fin)) {
|
|
3594
|
+
throw new WsError(CLOSE.protocol, "a control frame is too long or fragmented");
|
|
3595
|
+
}
|
|
3596
|
+
if (!control && this.size + length2 > this.max) {
|
|
3597
|
+
throw new WsError(CLOSE.tooBig, `a message is over ${this.max} bytes`);
|
|
3598
|
+
}
|
|
3599
|
+
const mask = new Uint8Array(4);
|
|
3600
|
+
await fill(this.incoming, mask, signal);
|
|
3601
|
+
const payload = new Uint8Array(length2);
|
|
3602
|
+
await fill(this.incoming, payload, signal);
|
|
3603
|
+
for (let i = 0; i < length2; i++) payload[i] ^= mask[i & 3];
|
|
3604
|
+
const event = this.take(opcode, fin, payload);
|
|
3605
|
+
if (event) return event;
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
async length(short, signal) {
|
|
3609
|
+
if (short < 126) return short;
|
|
3610
|
+
const ext = new Uint8Array(short === 126 ? 2 : 8);
|
|
3611
|
+
await fill(this.incoming, ext, signal);
|
|
3612
|
+
const view = new DataView(ext.buffer);
|
|
3613
|
+
if (short === 126) return view.getUint16(0);
|
|
3614
|
+
const long = view.getBigUint64(0);
|
|
3615
|
+
return long > BigInt(this.max) ? this.max + 1 : Number(long);
|
|
3616
|
+
}
|
|
3617
|
+
take(opcode, fin, payload) {
|
|
3618
|
+
switch (opcode) {
|
|
3619
|
+
case OP.ping:
|
|
3620
|
+
return { kind: "ping", payload };
|
|
3621
|
+
case OP.pong:
|
|
3622
|
+
return void 0;
|
|
3623
|
+
case OP.close: {
|
|
3624
|
+
if (payload.length === 1) throw new WsError(CLOSE.protocol, "a close frame is malformed");
|
|
3625
|
+
const code = payload.length >= 2 ? new DataView(payload.buffer).getUint16(0) : 1005;
|
|
3626
|
+
return { kind: "close", code, reason: decode(payload.subarray(2)) };
|
|
3627
|
+
}
|
|
3628
|
+
case OP.text:
|
|
3629
|
+
case OP.continuation: {
|
|
3630
|
+
if (opcode === OP.continuation !== this.continuing) {
|
|
3631
|
+
throw new WsError(CLOSE.protocol, "unexpected continuation frame");
|
|
3632
|
+
}
|
|
3633
|
+
this.parts.push(payload);
|
|
3634
|
+
this.size += payload.length;
|
|
3635
|
+
this.continuing = !fin;
|
|
3636
|
+
if (!fin) return void 0;
|
|
3637
|
+
const whole = this.parts.length === 1 ? payload : concat(this.parts, this.size);
|
|
3638
|
+
this.parts = [];
|
|
3639
|
+
this.size = 0;
|
|
3640
|
+
return { kind: "text", text: decode(whole) };
|
|
3641
|
+
}
|
|
3642
|
+
case OP.binary:
|
|
3643
|
+
throw new WsError(CLOSE.unsupported, "CDP messages are text");
|
|
3644
|
+
default:
|
|
3645
|
+
throw new WsError(CLOSE.protocol, `unknown opcode ${opcode}`);
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
};
|
|
3649
|
+
function switchingHead(accept2) {
|
|
3650
|
+
return latin1Bytes(
|
|
3651
|
+
`HTTP/1.1 101 Switching Protocols\r
|
|
3652
|
+
Upgrade: websocket\r
|
|
3653
|
+
Connection: Upgrade\r
|
|
3654
|
+
Sec-WebSocket-Accept: ${accept2}\r
|
|
3655
|
+
\r
|
|
3656
|
+
`
|
|
3657
|
+
);
|
|
3658
|
+
}
|
|
3659
|
+
|
|
3660
|
+
// src/cdp/facade.ts
|
|
3661
|
+
var MAX_HEAD = 64 * 1024;
|
|
3662
|
+
var LIST_TIMEOUT = 1e4;
|
|
3663
|
+
function respond(status, body, type = "text/plain; charset=utf-8") {
|
|
3664
|
+
const bytes = new TextEncoder().encode(body);
|
|
3665
|
+
const head = latin1Bytes(
|
|
3666
|
+
`HTTP/1.1 ${status} ${REASON[status]}\r
|
|
3667
|
+
Content-Type: ${type}\r
|
|
3668
|
+
Content-Length: ${bytes.length}\r
|
|
3669
|
+
Connection: close\r
|
|
3670
|
+
\r
|
|
3671
|
+
`
|
|
3672
|
+
);
|
|
3673
|
+
const out = new Uint8Array(head.length + bytes.length);
|
|
3674
|
+
out.set(head);
|
|
3675
|
+
out.set(bytes, head.length);
|
|
3676
|
+
return out;
|
|
3677
|
+
}
|
|
3678
|
+
function json(value) {
|
|
3679
|
+
return respond(200, `${JSON.stringify(value, null, 2)}
|
|
3680
|
+
`, "application/json; charset=UTF-8");
|
|
3681
|
+
}
|
|
3682
|
+
var CdpFacade = class {
|
|
3683
|
+
options;
|
|
3684
|
+
listener;
|
|
3685
|
+
stop = new AbortController();
|
|
3686
|
+
connections = /* @__PURE__ */ new Set();
|
|
3687
|
+
closed;
|
|
3688
|
+
constructor(options) {
|
|
3689
|
+
this.options = options;
|
|
3690
|
+
this.listener = options.net.listen({
|
|
3691
|
+
family: "inet",
|
|
3692
|
+
host: "127.0.0.1",
|
|
3693
|
+
port: options.port ?? CDP_PORT
|
|
3694
|
+
});
|
|
3695
|
+
this.closed = this.acceptLoop();
|
|
3696
|
+
}
|
|
3697
|
+
close() {
|
|
3698
|
+
if (this.stop.signal.aborted) return;
|
|
3699
|
+
this.stop.abort();
|
|
3700
|
+
this.listener.close();
|
|
3701
|
+
for (const conn of this.connections) conn.close();
|
|
3702
|
+
}
|
|
3703
|
+
async acceptLoop() {
|
|
3704
|
+
const served = /* @__PURE__ */ new Set();
|
|
3705
|
+
for (; ; ) {
|
|
3706
|
+
let conn;
|
|
3707
|
+
try {
|
|
3708
|
+
conn = await this.listener.accept(this.stop.signal);
|
|
3709
|
+
} catch {
|
|
3710
|
+
break;
|
|
3711
|
+
}
|
|
3712
|
+
const done4 = this.serve(conn).finally(() => served.delete(done4));
|
|
3713
|
+
served.add(done4);
|
|
3714
|
+
}
|
|
3715
|
+
await Promise.allSettled([...served]);
|
|
3716
|
+
}
|
|
3717
|
+
async serve(conn) {
|
|
3718
|
+
this.connections.add(conn);
|
|
3719
|
+
const incoming = new Incoming(conn);
|
|
3720
|
+
try {
|
|
3721
|
+
const head = await incoming.head(MAX_HEAD, this.stop.signal);
|
|
3722
|
+
if (head) await this.route(conn, incoming, parseRequestHead(head));
|
|
3723
|
+
} catch (e) {
|
|
3724
|
+
if (e instanceof HttpError) await this.write(conn, respond(e.status, `${e.message}
|
|
3725
|
+
`));
|
|
3726
|
+
} finally {
|
|
3727
|
+
this.connections.delete(conn);
|
|
3728
|
+
conn.close();
|
|
3729
|
+
}
|
|
3730
|
+
}
|
|
3731
|
+
async write(conn, bytes) {
|
|
3732
|
+
try {
|
|
3733
|
+
await conn.write(bytes, this.stop.signal);
|
|
3734
|
+
} catch {
|
|
3735
|
+
}
|
|
3736
|
+
}
|
|
3737
|
+
async route(conn, incoming, req) {
|
|
3738
|
+
const url = new URL(req.target, "http://127.0.0.1");
|
|
3739
|
+
const runtime = url.searchParams.get("runtime") ?? void 0;
|
|
3740
|
+
const host = req.headers.find(([n]) => n.toLowerCase() === "host")?.[1] ?? "127.0.0.1";
|
|
3741
|
+
if (req.method !== "GET") throw new HttpError(405, `${req.method} is not supported here`);
|
|
3742
|
+
const { hosts } = this.options;
|
|
3743
|
+
if (url.pathname === hosts.path && isUpgrade(req.headers)) {
|
|
3744
|
+
return this.upgrade(conn, incoming, req, runtime);
|
|
3745
|
+
}
|
|
3746
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
3747
|
+
if (path !== "/json/version" && path !== "/json/list" && path !== "/json") {
|
|
3748
|
+
throw new HttpError(404, "not found: try /json/version");
|
|
3749
|
+
}
|
|
3750
|
+
if (!this.options.hosts.available(runtime)) {
|
|
3751
|
+
throw new HttpError(503, NO_CDP_HOST);
|
|
3752
|
+
}
|
|
3753
|
+
if (path === "/json/version") {
|
|
3754
|
+
await this.write(
|
|
3755
|
+
conn,
|
|
3756
|
+
json({
|
|
3757
|
+
Browser: "slicc-kernel",
|
|
3758
|
+
"Protocol-Version": "1.3",
|
|
3759
|
+
webSocketDebuggerUrl: `ws://${host}${hosts.path}${url.search}`
|
|
3760
|
+
})
|
|
3761
|
+
);
|
|
3762
|
+
return;
|
|
3763
|
+
}
|
|
3764
|
+
await this.write(conn, json(await this.list(runtime)));
|
|
3765
|
+
}
|
|
3766
|
+
async list(runtime) {
|
|
3767
|
+
const conn = await this.host(runtime);
|
|
3768
|
+
try {
|
|
3769
|
+
const reply = await new Promise(
|
|
3770
|
+
(resolve, reject) => {
|
|
3771
|
+
const timer = setTimeout(
|
|
3772
|
+
() => reject(new HttpError(504, "the CDP host did not answer Target.getTargets")),
|
|
3773
|
+
this.options.listTimeout ?? LIST_TIMEOUT
|
|
3774
|
+
);
|
|
3775
|
+
conn.onclose = (reason) => {
|
|
3776
|
+
clearTimeout(timer);
|
|
3777
|
+
reject(new HttpError(502, `the CDP host closed: ${reason ?? "no reason"}`));
|
|
3778
|
+
};
|
|
3779
|
+
conn.onmessage = (message2) => {
|
|
3780
|
+
const parsed = JSON.parse(message2);
|
|
3781
|
+
if (parsed.id !== 1) return;
|
|
3782
|
+
clearTimeout(timer);
|
|
3783
|
+
resolve(parsed);
|
|
3784
|
+
};
|
|
3785
|
+
conn.send(JSON.stringify({ id: 1, method: "Target.getTargets" }));
|
|
3786
|
+
}
|
|
3787
|
+
);
|
|
3788
|
+
if (!reply.result) {
|
|
3789
|
+
throw new HttpError(502, `Target.getTargets failed: ${JSON.stringify(reply.error)}`);
|
|
3790
|
+
}
|
|
3791
|
+
return (reply.result.targetInfos ?? []).map((t) => ({
|
|
3792
|
+
description: "",
|
|
3793
|
+
id: t.targetId,
|
|
3794
|
+
title: t.title,
|
|
3795
|
+
type: t.type,
|
|
3796
|
+
url: t.url
|
|
3797
|
+
}));
|
|
3798
|
+
} finally {
|
|
3799
|
+
conn.close();
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
host(runtime) {
|
|
3803
|
+
return this.options.hosts.connect(runtime ? { runtime } : {});
|
|
3804
|
+
}
|
|
3805
|
+
async upgrade(conn, incoming, req, runtime) {
|
|
3806
|
+
const accept2 = await acceptKey(req.headers);
|
|
3807
|
+
const host = await this.host(runtime);
|
|
3808
|
+
await new Relay(conn, incoming, host, this.options.maxMessage ?? MAX_MESSAGE, this.stop.signal).start(switchingHead(accept2)).finally(() => host.close());
|
|
3809
|
+
}
|
|
3810
|
+
};
|
|
3811
|
+
var Relay = class {
|
|
3812
|
+
writes = Promise.resolve();
|
|
3813
|
+
ended = false;
|
|
3814
|
+
conn;
|
|
3815
|
+
incoming;
|
|
3816
|
+
host;
|
|
3817
|
+
max;
|
|
3818
|
+
stop;
|
|
3819
|
+
constructor(conn, incoming, host, max, stop) {
|
|
3820
|
+
this.conn = conn;
|
|
3821
|
+
this.incoming = incoming;
|
|
3822
|
+
this.host = host;
|
|
3823
|
+
this.max = max;
|
|
3824
|
+
this.stop = stop;
|
|
3825
|
+
}
|
|
3826
|
+
send(bytes) {
|
|
3827
|
+
this.writes = this.writes.then(() => this.conn.write(bytes, this.stop)).catch(() => void 0);
|
|
3828
|
+
return this.writes;
|
|
3829
|
+
}
|
|
3830
|
+
end(code, reason) {
|
|
3831
|
+
if (this.ended) return this.writes;
|
|
3832
|
+
this.ended = true;
|
|
3833
|
+
return this.send(closeFrame(code, reason));
|
|
3834
|
+
}
|
|
3835
|
+
async start(head) {
|
|
3836
|
+
await this.send(head);
|
|
3837
|
+
const hostGone = new Promise((resolve) => {
|
|
3838
|
+
this.host.onclose = (reason) => {
|
|
3839
|
+
void this.end(reason ? CLOSE.error : CLOSE.normal, reason ?? "").then(() => resolve());
|
|
3840
|
+
};
|
|
3841
|
+
});
|
|
3842
|
+
this.host.onmessage = (message2) => {
|
|
3843
|
+
if (this.ended) return;
|
|
3844
|
+
const bytes = new TextEncoder().encode(message2);
|
|
3845
|
+
if (bytes.length > this.max)
|
|
3846
|
+
void this.end(CLOSE.tooBig, `a message is over ${this.max} bytes`);
|
|
3847
|
+
else void this.send(frame(OP_TEXT, bytes));
|
|
3848
|
+
};
|
|
3849
|
+
await Promise.race([this.pump(), hostGone]);
|
|
3850
|
+
await this.writes;
|
|
3851
|
+
}
|
|
3852
|
+
async pump() {
|
|
3853
|
+
const reader = new WsReader(this.incoming, this.max);
|
|
3854
|
+
try {
|
|
3855
|
+
for (; ; ) {
|
|
3856
|
+
const event = await reader.next(this.stop);
|
|
3857
|
+
if (!event) return;
|
|
3858
|
+
if (event.kind === "text") this.host.send(event.text);
|
|
3859
|
+
else if (event.kind === "ping") void this.send(pongFrame(event.payload));
|
|
3860
|
+
else {
|
|
3861
|
+
await this.end(event.code === 1005 ? CLOSE.normal : event.code, "");
|
|
3862
|
+
return;
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
} catch (e) {
|
|
3866
|
+
if (e instanceof WsError) await this.end(e.code, e.message);
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
};
|
|
3870
|
+
function enableCdp(net, hosts) {
|
|
3871
|
+
let facade;
|
|
3872
|
+
net.kernelOnly(CDP_PORT, true);
|
|
3873
|
+
net.activate({ family: "inet", host: "127.0.0.1", port: CDP_PORT }, () => {
|
|
3874
|
+
const started = new CdpFacade({ net, hosts });
|
|
3875
|
+
facade = started;
|
|
3876
|
+
void started.closed.then(() => {
|
|
3877
|
+
if (facade === started) facade = void 0;
|
|
3878
|
+
});
|
|
3879
|
+
});
|
|
3880
|
+
return () => facade;
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
// src/cdp/hosts.ts
|
|
3884
|
+
var CdpHosts = class {
|
|
3885
|
+
embedder;
|
|
3886
|
+
clients = [];
|
|
3887
|
+
closed = false;
|
|
3888
|
+
path = `/devtools/browser/${crypto.randomUUID()}`;
|
|
3889
|
+
url = `ws://127.0.0.1:${CDP_PORT}${this.path}`;
|
|
3890
|
+
constructor(hook) {
|
|
3891
|
+
this.embedder = hook ? { hook, runtime: void 0, open: /* @__PURE__ */ new Set() } : void 0;
|
|
3892
|
+
}
|
|
3893
|
+
register(hook, runtime) {
|
|
3894
|
+
const entry = { hook, runtime, open: /* @__PURE__ */ new Set() };
|
|
3895
|
+
this.clients.push(entry);
|
|
3896
|
+
return () => {
|
|
3897
|
+
const at = this.clients.indexOf(entry);
|
|
3898
|
+
if (at >= 0) this.clients.splice(at, 1);
|
|
3899
|
+
closeAll(entry);
|
|
3900
|
+
};
|
|
3901
|
+
}
|
|
3902
|
+
pick(runtime) {
|
|
3903
|
+
if (this.closed) return void 0;
|
|
3904
|
+
const named = runtime ? this.clients.findLast((c) => c.runtime === runtime) : void 0;
|
|
3905
|
+
return named ?? this.embedder ?? this.clients.at(-1);
|
|
3906
|
+
}
|
|
3907
|
+
available(runtime) {
|
|
3908
|
+
return this.pick(runtime) !== void 0;
|
|
3909
|
+
}
|
|
3910
|
+
async connect(request2) {
|
|
3911
|
+
const entry = this.pick(request2.runtime);
|
|
3912
|
+
if (!entry) throw new HttpError(503, NO_CDP_HOST);
|
|
3913
|
+
let conn;
|
|
3914
|
+
try {
|
|
3915
|
+
conn = await entry.hook(request2.runtime ? { runtime: request2.runtime } : {});
|
|
3916
|
+
} catch (e) {
|
|
3917
|
+
throw new HttpError(502, `CDP host: ${e instanceof Error ? e.message : String(e)}`);
|
|
3918
|
+
}
|
|
3919
|
+
if (this.closed || !(entry === this.embedder || this.clients.includes(entry))) {
|
|
3920
|
+
conn.close();
|
|
3921
|
+
throw new HttpError(503, NO_CDP_HOST);
|
|
3922
|
+
}
|
|
3923
|
+
entry.open.add(conn);
|
|
3924
|
+
const close = conn.close.bind(conn);
|
|
3925
|
+
conn.close = () => {
|
|
3926
|
+
if (entry.open.delete(conn)) close();
|
|
3927
|
+
};
|
|
3928
|
+
return conn;
|
|
3929
|
+
}
|
|
3930
|
+
close() {
|
|
3931
|
+
this.closed = true;
|
|
3932
|
+
for (const entry of [this.embedder, ...this.clients]) if (entry) closeAll(entry);
|
|
3933
|
+
}
|
|
3934
|
+
};
|
|
3935
|
+
function closeAll(entry) {
|
|
3936
|
+
for (const conn of [...entry.open]) {
|
|
3937
|
+
conn.close();
|
|
3938
|
+
conn.onclose?.("the CDP host is gone");
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
|
|
3391
3942
|
// src/commands.ts
|
|
3392
3943
|
var NAME = /^[A-Za-z0-9._+-]+$/;
|
|
3393
3944
|
var ENV_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
@@ -4711,7 +5262,7 @@ async function storageUsage() {
|
|
|
4711
5262
|
return { quota: estimate.quota, usage: estimate.usage ?? 0 };
|
|
4712
5263
|
}
|
|
4713
5264
|
var done = { ok: true, kind: "void" };
|
|
4714
|
-
function
|
|
5265
|
+
function json2(value) {
|
|
4715
5266
|
return { ok: true, kind: "json", json: value };
|
|
4716
5267
|
}
|
|
4717
5268
|
async function run(entry, path, req) {
|
|
@@ -4723,15 +5274,15 @@ async function run(entry, path, req) {
|
|
|
4723
5274
|
await fs.writeFile(path, req.body ?? new Uint8Array(0));
|
|
4724
5275
|
return done;
|
|
4725
5276
|
case "exists":
|
|
4726
|
-
return
|
|
5277
|
+
return json2(await fs.exists(path));
|
|
4727
5278
|
case "stat":
|
|
4728
|
-
return
|
|
5279
|
+
return json2(statJson(await fs.stat(path)));
|
|
4729
5280
|
case "lstat":
|
|
4730
|
-
return
|
|
5281
|
+
return json2(statJson(await fs.lstat(path)));
|
|
4731
5282
|
case "readdir":
|
|
4732
|
-
return
|
|
5283
|
+
return json2(await fs.readdir(path));
|
|
4733
5284
|
case "readdir-stat":
|
|
4734
|
-
return
|
|
5285
|
+
return json2(await readdirStat(fs, path));
|
|
4735
5286
|
case "mkdir":
|
|
4736
5287
|
await fs.mkdir(path, { recursive: true });
|
|
4737
5288
|
return done;
|
|
@@ -4757,7 +5308,7 @@ async function run(entry, path, req) {
|
|
|
4757
5308
|
await fs.symlink(req.arg2 ?? "", path);
|
|
4758
5309
|
return done;
|
|
4759
5310
|
case "readlink":
|
|
4760
|
-
return
|
|
5311
|
+
return json2(await fs.readlink(path));
|
|
4761
5312
|
case "chmod":
|
|
4762
5313
|
await fs.chmod(path, req.mode ?? 0);
|
|
4763
5314
|
return done;
|
|
@@ -4788,7 +5339,7 @@ async function dispatchSyncFs(req) {
|
|
|
4788
5339
|
const { fs, cwd } = entry;
|
|
4789
5340
|
try {
|
|
4790
5341
|
const path = fs.resolvePath(cwd, req.path);
|
|
4791
|
-
if (req.op === "statfs") return
|
|
5342
|
+
if (req.op === "statfs") return json2(await entry.statfs?.(path) ?? await storageUsage());
|
|
4792
5343
|
if (req.op === "hold") {
|
|
4793
5344
|
entry.hold?.(path, req.mode === 1);
|
|
4794
5345
|
return done;
|
|
@@ -4961,7 +5512,7 @@ var HOST_OPS = [
|
|
|
4961
5512
|
"async-cancel",
|
|
4962
5513
|
"async-close"
|
|
4963
5514
|
];
|
|
4964
|
-
var
|
|
5515
|
+
var json3 = (value) => ({ ok: true, kind: "json", json: value });
|
|
4965
5516
|
var done2 = { ok: true, kind: "void" };
|
|
4966
5517
|
var LockTable = class {
|
|
4967
5518
|
held = /* @__PURE__ */ new Map();
|
|
@@ -5010,7 +5561,7 @@ var AsyncOps = class {
|
|
|
5010
5561
|
}
|
|
5011
5562
|
resolve(value) {
|
|
5012
5563
|
const id = this.hold();
|
|
5013
|
-
this.complete(id,
|
|
5564
|
+
this.complete(id, json3(value));
|
|
5014
5565
|
return id;
|
|
5015
5566
|
}
|
|
5016
5567
|
hold() {
|
|
@@ -5092,15 +5643,15 @@ async function hostSyscall(req, ctx) {
|
|
|
5092
5643
|
return done2;
|
|
5093
5644
|
case "async-submit":
|
|
5094
5645
|
if (!ctx.valid(req.req)) throw new KernelError("EINVAL");
|
|
5095
|
-
return
|
|
5646
|
+
return json3(ctx.ops.submit(req.req));
|
|
5096
5647
|
case "async-wait":
|
|
5097
|
-
return
|
|
5648
|
+
return json3(await ctx.ops.wait(req.timeoutMs, ctx.blocking()));
|
|
5098
5649
|
case "async-take":
|
|
5099
5650
|
return ctx.ops.take(req.id);
|
|
5100
5651
|
case "async-resolve":
|
|
5101
|
-
return
|
|
5652
|
+
return json3(ctx.ops.resolve(req.value));
|
|
5102
5653
|
case "async-hold":
|
|
5103
|
-
return
|
|
5654
|
+
return json3(ctx.ops.hold());
|
|
5104
5655
|
case "async-cancel":
|
|
5105
5656
|
ctx.ops.cancel(req.id);
|
|
5106
5657
|
return done2;
|
|
@@ -5627,23 +6178,23 @@ function terminalOf(ctx, fd) {
|
|
|
5627
6178
|
if (!tty) throw new KernelError("ENOTTY");
|
|
5628
6179
|
return tty;
|
|
5629
6180
|
}
|
|
5630
|
-
var
|
|
6181
|
+
var json4 = (value) => ({ ok: true, kind: "json", json: value });
|
|
5631
6182
|
var done3 = { ok: true, kind: "void" };
|
|
5632
6183
|
function ptySyscall(req, ctx) {
|
|
5633
6184
|
switch (req.op) {
|
|
5634
6185
|
case "pty-open": {
|
|
5635
6186
|
if (!ctx.ptys) throw new KernelError("ENOENT");
|
|
5636
|
-
return
|
|
6187
|
+
return json4(ctx.fds.install(ctx.ptys.open().master, 3));
|
|
5637
6188
|
}
|
|
5638
6189
|
case "pty-slave-open": {
|
|
5639
6190
|
if (!ctx.ptys) throw new KernelError("ENOENT");
|
|
5640
6191
|
const pair = ctx.ptys.get(req.n);
|
|
5641
6192
|
const fd = ctx.fds.install(pair.openSlave(), 3);
|
|
5642
6193
|
if (!req.noctty) ctx.jobs?.acquireTerminal(ctx.pid, pair.slave);
|
|
5643
|
-
return
|
|
6194
|
+
return json4(fd);
|
|
5644
6195
|
}
|
|
5645
6196
|
case "pty-number":
|
|
5646
|
-
return
|
|
6197
|
+
return json4(masterOf(ctx, req.fd).index);
|
|
5647
6198
|
case "pty-lock":
|
|
5648
6199
|
masterOf(ctx, req.fd).locked = req.lock;
|
|
5649
6200
|
return done3;
|
|
@@ -5655,7 +6206,7 @@ function ptySyscall(req, ctx) {
|
|
|
5655
6206
|
return done3;
|
|
5656
6207
|
}
|
|
5657
6208
|
case "pty-list":
|
|
5658
|
-
return
|
|
6209
|
+
return json4(ctx.ptys?.numbers() ?? []);
|
|
5659
6210
|
case "pty-packet":
|
|
5660
6211
|
masterOf(ctx, req.fd).packet = req.on;
|
|
5661
6212
|
return done3;
|
|
@@ -5733,7 +6284,7 @@ function socketAt(fds, fd) {
|
|
|
5733
6284
|
if (!(file instanceof KernelSocket)) throw new KernelError("ENOTSOCK");
|
|
5734
6285
|
return file;
|
|
5735
6286
|
}
|
|
5736
|
-
var ok = (
|
|
6287
|
+
var ok = (json5) => json5 === void 0 ? { ok: true, kind: "void" } : { ok: true, kind: "json", json: json5 };
|
|
5737
6288
|
async function socketSyscall(req, proc) {
|
|
5738
6289
|
const { fds, net } = proc;
|
|
5739
6290
|
switch (req.op) {
|
|
@@ -7697,8 +8248,8 @@ function umountCall(target, flags) {
|
|
|
7697
8248
|
var FSTAB_PATH = "/etc/fstab";
|
|
7698
8249
|
var FSTAB_RETRIES = [1e3, 4e3, 16e3];
|
|
7699
8250
|
var FINAL = /* @__PURE__ */ new Set(["EINVAL", "EBUSY", "EPERM", "EACCES"]);
|
|
7700
|
-
function unescape(
|
|
7701
|
-
return
|
|
8251
|
+
function unescape(field2) {
|
|
8252
|
+
return field2.replace(
|
|
7702
8253
|
/\\([0-7]{3})/g,
|
|
7703
8254
|
(_, octal) => String.fromCharCode(Number.parseInt(octal, 8))
|
|
7704
8255
|
);
|
|
@@ -8346,7 +8897,7 @@ function importedMemory(bytes) {
|
|
|
8346
8897
|
const count = u32();
|
|
8347
8898
|
for (let i = 0; i < count; i++) {
|
|
8348
8899
|
const module = name2();
|
|
8349
|
-
const
|
|
8900
|
+
const field2 = name2();
|
|
8350
8901
|
const kind = bytes[at++];
|
|
8351
8902
|
if (kind === 0) u32();
|
|
8352
8903
|
else if (kind === 1) {
|
|
@@ -8354,7 +8905,7 @@ function importedMemory(bytes) {
|
|
|
8354
8905
|
limits();
|
|
8355
8906
|
} else if (kind === 2) {
|
|
8356
8907
|
const l = limits();
|
|
8357
|
-
return { module, name:
|
|
8908
|
+
return { module, name: field2, ...l };
|
|
8358
8909
|
} else if (kind === 3) at += 2;
|
|
8359
8910
|
else if (kind === 4) {
|
|
8360
8911
|
at++;
|
|
@@ -8445,12 +8996,12 @@ function readImports(r, types) {
|
|
|
8445
8996
|
const foreign = {};
|
|
8446
8997
|
for (let i = r.u32(); i > 0; i--) {
|
|
8447
8998
|
const module = r.name();
|
|
8448
|
-
const
|
|
8999
|
+
const field2 = r.name();
|
|
8449
9000
|
const kind = r.byte();
|
|
8450
9001
|
if (kind !== 0) skipImport(r, kind);
|
|
8451
9002
|
else {
|
|
8452
9003
|
const type = types[r.u32()] ?? "other";
|
|
8453
|
-
if (!RESERVED_NAMESPACES.has(module)) (foreign[module] ??= {})[
|
|
9004
|
+
if (!RESERVED_NAMESPACES.has(module)) (foreign[module] ??= {})[field2] = type;
|
|
8454
9005
|
}
|
|
8455
9006
|
}
|
|
8456
9007
|
return foreign;
|
|
@@ -8557,6 +9108,7 @@ var Launcher = class {
|
|
|
8557
9108
|
locks = new LockTable();
|
|
8558
9109
|
ptys = new PtyTable((tty, sig) => this.jobs.signalOwnedForeground(tty, sig));
|
|
8559
9110
|
net = new LoopbackNet();
|
|
9111
|
+
cdp;
|
|
8560
9112
|
ca;
|
|
8561
9113
|
transport;
|
|
8562
9114
|
watchers = new FsWatchers();
|
|
@@ -8593,7 +9145,8 @@ var Launcher = class {
|
|
|
8593
9145
|
this.processMounts = options.processMounts ?? true;
|
|
8594
9146
|
this.pnpmHome = options.env?.PNPM_HOME ?? PNPM_HOME;
|
|
8595
9147
|
this.modulesDir = options.modules ?? "/node_modules";
|
|
8596
|
-
this.
|
|
9148
|
+
this.cdp = new CdpHosts(options.cdp);
|
|
9149
|
+
this.env = { ...networkEnv(), SLICC_CDP_URL: this.cdp.url, ...options.env };
|
|
8597
9150
|
this.ca = kernelCa(options.caStore ?? memoryCaStore());
|
|
8598
9151
|
this.transport = options.transport ?? missingTransport();
|
|
8599
9152
|
enableNetwork(this.net, {
|
|
@@ -8601,6 +9154,7 @@ var Launcher = class {
|
|
|
8601
9154
|
engine: kernelTlsEngine(packageTlsEngine(options.fs, this.modulesDir)),
|
|
8602
9155
|
ca: this.ca
|
|
8603
9156
|
});
|
|
9157
|
+
enableCdp(this.net, this.cdp);
|
|
8604
9158
|
this.fs = withCommandDirs(this.base, async () => new Set((await this.commands()).keys()));
|
|
8605
9159
|
this.watchers.watch([this.modulesDir, this.pnpmHome], { recursive: true }, () => {
|
|
8606
9160
|
this.catalog = void 0;
|
|
@@ -9159,6 +9713,14 @@ async function stores(deps, name2, media) {
|
|
|
9159
9713
|
...handles === false ? {} : { media: await deps.media?.(handles) }
|
|
9160
9714
|
};
|
|
9161
9715
|
}
|
|
9716
|
+
function cdpOption(req, port) {
|
|
9717
|
+
if (!req.cdp) return {};
|
|
9718
|
+
return {
|
|
9719
|
+
cdp: portCdpHook(
|
|
9720
|
+
(request2, cdp) => port.postMessage({ cdpOpen: request2, port: cdp }, [cdp])
|
|
9721
|
+
)
|
|
9722
|
+
};
|
|
9723
|
+
}
|
|
9162
9724
|
function serveKernel(port, deps) {
|
|
9163
9725
|
let launcher;
|
|
9164
9726
|
let remote;
|
|
@@ -9230,6 +9792,7 @@ function serveKernel(port, deps) {
|
|
|
9230
9792
|
...media ? { media } : {},
|
|
9231
9793
|
onMountPending: (medium) => port.postMessage({ medium }),
|
|
9232
9794
|
...req.hostfs ? { hostfs: askGrant } : {},
|
|
9795
|
+
...cdpOption(req, port),
|
|
9233
9796
|
...mountPolicy(req.processMounts),
|
|
9234
9797
|
caStore: caStore(deps.metadata ? caDb(req) : false)
|
|
9235
9798
|
});
|