@ai-ecoverse/slicc-kernel 1.27.0 → 1.29.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 +41 -6
- package/dist/driver-worker.js +1 -1
- package/dist/driver-worker.js.map +1 -1
- package/dist/index.js +171 -16
- package/dist/index.js.map +4 -4
- package/dist/kernel-worker.js +442 -133
- 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 +7 -1
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +313 -41
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +7 -1
- package/dist/process-worker.js.map +2 -2
- package/dist/testing.js +196 -0
- package/dist/testing.js.map +3 -3
- package/package.json +3 -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, 7];
|
|
887
887
|
var FS_METHODS = [
|
|
888
888
|
"readFile",
|
|
889
889
|
"writeFile",
|
|
@@ -1253,6 +1253,170 @@ var FdTable = class _FdTable {
|
|
|
1253
1253
|
}
|
|
1254
1254
|
};
|
|
1255
1255
|
|
|
1256
|
+
// src/process/wasi/wasi-abi.ts
|
|
1257
|
+
var E = {
|
|
1258
|
+
SUCCESS: 0,
|
|
1259
|
+
"2BIG": 1,
|
|
1260
|
+
ACCES: 2,
|
|
1261
|
+
ADDRINUSE: 3,
|
|
1262
|
+
ADDRNOTAVAIL: 4,
|
|
1263
|
+
AFNOSUPPORT: 5,
|
|
1264
|
+
AGAIN: 6,
|
|
1265
|
+
ALREADY: 7,
|
|
1266
|
+
BADF: 8,
|
|
1267
|
+
BADMSG: 9,
|
|
1268
|
+
BUSY: 10,
|
|
1269
|
+
CANCELED: 11,
|
|
1270
|
+
CHILD: 12,
|
|
1271
|
+
CONNABORTED: 13,
|
|
1272
|
+
CONNREFUSED: 14,
|
|
1273
|
+
CONNRESET: 15,
|
|
1274
|
+
DEADLK: 16,
|
|
1275
|
+
DESTADDRREQ: 17,
|
|
1276
|
+
DOM: 18,
|
|
1277
|
+
DQUOT: 19,
|
|
1278
|
+
EXIST: 20,
|
|
1279
|
+
FAULT: 21,
|
|
1280
|
+
FBIG: 22,
|
|
1281
|
+
HOSTUNREACH: 23,
|
|
1282
|
+
IDRM: 24,
|
|
1283
|
+
ILSEQ: 25,
|
|
1284
|
+
INPROGRESS: 26,
|
|
1285
|
+
INTR: 27,
|
|
1286
|
+
INVAL: 28,
|
|
1287
|
+
IO: 29,
|
|
1288
|
+
ISCONN: 30,
|
|
1289
|
+
ISDIR: 31,
|
|
1290
|
+
LOOP: 32,
|
|
1291
|
+
MFILE: 33,
|
|
1292
|
+
MLINK: 34,
|
|
1293
|
+
MSGSIZE: 35,
|
|
1294
|
+
MULTIHOP: 36,
|
|
1295
|
+
NAMETOOLONG: 37,
|
|
1296
|
+
NETDOWN: 38,
|
|
1297
|
+
NETRESET: 39,
|
|
1298
|
+
NETUNREACH: 40,
|
|
1299
|
+
NFILE: 41,
|
|
1300
|
+
NOBUFS: 42,
|
|
1301
|
+
NODEV: 43,
|
|
1302
|
+
NOENT: 44,
|
|
1303
|
+
NOEXEC: 45,
|
|
1304
|
+
NOLCK: 46,
|
|
1305
|
+
NOLINK: 47,
|
|
1306
|
+
NOMEM: 48,
|
|
1307
|
+
NOMSG: 49,
|
|
1308
|
+
NOPROTOOPT: 50,
|
|
1309
|
+
NOSPC: 51,
|
|
1310
|
+
NOSYS: 52,
|
|
1311
|
+
NOTCONN: 53,
|
|
1312
|
+
NOTDIR: 54,
|
|
1313
|
+
NOTEMPTY: 55,
|
|
1314
|
+
NOTRECOVERABLE: 56,
|
|
1315
|
+
NOTSOCK: 57,
|
|
1316
|
+
NOTSUP: 58,
|
|
1317
|
+
NOTTY: 59,
|
|
1318
|
+
NXIO: 60,
|
|
1319
|
+
OVERFLOW: 61,
|
|
1320
|
+
OWNERDEAD: 62,
|
|
1321
|
+
PERM: 63,
|
|
1322
|
+
PIPE: 64,
|
|
1323
|
+
PROTO: 65,
|
|
1324
|
+
PROTONOSUPPORT: 66,
|
|
1325
|
+
PROTOTYPE: 67,
|
|
1326
|
+
RANGE: 68,
|
|
1327
|
+
ROFS: 69,
|
|
1328
|
+
SPIPE: 70,
|
|
1329
|
+
SRCH: 71,
|
|
1330
|
+
STALE: 72,
|
|
1331
|
+
TIMEDOUT: 73,
|
|
1332
|
+
TXTBSY: 74,
|
|
1333
|
+
XDEV: 75,
|
|
1334
|
+
NOTCAPABLE: 76
|
|
1335
|
+
};
|
|
1336
|
+
var RIGHTS = {
|
|
1337
|
+
FD_DATASYNC: 1n << 0n,
|
|
1338
|
+
FD_READ: 1n << 1n,
|
|
1339
|
+
FD_SEEK: 1n << 2n,
|
|
1340
|
+
FD_FDSTAT_SET_FLAGS: 1n << 3n,
|
|
1341
|
+
FD_SYNC: 1n << 4n,
|
|
1342
|
+
FD_TELL: 1n << 5n,
|
|
1343
|
+
FD_WRITE: 1n << 6n,
|
|
1344
|
+
ALL: (1n << 30n) - 1n
|
|
1345
|
+
};
|
|
1346
|
+
var WASI_SIGNAL_TO_POSIX = Object.fromEntries(
|
|
1347
|
+
Array.from({ length: 30 }, (_, i) => [i + 1, i + 1 < 16 ? i + 1 : i + 2])
|
|
1348
|
+
);
|
|
1349
|
+
|
|
1350
|
+
// src/process/wasi-errno.ts
|
|
1351
|
+
var WASI_ERRNO = {
|
|
1352
|
+
...Object.fromEntries(Object.entries(E).map(([name2, errno]) => [`E${name2}`, errno])),
|
|
1353
|
+
EWOULDBLOCK: E.AGAIN,
|
|
1354
|
+
ENOTSUP: 138,
|
|
1355
|
+
EOPNOTSUPP: 138,
|
|
1356
|
+
ENOMEDIUM: 148
|
|
1357
|
+
};
|
|
1358
|
+
function wasiErrno(code) {
|
|
1359
|
+
return WASI_ERRNO[code] ?? E.IO;
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
// src/kernel/net/uplink-socket.ts
|
|
1363
|
+
var CHUNK = 64 * 1024;
|
|
1364
|
+
function hostPort(text) {
|
|
1365
|
+
const match = /^\[?([^\]]*?)\]?:(\d{1,5})$/.exec(text);
|
|
1366
|
+
const port = Number(match?.[2]);
|
|
1367
|
+
const host = match?.[1];
|
|
1368
|
+
if (!host || port > 65535) return void 0;
|
|
1369
|
+
return { host, port };
|
|
1370
|
+
}
|
|
1371
|
+
async function inbound(conn, rx) {
|
|
1372
|
+
for (; ; ) {
|
|
1373
|
+
while (!rx.writeReady) await rx.changed();
|
|
1374
|
+
if (rx.readersGone) return;
|
|
1375
|
+
const bytes = await conn.read();
|
|
1376
|
+
if (!bytes) return;
|
|
1377
|
+
await rx.write(bytes);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
async function outbound(conn, tx) {
|
|
1381
|
+
for (; ; ) {
|
|
1382
|
+
const bytes = await tx.read(CHUNK);
|
|
1383
|
+
if (bytes.length === 0) {
|
|
1384
|
+
conn.closeWrite();
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
for (let at = 0; at < bytes.length; ) {
|
|
1388
|
+
const n = await conn.write(bytes.subarray(at));
|
|
1389
|
+
if (!(n > 0)) throw new Error("the uplink wrote nothing");
|
|
1390
|
+
at += n;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
async function released(rx, tx) {
|
|
1395
|
+
while (!(rx.readersGone && tx.writersGone)) await Promise.race([rx.changed(), tx.changed()]);
|
|
1396
|
+
}
|
|
1397
|
+
function uplinkLink(conn, onReset) {
|
|
1398
|
+
const rx = new KernelPipe();
|
|
1399
|
+
const tx = new KernelPipe();
|
|
1400
|
+
for (const pipe of [rx, tx]) {
|
|
1401
|
+
pipe.openRead();
|
|
1402
|
+
pipe.openWrite();
|
|
1403
|
+
}
|
|
1404
|
+
let open = true;
|
|
1405
|
+
const close = () => {
|
|
1406
|
+
if (!open) return;
|
|
1407
|
+
open = false;
|
|
1408
|
+
conn.close();
|
|
1409
|
+
};
|
|
1410
|
+
void inbound(conn, rx).catch(() => {
|
|
1411
|
+
onReset();
|
|
1412
|
+
close();
|
|
1413
|
+
tx.closeRead();
|
|
1414
|
+
}).finally(() => rx.closeWrite());
|
|
1415
|
+
void outbound(conn, tx).catch(close).finally(() => tx.closeRead());
|
|
1416
|
+
void released(rx, tx).then(close);
|
|
1417
|
+
return { rx, tx };
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1256
1420
|
// src/kernel/socket.ts
|
|
1257
1421
|
var SOMAXCONN = 4096;
|
|
1258
1422
|
var EPHEMERAL_FIRST = 32768;
|
|
@@ -1270,6 +1434,21 @@ var AF_INET = 2;
|
|
|
1270
1434
|
var SHUT_RD = 0;
|
|
1271
1435
|
var SHUT_WR = 1;
|
|
1272
1436
|
var SHUT_RDWR = 2;
|
|
1437
|
+
var DIAL_TIMEOUT_MS = 3e4;
|
|
1438
|
+
var DIAL_ERRORS = [
|
|
1439
|
+
"ECONNREFUSED",
|
|
1440
|
+
"ENETUNREACH",
|
|
1441
|
+
"EHOSTUNREACH",
|
|
1442
|
+
"ETIMEDOUT",
|
|
1443
|
+
"ECONNRESET"
|
|
1444
|
+
];
|
|
1445
|
+
function dialError(e, timedOut, closed) {
|
|
1446
|
+
if (timedOut) return new KernelError("ETIMEDOUT");
|
|
1447
|
+
if (closed) return new KernelError("ECONNABORTED");
|
|
1448
|
+
const code = e?.code;
|
|
1449
|
+
const known = DIAL_ERRORS.find((errno) => errno === code);
|
|
1450
|
+
return new KernelError(known ?? "EHOSTUNREACH");
|
|
1451
|
+
}
|
|
1273
1452
|
function isLoopback(host) {
|
|
1274
1453
|
return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
1275
1454
|
}
|
|
@@ -1318,6 +1497,9 @@ var KernelSocket = class _KernelSocket {
|
|
|
1318
1497
|
net;
|
|
1319
1498
|
domain;
|
|
1320
1499
|
state = "open";
|
|
1500
|
+
dialing;
|
|
1501
|
+
failed;
|
|
1502
|
+
reset = false;
|
|
1321
1503
|
local;
|
|
1322
1504
|
peer;
|
|
1323
1505
|
link;
|
|
@@ -1325,7 +1507,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
1325
1507
|
writeShut = false;
|
|
1326
1508
|
queue = [];
|
|
1327
1509
|
backlog = 0;
|
|
1328
|
-
|
|
1510
|
+
boundAt;
|
|
1329
1511
|
changes = new Changes();
|
|
1330
1512
|
options = /* @__PURE__ */ new Map();
|
|
1331
1513
|
constructor(net, domain) {
|
|
@@ -1347,12 +1529,16 @@ var KernelSocket = class _KernelSocket {
|
|
|
1347
1529
|
async read(max, signal) {
|
|
1348
1530
|
const { rx } = this.connection();
|
|
1349
1531
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1350
|
-
|
|
1532
|
+
const bytes = await pipeCall(() => rx.read(max, signal));
|
|
1533
|
+
if (bytes.length === 0 && this.reset) throw new KernelError("ECONNRESET");
|
|
1534
|
+
return bytes;
|
|
1351
1535
|
}
|
|
1352
1536
|
async peek(max, signal) {
|
|
1353
1537
|
const { rx } = this.connection();
|
|
1354
1538
|
if (this.readShut || max <= 0) return new Uint8Array(0);
|
|
1355
|
-
|
|
1539
|
+
const bytes = await pipeCall(() => rx.peek(max, signal));
|
|
1540
|
+
if (bytes.length === 0 && this.reset) throw new KernelError("ECONNRESET");
|
|
1541
|
+
return bytes;
|
|
1356
1542
|
}
|
|
1357
1543
|
async write(bytes, signal) {
|
|
1358
1544
|
const { tx } = this.connection();
|
|
@@ -1363,6 +1549,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1363
1549
|
if (this.state === "listening") {
|
|
1364
1550
|
return { readable: this.queue.length > 0, writable: false, hangup: false };
|
|
1365
1551
|
}
|
|
1552
|
+
if (this.state === "connecting") return { readable: false, writable: false, hangup: false };
|
|
1553
|
+
if (this.failed) return { readable: true, writable: true, hangup: true };
|
|
1366
1554
|
if (this.state !== "connected" || !this.link) {
|
|
1367
1555
|
return { readable: false, writable: false, hangup: true };
|
|
1368
1556
|
}
|
|
@@ -1384,7 +1572,7 @@ var KernelSocket = class _KernelSocket {
|
|
|
1384
1572
|
if (this.state !== "open" || this.local) throw new KernelError("EINVAL");
|
|
1385
1573
|
if (addr.family !== this.domain) throw new KernelError("EAFNOSUPPORT");
|
|
1386
1574
|
this.local = this.net.bind(this, addr);
|
|
1387
|
-
this.
|
|
1575
|
+
this.boundAt = this.local;
|
|
1388
1576
|
}
|
|
1389
1577
|
listen(backlog) {
|
|
1390
1578
|
if (this.state === "connected") throw new KernelError("EISCONN");
|
|
@@ -1411,15 +1599,19 @@ var KernelSocket = class _KernelSocket {
|
|
|
1411
1599
|
this.changes.wake();
|
|
1412
1600
|
return true;
|
|
1413
1601
|
}
|
|
1414
|
-
connect(addr) {
|
|
1602
|
+
connect(addr, viaUplink = true) {
|
|
1415
1603
|
if (this.state === "connected") throw new KernelError("EISCONN");
|
|
1604
|
+
if (this.state === "connecting") throw new KernelError("EALREADY");
|
|
1416
1605
|
if (this.state !== "open") throw new KernelError("EINVAL");
|
|
1417
1606
|
if (addr.family !== this.domain) throw new KernelError("EAFNOSUPPORT");
|
|
1607
|
+
this.failed = void 0;
|
|
1608
|
+
const route = viaUplink && addr.family === "inet" ? this.net.uplinkFor(addr.host) : void 0;
|
|
1609
|
+
if (route) return this.dial(addr, route);
|
|
1418
1610
|
const target = this.net.target(addr);
|
|
1419
1611
|
if (!this.local) {
|
|
1420
1612
|
if (addr.family === "inet") {
|
|
1421
1613
|
this.local = this.net.bind(this, { family: "inet", host: "127.0.0.1", port: 0 });
|
|
1422
|
-
this.
|
|
1614
|
+
this.boundAt = this.local;
|
|
1423
1615
|
} else this.local = { family: "unix", path: "" };
|
|
1424
1616
|
}
|
|
1425
1617
|
const server = new _KernelSocket(this.net, this.domain);
|
|
@@ -1432,6 +1624,52 @@ var KernelSocket = class _KernelSocket {
|
|
|
1432
1624
|
server.close();
|
|
1433
1625
|
throw new KernelError("ECONNREFUSED");
|
|
1434
1626
|
}
|
|
1627
|
+
return void 0;
|
|
1628
|
+
}
|
|
1629
|
+
dial(addr, route) {
|
|
1630
|
+
this.state = "connecting";
|
|
1631
|
+
const abort = new AbortController();
|
|
1632
|
+
this.dialing = abort;
|
|
1633
|
+
let timedOut = false;
|
|
1634
|
+
const timer = setTimeout(() => {
|
|
1635
|
+
timedOut = true;
|
|
1636
|
+
abort.abort(new KernelError("ETIMEDOUT"));
|
|
1637
|
+
}, route.timeoutMs ?? DIAL_TIMEOUT_MS);
|
|
1638
|
+
const abandoned = new Promise((_, reject) => {
|
|
1639
|
+
abort.signal.addEventListener("abort", () => reject(abort.signal.reason), { once: true });
|
|
1640
|
+
});
|
|
1641
|
+
const { host, port } = addr;
|
|
1642
|
+
const dialled = new Promise(
|
|
1643
|
+
(resolve) => resolve(route.uplink.dial({ network: "tcp", host, port, signal: abort.signal }))
|
|
1644
|
+
);
|
|
1645
|
+
dialled.then(
|
|
1646
|
+
(conn) => abort.signal.aborted && conn.close(),
|
|
1647
|
+
() => void 0
|
|
1648
|
+
);
|
|
1649
|
+
return Promise.race([dialled, abandoned]).then(
|
|
1650
|
+
(conn) => {
|
|
1651
|
+
if (abort.signal.aborted) throw dialError(abort.signal.reason, timedOut, true);
|
|
1652
|
+
this.local = { family: "inet", host: "0.0.0.0", port: 0, ...hostPort(conn.localAddr) };
|
|
1653
|
+
this.peer = { ...addr, ...hostPort(conn.remoteAddr) };
|
|
1654
|
+
this.dialing = void 0;
|
|
1655
|
+
this.attach(
|
|
1656
|
+
uplinkLink(conn, () => {
|
|
1657
|
+
this.reset = true;
|
|
1658
|
+
this.changes.wake();
|
|
1659
|
+
})
|
|
1660
|
+
);
|
|
1661
|
+
},
|
|
1662
|
+
(e) => {
|
|
1663
|
+
const error = dialError(e, timedOut, abort.signal.aborted);
|
|
1664
|
+
if (this.dialing === abort) {
|
|
1665
|
+
this.dialing = void 0;
|
|
1666
|
+
this.failed = error.code;
|
|
1667
|
+
this.state = "open";
|
|
1668
|
+
this.changes.wake();
|
|
1669
|
+
}
|
|
1670
|
+
throw error;
|
|
1671
|
+
}
|
|
1672
|
+
).finally(() => clearTimeout(timer));
|
|
1435
1673
|
}
|
|
1436
1674
|
unlink() {
|
|
1437
1675
|
const link2 = this.link;
|
|
@@ -1461,8 +1699,11 @@ var KernelSocket = class _KernelSocket {
|
|
|
1461
1699
|
switch (name2) {
|
|
1462
1700
|
case SO_TYPE:
|
|
1463
1701
|
return SOCK_STREAM;
|
|
1464
|
-
case SO_ERROR:
|
|
1465
|
-
|
|
1702
|
+
case SO_ERROR: {
|
|
1703
|
+
const failed = this.failed;
|
|
1704
|
+
this.failed = void 0;
|
|
1705
|
+
return failed ? wasiErrno(failed) : 0;
|
|
1706
|
+
}
|
|
1466
1707
|
case SO_ACCEPTCONN:
|
|
1467
1708
|
return this.state === "listening" ? 1 : 0;
|
|
1468
1709
|
case SO_DOMAIN:
|
|
@@ -1480,6 +1721,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1480
1721
|
close() {
|
|
1481
1722
|
const was = this.state;
|
|
1482
1723
|
this.state = "closed";
|
|
1724
|
+
this.dialing?.abort(new KernelError("ECONNABORTED"));
|
|
1725
|
+
this.dialing = void 0;
|
|
1483
1726
|
if (was === "listening") {
|
|
1484
1727
|
for (const pending of this.queue.splice(0)) pending.close();
|
|
1485
1728
|
}
|
|
@@ -1489,8 +1732,8 @@ var KernelSocket = class _KernelSocket {
|
|
|
1489
1732
|
this.readShut = true;
|
|
1490
1733
|
this.writeShut = true;
|
|
1491
1734
|
}
|
|
1492
|
-
if (this.
|
|
1493
|
-
this.
|
|
1735
|
+
if (this.boundAt) this.net.release(this.boundAt, this);
|
|
1736
|
+
this.boundAt = void 0;
|
|
1494
1737
|
this.changes.wake();
|
|
1495
1738
|
}
|
|
1496
1739
|
static pair(net, domain) {
|
|
@@ -1513,6 +1756,15 @@ var LoopbackNet = class {
|
|
|
1513
1756
|
activators = /* @__PURE__ */ new Map();
|
|
1514
1757
|
internal = /* @__PURE__ */ new Set();
|
|
1515
1758
|
nextEphemeral = EPHEMERAL_FIRST;
|
|
1759
|
+
route;
|
|
1760
|
+
useUplink(route) {
|
|
1761
|
+
this.route = route;
|
|
1762
|
+
}
|
|
1763
|
+
uplinkFor(host) {
|
|
1764
|
+
const route = this.route;
|
|
1765
|
+
if (!route) return void 0;
|
|
1766
|
+
return route.routes.classify(host) === "uplink" ? route : void 0;
|
|
1767
|
+
}
|
|
1516
1768
|
kernelOnly(port, reserve = false) {
|
|
1517
1769
|
if (reserve) this.internal.add(port);
|
|
1518
1770
|
return this.internal.has(port);
|
|
@@ -1531,7 +1783,7 @@ var LoopbackNet = class {
|
|
|
1531
1783
|
}
|
|
1532
1784
|
connect(addr) {
|
|
1533
1785
|
const socket = this.socket(addr.family);
|
|
1534
|
-
socket.connect(addr);
|
|
1786
|
+
void socket.connect(addr, false);
|
|
1535
1787
|
return socket;
|
|
1536
1788
|
}
|
|
1537
1789
|
bind(socket, addr) {
|
|
@@ -1572,7 +1824,7 @@ var LoopbackNet = class {
|
|
|
1572
1824
|
};
|
|
1573
1825
|
|
|
1574
1826
|
// src/kernel/dial.ts
|
|
1575
|
-
var
|
|
1827
|
+
var CHUNK2 = 64 * 1024;
|
|
1576
1828
|
var LOOPBACK_NAMES = /* @__PURE__ */ new Set(["127.0.0.1", "localhost", "::1", "[::1]"]);
|
|
1577
1829
|
function dialSocket(net, port, host = "127.0.0.1") {
|
|
1578
1830
|
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new KernelError("EINVAL");
|
|
@@ -1637,7 +1889,7 @@ function serveSocket(socket, port, onClose) {
|
|
|
1637
1889
|
for (; ; ) {
|
|
1638
1890
|
await turn();
|
|
1639
1891
|
if (closed) return;
|
|
1640
|
-
const chunk2 = await socket.read(
|
|
1892
|
+
const chunk2 = await socket.read(CHUNK2);
|
|
1641
1893
|
if (chunk2.length === 0) break;
|
|
1642
1894
|
credit--;
|
|
1643
1895
|
send(chunk2, [chunk2.buffer]);
|
|
@@ -3570,6 +3822,95 @@ var RemoteTransport = class {
|
|
|
3570
3822
|
}
|
|
3571
3823
|
};
|
|
3572
3824
|
|
|
3825
|
+
// src/kernel/net/routes.ts
|
|
3826
|
+
var HOST_ADDRESS = HOST_LOOPBACK_ADDRESS.join(".");
|
|
3827
|
+
function ipv4Bytes(text) {
|
|
3828
|
+
const parts = text.split(".");
|
|
3829
|
+
if (parts.length !== 4 || !parts.every((p) => /^\d{1,3}$/.test(p))) return void 0;
|
|
3830
|
+
const bytes = parts.map(Number);
|
|
3831
|
+
return bytes.every((b) => b <= 255) ? bytes : void 0;
|
|
3832
|
+
}
|
|
3833
|
+
function ipv6Groups(text) {
|
|
3834
|
+
if (!text.includes(":")) return void 0;
|
|
3835
|
+
let canonical;
|
|
3836
|
+
try {
|
|
3837
|
+
canonical = new URL(`http://[${text}]/`).hostname.slice(1, -1);
|
|
3838
|
+
} catch {
|
|
3839
|
+
return void 0;
|
|
3840
|
+
}
|
|
3841
|
+
const [head, tail] = canonical.split("::");
|
|
3842
|
+
const part = (s) => s ? s.split(":").map((h) => Number.parseInt(h, 16)) : [];
|
|
3843
|
+
const front = part(head);
|
|
3844
|
+
const back = part(tail);
|
|
3845
|
+
return tail === void 0 ? front : [...front, ...new Array(8 - front.length - back.length).fill(0), ...back];
|
|
3846
|
+
}
|
|
3847
|
+
function toBits(values, width) {
|
|
3848
|
+
return values.reduce((acc, v) => acc << BigInt(width) | BigInt(v), 0n);
|
|
3849
|
+
}
|
|
3850
|
+
function addressBits(host) {
|
|
3851
|
+
const v4 = ipv4Bytes(host);
|
|
3852
|
+
if (v4) return { v6: false, bits: toBits(v4, 8) };
|
|
3853
|
+
const v6 = ipv6Groups(host);
|
|
3854
|
+
return v6 ? { v6: true, bits: toBits(v6, 16) } : void 0;
|
|
3855
|
+
}
|
|
3856
|
+
function parsePrefix(text) {
|
|
3857
|
+
const parts = text.trim().split("/");
|
|
3858
|
+
if (parts.length > 2) return void 0;
|
|
3859
|
+
const [address = "", size] = parts;
|
|
3860
|
+
const parsed = addressBits(address);
|
|
3861
|
+
if (!parsed) return void 0;
|
|
3862
|
+
const max = parsed.v6 ? 128 : 32;
|
|
3863
|
+
const length2 = size === void 0 ? max : /^\d{1,3}$/.test(size) ? Number(size) : -1;
|
|
3864
|
+
if (length2 < 0 || length2 > max) return void 0;
|
|
3865
|
+
return { ...parsed, length: length2 };
|
|
3866
|
+
}
|
|
3867
|
+
function within2(prefix, addr) {
|
|
3868
|
+
if (prefix.v6 !== addr.v6) return false;
|
|
3869
|
+
const shift = BigInt((prefix.v6 ? 128 : 32) - prefix.length);
|
|
3870
|
+
return addr.bits >> shift === prefix.bits >> shift;
|
|
3871
|
+
}
|
|
3872
|
+
var RESERVED = [
|
|
3873
|
+
"0.0.0.0/8",
|
|
3874
|
+
"127.0.0.0/8",
|
|
3875
|
+
"169.254.0.0/16",
|
|
3876
|
+
"224.0.0.0/4",
|
|
3877
|
+
"240.0.0.0/4",
|
|
3878
|
+
"::/96",
|
|
3879
|
+
"::ffff:0:0/96",
|
|
3880
|
+
"fe80::/10",
|
|
3881
|
+
"ff00::/8"
|
|
3882
|
+
].map((p) => parsePrefix(p));
|
|
3883
|
+
var Routes = class {
|
|
3884
|
+
table = [];
|
|
3885
|
+
exit = false;
|
|
3886
|
+
ipv6;
|
|
3887
|
+
constructor(ipv62 = false) {
|
|
3888
|
+
this.ipv6 = ipv62;
|
|
3889
|
+
}
|
|
3890
|
+
set(table) {
|
|
3891
|
+
const parsed = (table.prefixes ?? []).map(parsePrefix);
|
|
3892
|
+
const bad = (table.prefixes ?? []).find((_, i) => !parsed[i]);
|
|
3893
|
+
if (bad !== void 0) throw new Error(`not an address prefix: ${bad}`);
|
|
3894
|
+
this.table = parsed;
|
|
3895
|
+
this.exit = table.exit === true;
|
|
3896
|
+
}
|
|
3897
|
+
classify(host) {
|
|
3898
|
+
const name2 = host.toLowerCase().replace(/\.$/, "");
|
|
3899
|
+
if (name2 === "localhost" || name2.endsWith(".localhost") || name2 === "0.0.0.0") {
|
|
3900
|
+
return "loopback";
|
|
3901
|
+
}
|
|
3902
|
+
if (name2 === HOST_LOOPBACK || name2 === HOST_ADDRESS) return "host";
|
|
3903
|
+
const addr = addressBits(name2);
|
|
3904
|
+
if (!addr) return "unreachable";
|
|
3905
|
+
if (addr.v6 && addr.bits === 1n) return "loopback";
|
|
3906
|
+
if (!addr.v6 && addr.bits >> 24n === 127n) return "loopback";
|
|
3907
|
+
if (RESERVED.some((p) => within2(p, addr))) return "reserved";
|
|
3908
|
+
if (addr.v6 && !this.ipv6) return "unreachable";
|
|
3909
|
+
if (this.exit || this.table.some((p) => within2(p, addr))) return "uplink";
|
|
3910
|
+
return "unreachable";
|
|
3911
|
+
}
|
|
3912
|
+
};
|
|
3913
|
+
|
|
3573
3914
|
// src/kernel/net/uplink.ts
|
|
3574
3915
|
function answerOf(result) {
|
|
3575
3916
|
const answer = Array.isArray(result) ? { addresses: result } : result;
|
|
@@ -3579,6 +3920,7 @@ function answerOf(result) {
|
|
|
3579
3920
|
...typeof answer?.ttl === "number" && answer.ttl >= 0 ? { ttl: answer.ttl } : {}
|
|
3580
3921
|
};
|
|
3581
3922
|
}
|
|
3923
|
+
var NEVER = new Routes(true);
|
|
3582
3924
|
var RemoteUplink = class {
|
|
3583
3925
|
traits;
|
|
3584
3926
|
routes;
|
|
@@ -3596,23 +3938,60 @@ var RemoteUplink = class {
|
|
|
3596
3938
|
this.waiting.delete(reply.uid);
|
|
3597
3939
|
if (reply.uplink === "error") {
|
|
3598
3940
|
waiter.reject(Object.assign(new Error(reply.message), { code: reply.code }));
|
|
3599
|
-
} else waiter.resolve(
|
|
3941
|
+
} else waiter.resolve(reply);
|
|
3600
3942
|
}
|
|
3601
|
-
|
|
3602
|
-
const uid = ++this.nextId;
|
|
3943
|
+
ask(call, signal, transfer) {
|
|
3603
3944
|
const waiter = Promise.withResolvers();
|
|
3604
|
-
this.waiting.set(uid, waiter);
|
|
3945
|
+
this.waiting.set(call.uid, waiter);
|
|
3605
3946
|
const abort = () => {
|
|
3606
|
-
this.waiting.delete(uid);
|
|
3607
|
-
this.port.postMessage({ uplink: "cancel", uid });
|
|
3947
|
+
this.waiting.delete(call.uid);
|
|
3948
|
+
this.port.postMessage({ uplink: "cancel", uid: call.uid });
|
|
3608
3949
|
waiter.reject(signal?.reason);
|
|
3609
3950
|
};
|
|
3610
3951
|
signal?.addEventListener("abort", abort, { once: true });
|
|
3611
3952
|
const settled = () => signal?.removeEventListener("abort", abort);
|
|
3612
3953
|
waiter.promise.then(settled, settled);
|
|
3613
|
-
this.port.postMessage(
|
|
3954
|
+
this.port.postMessage(call, transfer);
|
|
3614
3955
|
return waiter.promise;
|
|
3615
3956
|
}
|
|
3957
|
+
async resolve(name2, family, signal) {
|
|
3958
|
+
const reply = await this.ask(
|
|
3959
|
+
{ uplink: "resolve", uid: ++this.nextId, name: name2, family },
|
|
3960
|
+
signal
|
|
3961
|
+
);
|
|
3962
|
+
return answerOf(reply);
|
|
3963
|
+
}
|
|
3964
|
+
async dial(req) {
|
|
3965
|
+
req.signal.throwIfAborted();
|
|
3966
|
+
const { host, port } = req;
|
|
3967
|
+
const opened2 = await this.ask(
|
|
3968
|
+
{ uplink: "dial", uid: ++this.nextId, host, port },
|
|
3969
|
+
req.signal
|
|
3970
|
+
);
|
|
3971
|
+
const { cid, localAddr, remoteAddr } = opened2;
|
|
3972
|
+
return {
|
|
3973
|
+
localAddr,
|
|
3974
|
+
remoteAddr,
|
|
3975
|
+
read: async () => {
|
|
3976
|
+
const got = await this.ask({
|
|
3977
|
+
uplink: "read",
|
|
3978
|
+
uid: ++this.nextId,
|
|
3979
|
+
cid
|
|
3980
|
+
});
|
|
3981
|
+
return got.bytes;
|
|
3982
|
+
},
|
|
3983
|
+
write: async (bytes) => {
|
|
3984
|
+
const copy = bytes.slice();
|
|
3985
|
+
const call = { uplink: "write", uid: ++this.nextId, cid, bytes: copy };
|
|
3986
|
+
const done4 = await this.ask(call, void 0, [
|
|
3987
|
+
copy.buffer
|
|
3988
|
+
]);
|
|
3989
|
+
return done4.n;
|
|
3990
|
+
},
|
|
3991
|
+
closeWrite: () => this.port.postMessage({ uplink: "close-write", cid }),
|
|
3992
|
+
close: () => this.port.postMessage({ uplink: "close", cid })
|
|
3993
|
+
};
|
|
3994
|
+
}
|
|
3616
3995
|
};
|
|
3617
3996
|
|
|
3618
3997
|
// src/cdp/types.ts
|
|
@@ -4148,6 +4527,7 @@ function commandOf(pkg, name2, raw, packageAbi, shared) {
|
|
|
4148
4527
|
glue,
|
|
4149
4528
|
wasm,
|
|
4150
4529
|
argv0,
|
|
4530
|
+
...raw.argv0Path === true ? { argv0Path: true } : {},
|
|
4151
4531
|
...args ? { args } : {},
|
|
4152
4532
|
...withEnv,
|
|
4153
4533
|
...imports ? { imports } : {}
|
|
@@ -4747,9 +5127,9 @@ function parseSize(text) {
|
|
|
4747
5127
|
if (!match) throw errnoError("EINVAL", `not a size: ${text}`);
|
|
4748
5128
|
return Math.floor(Number(match[1]) * UNITS[match[2].toLowerCase()]);
|
|
4749
5129
|
}
|
|
4750
|
-
var
|
|
5130
|
+
var within3 = (path, target) => path === target || target === "/" || path.startsWith(`${target}/`);
|
|
4751
5131
|
function heldUnder(held, target) {
|
|
4752
|
-
for (const paths of held) for (const path of paths.keys()) if (
|
|
5132
|
+
for (const paths of held) for (const path of paths.keys()) if (within3(path, target)) return true;
|
|
4753
5133
|
return false;
|
|
4754
5134
|
}
|
|
4755
5135
|
var HeldPaths = class extends Map {
|
|
@@ -4763,11 +5143,11 @@ var HeldPaths = class extends Map {
|
|
|
4763
5143
|
}
|
|
4764
5144
|
}
|
|
4765
5145
|
revoke(prefix) {
|
|
4766
|
-
for (const path of this.keys()) if (
|
|
5146
|
+
for (const path of this.keys()) if (within3(path, prefix)) this.revoked.add(path);
|
|
4767
5147
|
}
|
|
4768
5148
|
renamed(from, to) {
|
|
4769
5149
|
for (const [path, count] of [...this]) {
|
|
4770
|
-
if (!
|
|
5150
|
+
if (!within3(path, from)) continue;
|
|
4771
5151
|
const moved2 = to + path.slice(from.length);
|
|
4772
5152
|
this.delete(path);
|
|
4773
5153
|
this.set(moved2, (this.get(moved2) ?? 0) + count);
|
|
@@ -4865,7 +5245,7 @@ var MountTable = class {
|
|
|
4865
5245
|
locate(path) {
|
|
4866
5246
|
let best;
|
|
4867
5247
|
for (const mount of this.mounts.values()) {
|
|
4868
|
-
if (
|
|
5248
|
+
if (within3(path, mount.target) && (!best || mount.target.length > best.target.length))
|
|
4869
5249
|
best = mount;
|
|
4870
5250
|
}
|
|
4871
5251
|
if (!best) return void 0;
|
|
@@ -4977,10 +5357,10 @@ var MountTable = class {
|
|
|
4977
5357
|
this.deps.changed?.(...full);
|
|
4978
5358
|
}
|
|
4979
5359
|
forget(mount, path) {
|
|
4980
|
-
for (const key of [...mount.attrs.keys()]) if (
|
|
5360
|
+
for (const key of [...mount.attrs.keys()]) if (within3(key, path)) mount.attrs.delete(key);
|
|
4981
5361
|
mount.lists.delete(path);
|
|
4982
5362
|
mount.lists.delete(parentOf4(path));
|
|
4983
|
-
for (const key of [...mount.lists.keys()]) if (
|
|
5363
|
+
for (const key of [...mount.lists.keys()]) if (within3(key, path)) mount.lists.delete(key);
|
|
4984
5364
|
}
|
|
4985
5365
|
async getattr(mount, path, rel2) {
|
|
4986
5366
|
if (mount.conn.failure) throw mount.conn.failure;
|
|
@@ -5943,95 +6323,6 @@ var HttpHandles = class {
|
|
|
5943
6323
|
}
|
|
5944
6324
|
};
|
|
5945
6325
|
|
|
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
6326
|
// src/kernel/net/resolver.ts
|
|
6036
6327
|
var RESOLVE_TTL_MAX = 60;
|
|
6037
6328
|
var RESOLVE_TIMEOUT_MS = 1e4;
|
|
@@ -6676,10 +6967,15 @@ async function socketSyscall(req, proc) {
|
|
|
6676
6967
|
return ok();
|
|
6677
6968
|
case "sock-accept":
|
|
6678
6969
|
return ok(await accept(proc, req.fd, req.nonblock));
|
|
6679
|
-
case "sock-connect":
|
|
6680
|
-
socketAt(fds, req.fd).connect(req.addr);
|
|
6681
|
-
if (req.nonblock)
|
|
6970
|
+
case "sock-connect": {
|
|
6971
|
+
const dialing = socketAt(fds, req.fd).connect(req.addr);
|
|
6972
|
+
if (req.nonblock) {
|
|
6973
|
+
dialing?.catch(() => void 0);
|
|
6974
|
+
throw new KernelError("EINPROGRESS");
|
|
6975
|
+
}
|
|
6976
|
+
if (dialing !== void 0) await interruptible(dialing, proc.blocking());
|
|
6682
6977
|
return ok();
|
|
6978
|
+
}
|
|
6683
6979
|
case "sock-shutdown":
|
|
6684
6980
|
socketAt(fds, req.fd).shutdown(req.how);
|
|
6685
6981
|
return ok();
|
|
@@ -6701,6 +6997,13 @@ async function socketSyscall(req, proc) {
|
|
|
6701
6997
|
}
|
|
6702
6998
|
}
|
|
6703
6999
|
}
|
|
7000
|
+
function interruptible(dialing, signal) {
|
|
7001
|
+
return new Promise((resolve, reject) => {
|
|
7002
|
+
const abort = () => reject(new KernelError("EINTR"));
|
|
7003
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
7004
|
+
dialing.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
7005
|
+
});
|
|
7006
|
+
}
|
|
6704
7007
|
function unnamed(domain) {
|
|
6705
7008
|
return domain === "inet" ? { family: "inet", host: "0.0.0.0", port: 0 } : { family: "unix", path: "" };
|
|
6706
7009
|
}
|
|
@@ -9121,7 +9424,7 @@ async function openHostfs(spec, hook, fetch2, timing = {}) {
|
|
|
9121
9424
|
}
|
|
9122
9425
|
|
|
9123
9426
|
// src/mount/chunked.ts
|
|
9124
|
-
var
|
|
9427
|
+
var CHUNK3 = 1024 * 1024;
|
|
9125
9428
|
var ChunkedBytes = class {
|
|
9126
9429
|
chunks = [];
|
|
9127
9430
|
size = 0;
|
|
@@ -9130,9 +9433,9 @@ var ChunkedBytes = class {
|
|
|
9130
9433
|
if (end <= offset) return new Uint8Array(0);
|
|
9131
9434
|
const out = new Uint8Array(end - offset);
|
|
9132
9435
|
for (let at = offset; at < end; ) {
|
|
9133
|
-
const index = Math.floor(at /
|
|
9134
|
-
const from = at - index *
|
|
9135
|
-
const n = Math.min(
|
|
9436
|
+
const index = Math.floor(at / CHUNK3);
|
|
9437
|
+
const from = at - index * CHUNK3;
|
|
9438
|
+
const n = Math.min(CHUNK3 - from, end - at);
|
|
9136
9439
|
const chunk2 = this.chunks[index];
|
|
9137
9440
|
if (chunk2) out.set(chunk2.subarray(from, Math.min(from + n, chunk2.length)), at - offset);
|
|
9138
9441
|
at += n;
|
|
@@ -9143,10 +9446,10 @@ var ChunkedBytes = class {
|
|
|
9143
9446
|
const whole = owned && bytes.byteOffset === 0 && bytes.byteLength === bytes.buffer.byteLength;
|
|
9144
9447
|
for (let done4 = 0; done4 < bytes.length; ) {
|
|
9145
9448
|
const at = offset + done4;
|
|
9146
|
-
const index = Math.floor(at /
|
|
9147
|
-
const from = at - index *
|
|
9148
|
-
const n = Math.min(
|
|
9149
|
-
if (whole && n ===
|
|
9449
|
+
const index = Math.floor(at / CHUNK3);
|
|
9450
|
+
const from = at - index * CHUNK3;
|
|
9451
|
+
const n = Math.min(CHUNK3 - from, bytes.length - done4);
|
|
9452
|
+
if (whole && n === CHUNK3 && bytes.length === CHUNK3) this.chunks[index] = bytes;
|
|
9150
9453
|
else this.room(index, from + n).set(bytes.subarray(done4, done4 + n), from);
|
|
9151
9454
|
done4 += n;
|
|
9152
9455
|
}
|
|
@@ -9154,10 +9457,10 @@ var ChunkedBytes = class {
|
|
|
9154
9457
|
}
|
|
9155
9458
|
truncate(size) {
|
|
9156
9459
|
if (size < this.size) {
|
|
9157
|
-
const keep = Math.ceil(size /
|
|
9460
|
+
const keep = Math.ceil(size / CHUNK3);
|
|
9158
9461
|
this.chunks.length = Math.min(this.chunks.length, keep);
|
|
9159
9462
|
const tail = this.chunks[keep - 1];
|
|
9160
|
-
const from = size - (keep - 1) *
|
|
9463
|
+
const from = size - (keep - 1) * CHUNK3;
|
|
9161
9464
|
if (tail && from < tail.length) tail.fill(0, from);
|
|
9162
9465
|
}
|
|
9163
9466
|
this.size = size;
|
|
@@ -9165,7 +9468,7 @@ var ChunkedBytes = class {
|
|
|
9165
9468
|
room(index, need) {
|
|
9166
9469
|
const chunk2 = this.chunks[index];
|
|
9167
9470
|
if (chunk2 && chunk2.length >= need) return chunk2;
|
|
9168
|
-
const grown = new Uint8Array(Math.min(
|
|
9471
|
+
const grown = new Uint8Array(Math.min(CHUNK3, Math.max(need, (chunk2?.length ?? 0) * 2)));
|
|
9169
9472
|
if (chunk2) grown.set(chunk2);
|
|
9170
9473
|
this.chunks[index] = grown;
|
|
9171
9474
|
return grown;
|
|
@@ -9625,6 +9928,7 @@ var Launcher = class {
|
|
|
9625
9928
|
this.routes = new Routes(options.uplink?.traits.ipv6 === true);
|
|
9626
9929
|
if (options.uplink?.routes) this.routes.set(options.uplink.routes);
|
|
9627
9930
|
this.resolver = new Resolver({ uplink: options.uplink, routes: this.routes });
|
|
9931
|
+
if (options.uplink) this.net.useUplink({ uplink: options.uplink, routes: this.routes });
|
|
9628
9932
|
enableNetwork(this.net, {
|
|
9629
9933
|
transport: this.transport,
|
|
9630
9934
|
engine: kernelTlsEngine(packageTlsEngine(options.fs, this.modulesDir)),
|
|
@@ -9655,9 +9959,14 @@ var Launcher = class {
|
|
|
9655
9959
|
const command = (await this.commands()).get(name2);
|
|
9656
9960
|
return command && !command.script ? targetOf(command) : void 0;
|
|
9657
9961
|
}
|
|
9658
|
-
const
|
|
9962
|
+
const path = this.fs.resolvePath(cwd, file);
|
|
9963
|
+
const glue = await followLinks(this.base, path);
|
|
9659
9964
|
const linked = COMMAND2.exec(glue)?.[1];
|
|
9660
|
-
if (linked !== void 0)
|
|
9965
|
+
if (linked !== void 0) {
|
|
9966
|
+
const target = await this.resolve(`/bin/${linked}`, argv0, cwd);
|
|
9967
|
+
const byPath = !COMMAND2.test(path) && (await this.commands()).get(linked)?.argv0Path === true;
|
|
9968
|
+
return target && byPath ? { ...target, argv0: path } : target;
|
|
9969
|
+
}
|
|
9661
9970
|
const head = await this.head(glue);
|
|
9662
9971
|
if (!head) return void 0;
|
|
9663
9972
|
if (isWasm(head)) {
|