@poe-platform/safe-bash 0.1.683 → 0.1.684
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 +10 -0
- package/dist/safe-bash/chunks/chunk-4MPK7VIM.js +519 -0
- package/dist/safe-bash/chunks/chunk-4MPK7VIM.js.map +7 -0
- package/dist/safe-bash/chunks/{chunk-6R7IR2MV.js → chunk-BONY6MX5.js} +731 -15
- package/dist/safe-bash/chunks/chunk-BONY6MX5.js.map +7 -0
- package/dist/safe-bash/commands/python/index.browser.js +12 -2
- package/dist/safe-bash/commands/python/index.d.ts +5 -0
- package/dist/safe-bash/commands/python/index.d.ts.map +1 -1
- package/dist/safe-bash/commands/python/index.js +15 -3
- package/dist/safe-bash/commands/python/index.js.map +1 -1
- package/dist/safe-bash/commands/python/jspi-assets.d.ts +14 -0
- package/dist/safe-bash/commands/python/jspi-assets.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/jspi-assets.js +51 -0
- package/dist/safe-bash/commands/python/jspi-assets.js.map +1 -0
- package/dist/safe-bash/commands/python/jspi-scheduler.d.ts +8 -0
- package/dist/safe-bash/commands/python/jspi-scheduler.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/jspi-scheduler.js +49 -0
- package/dist/safe-bash/commands/python/jspi-scheduler.js.map +1 -0
- package/dist/safe-bash/commands/python/jspi-trampoline.d.ts +5 -0
- package/dist/safe-bash/commands/python/jspi-trampoline.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/jspi-trampoline.js +90 -0
- package/dist/safe-bash/commands/python/jspi-trampoline.js.map +1 -0
- package/dist/safe-bash/commands/python/jspi.d.ts +22 -0
- package/dist/safe-bash/commands/python/jspi.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/jspi.js +295 -0
- package/dist/safe-bash/commands/python/jspi.js.map +1 -0
- package/dist/safe-bash/commands/python/runtime-scripts.d.ts +6 -0
- package/dist/safe-bash/commands/python/runtime-scripts.d.ts.map +1 -0
- package/dist/safe-bash/commands/python/runtime-scripts.js +168 -0
- package/dist/safe-bash/commands/python/runtime-scripts.js.map +1 -0
- package/dist/safe-bash/commands/python/worker.browser.js +13 -368
- package/dist/safe-bash/commands/python/worker.browser.js.map +3 -3
- package/dist/safe-bash/commands/python/worker.d.ts.map +1 -1
- package/dist/safe-bash/commands/python/worker.js +6 -168
- package/dist/safe-bash/commands/python/worker.js.map +1 -1
- package/dist/safe-bash/core.browser.js +12 -2
- package/dist/safe-bash/core.browser.js.map +1 -1
- package/package.json +2 -2
- package/dist/safe-bash/chunks/chunk-3G3EZZ63.js +0 -145
- package/dist/safe-bash/chunks/chunk-3G3EZZ63.js.map +0 -7
- package/dist/safe-bash/chunks/chunk-6R7IR2MV.js.map +0 -7
|
@@ -6,8 +6,14 @@ import {
|
|
|
6
6
|
PythonInvocationError,
|
|
7
7
|
isPythonFailureCategory,
|
|
8
8
|
parsePythonInvocation,
|
|
9
|
+
pythonDirectoryEntries,
|
|
10
|
+
pythonExecution,
|
|
11
|
+
pythonImportMetadata,
|
|
12
|
+
pythonRuntimeRelocation,
|
|
13
|
+
pythonStatProjection,
|
|
14
|
+
pythonTreeCleanup,
|
|
9
15
|
reportPythonFailure
|
|
10
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4MPK7VIM.js";
|
|
11
17
|
import {
|
|
12
18
|
createOutputOperation
|
|
13
19
|
} from "./chunk-ZDYA3SLF.js";
|
|
@@ -44,21 +50,21 @@ function encodePythonReply(value, maxBytes) {
|
|
|
44
50
|
used += bytes;
|
|
45
51
|
if (used > maxBytes) throw new FsError("EFBIG", { syscall: "python reply" });
|
|
46
52
|
};
|
|
47
|
-
const string = (
|
|
48
|
-
if (
|
|
53
|
+
const string = (text2) => {
|
|
54
|
+
if (text2.length + 2 > maxBytes - used) throw new FsError("EFBIG", { syscall: "python reply" });
|
|
49
55
|
reserve(2);
|
|
50
|
-
for (let index = 0; index <
|
|
51
|
-
const code =
|
|
56
|
+
for (let index = 0; index < text2.length; index++) {
|
|
57
|
+
const code = text2.charCodeAt(index);
|
|
52
58
|
if (code < 32) reserve([8, 9, 10, 12, 13].includes(code) ? 2 : 6);
|
|
53
59
|
else if (code === 34 || code === 92) reserve(2);
|
|
54
60
|
else if (code < 128) reserve(1);
|
|
55
61
|
else if (code < 2048) reserve(2);
|
|
56
|
-
else if (code >= 55296 && code <= 56319 &&
|
|
62
|
+
else if (code >= 55296 && code <= 56319 && text2.charCodeAt(index + 1) >= 56320 && text2.charCodeAt(index + 1) <= 57343) {
|
|
57
63
|
reserve(4);
|
|
58
64
|
index++;
|
|
59
65
|
} else reserve(code >= 55296 && code <= 57343 ? 6 : 3);
|
|
60
66
|
}
|
|
61
|
-
return
|
|
67
|
+
return text2;
|
|
62
68
|
};
|
|
63
69
|
const own = (input, depth) => {
|
|
64
70
|
if (depth > 64) throw new FsError("EFBIG", { syscall: "python reply" });
|
|
@@ -1131,10 +1137,10 @@ function createPythonPackageEnvironment(options = {}) {
|
|
|
1131
1137
|
}
|
|
1132
1138
|
for (const line of source.split("\n")) {
|
|
1133
1139
|
const comment = line.split("").findIndex((character, index) => character === "#" && (index === 0 || line[index - 1].trim() === ""));
|
|
1134
|
-
const
|
|
1135
|
-
if (!
|
|
1136
|
-
if (
|
|
1137
|
-
requirements.push(normalizeRequirement(
|
|
1140
|
+
const text2 = (comment < 0 ? line : line.slice(0, comment)).trim();
|
|
1141
|
+
if (!text2) continue;
|
|
1142
|
+
if (text2.endsWith("\\") || text2.startsWith("-")) throw failure(`Unsupported requirements option or continuation in ${path}: ${text2}`);
|
|
1143
|
+
requirements.push(normalizeRequirement(text2, dirname(path)));
|
|
1138
1144
|
}
|
|
1139
1145
|
}
|
|
1140
1146
|
context.signal.throwIfAborted();
|
|
@@ -1424,6 +1430,706 @@ function createPythonExecutorPool(options) {
|
|
|
1424
1430
|
};
|
|
1425
1431
|
}
|
|
1426
1432
|
|
|
1433
|
+
// packages/safe-bash/src/commands/python/jspi.ts
|
|
1434
|
+
init_platform();
|
|
1435
|
+
import { createPythonNativeSyscalls } from "@poe-platform/safe-fs/core";
|
|
1436
|
+
|
|
1437
|
+
// packages/safe-bash/src/commands/python/jspi-trampoline.ts
|
|
1438
|
+
init_platform();
|
|
1439
|
+
var pythonJspiSignatures = Object.freeze({
|
|
1440
|
+
__syscall_chdir: "ip",
|
|
1441
|
+
__syscall_chmod: "ipi",
|
|
1442
|
+
__syscall_dup: "ii",
|
|
1443
|
+
__syscall_faccessat: "iipii",
|
|
1444
|
+
__syscall_fcntl64: "iiip",
|
|
1445
|
+
__syscall_fdatasync: "ii",
|
|
1446
|
+
__syscall_fstat64: "iip",
|
|
1447
|
+
__syscall_ftruncate64: "iij",
|
|
1448
|
+
__syscall_getcwd: "ipp",
|
|
1449
|
+
__syscall_getdents64: "iipp",
|
|
1450
|
+
__syscall_ioctl: "iiip",
|
|
1451
|
+
__syscall_lstat64: "ipp",
|
|
1452
|
+
__syscall_mkdirat: "iipi",
|
|
1453
|
+
__syscall_newfstatat: "iippi",
|
|
1454
|
+
__syscall_openat: "iipip",
|
|
1455
|
+
__syscall_readlinkat: "iippp",
|
|
1456
|
+
__syscall_renameat: "iipip",
|
|
1457
|
+
__syscall_rmdir: "ip",
|
|
1458
|
+
__syscall_stat64: "ipp",
|
|
1459
|
+
__syscall_symlinkat: "ipip",
|
|
1460
|
+
__syscall_truncate64: "ipj",
|
|
1461
|
+
__syscall_unlinkat: "iipi",
|
|
1462
|
+
__syscall_utimensat: "iippi",
|
|
1463
|
+
fd_close: "ii",
|
|
1464
|
+
fd_fdstat_get: "iip",
|
|
1465
|
+
fd_pread: "iippjp",
|
|
1466
|
+
fd_pwrite: "iippjp",
|
|
1467
|
+
fd_read: "iippp",
|
|
1468
|
+
fd_seek: "iijip",
|
|
1469
|
+
fd_sync: "ii",
|
|
1470
|
+
fd_write: "iippp"
|
|
1471
|
+
});
|
|
1472
|
+
var unsigned = (value) => {
|
|
1473
|
+
const bytes = [];
|
|
1474
|
+
do {
|
|
1475
|
+
bytes.push(value & 127 | (value > 127 ? 128 : 0));
|
|
1476
|
+
value >>>= 7;
|
|
1477
|
+
} while (value);
|
|
1478
|
+
return bytes;
|
|
1479
|
+
};
|
|
1480
|
+
var vector = (entries) => [...unsigned(entries.length), ...entries.flat()];
|
|
1481
|
+
var text = (value) => {
|
|
1482
|
+
const bytes = new TextEncoder().encode(value);
|
|
1483
|
+
return [...unsigned(bytes.length), ...bytes];
|
|
1484
|
+
};
|
|
1485
|
+
var section = (type, bytes) => [type, ...unsigned(bytes.length), ...bytes];
|
|
1486
|
+
var signature = (parameters, result) => [96, ...vector(parameters.map((type) => [type])), ...result === void 0 ? [0] : [1, result]];
|
|
1487
|
+
function createPythonJspiTrampoline() {
|
|
1488
|
+
const entries = Object.entries(pythonJspiSignatures);
|
|
1489
|
+
const types = entries.flatMap(([, value]) => {
|
|
1490
|
+
const parameters = [...value.slice(1)].map((type) => type === "j" ? 126 : 127);
|
|
1491
|
+
return [signature(parameters, 127), signature(parameters, 111)];
|
|
1492
|
+
});
|
|
1493
|
+
types.push(signature([111], 127));
|
|
1494
|
+
const imports = entries.flatMap(([name], index) => [
|
|
1495
|
+
[...text("original"), ...text(name), 0, ...unsigned(index * 2)],
|
|
1496
|
+
[...text("request"), ...text(name), 0, ...unsigned(index * 2 + 1)],
|
|
1497
|
+
[...text("shutdown"), ...text(name), 0, ...unsigned(index * 2)]
|
|
1498
|
+
]);
|
|
1499
|
+
imports.push([...text("control"), ...text("syncify"), 1, 112, 0, 1]);
|
|
1500
|
+
imports.push([...text("control"), ...text("active"), 3, 127, 1]);
|
|
1501
|
+
const functions = entries.map(([, value], index) => {
|
|
1502
|
+
const argumentsBytes = [...value.slice(1)].flatMap((_type, parameter) => [32, ...unsigned(parameter)]);
|
|
1503
|
+
const code = [
|
|
1504
|
+
0,
|
|
1505
|
+
35,
|
|
1506
|
+
0,
|
|
1507
|
+
4,
|
|
1508
|
+
127,
|
|
1509
|
+
35,
|
|
1510
|
+
0,
|
|
1511
|
+
65,
|
|
1512
|
+
2,
|
|
1513
|
+
70,
|
|
1514
|
+
4,
|
|
1515
|
+
127,
|
|
1516
|
+
...argumentsBytes,
|
|
1517
|
+
16,
|
|
1518
|
+
...unsigned(index * 3 + 2),
|
|
1519
|
+
5,
|
|
1520
|
+
...argumentsBytes,
|
|
1521
|
+
16,
|
|
1522
|
+
...unsigned(index * 3 + 1),
|
|
1523
|
+
65,
|
|
1524
|
+
0,
|
|
1525
|
+
17,
|
|
1526
|
+
...unsigned(entries.length * 2),
|
|
1527
|
+
0,
|
|
1528
|
+
11,
|
|
1529
|
+
5,
|
|
1530
|
+
...argumentsBytes,
|
|
1531
|
+
16,
|
|
1532
|
+
...unsigned(index * 3),
|
|
1533
|
+
11,
|
|
1534
|
+
11
|
|
1535
|
+
];
|
|
1536
|
+
return [...unsigned(code.length), ...code];
|
|
1537
|
+
});
|
|
1538
|
+
return new Uint8Array([
|
|
1539
|
+
0,
|
|
1540
|
+
97,
|
|
1541
|
+
115,
|
|
1542
|
+
109,
|
|
1543
|
+
1,
|
|
1544
|
+
0,
|
|
1545
|
+
0,
|
|
1546
|
+
0,
|
|
1547
|
+
...section(1, vector(types)),
|
|
1548
|
+
...section(2, vector(imports)),
|
|
1549
|
+
...section(3, vector(entries.map((_entry, index) => unsigned(index * 2)))),
|
|
1550
|
+
...section(7, vector(entries.map(([name], index) => [...text(name), 0, ...unsigned(entries.length * 3 + index)]))),
|
|
1551
|
+
...section(10, vector(functions))
|
|
1552
|
+
]);
|
|
1553
|
+
}
|
|
1554
|
+
function createPythonJspiNativeCall() {
|
|
1555
|
+
const types = [
|
|
1556
|
+
signature([127], 127),
|
|
1557
|
+
signature([127]),
|
|
1558
|
+
signature([127], 111),
|
|
1559
|
+
signature([111], 127),
|
|
1560
|
+
signature([127, 127], 127),
|
|
1561
|
+
signature([], 127)
|
|
1562
|
+
];
|
|
1563
|
+
const imports = [
|
|
1564
|
+
["python", "utf8", 0],
|
|
1565
|
+
["python", "unicode", 0],
|
|
1566
|
+
["python", "free", 1],
|
|
1567
|
+
["python", "noMemory", 5],
|
|
1568
|
+
["request", "send", 2],
|
|
1569
|
+
["shutdown", "send", 0]
|
|
1570
|
+
];
|
|
1571
|
+
const code = [
|
|
1572
|
+
1,
|
|
1573
|
+
2,
|
|
1574
|
+
127,
|
|
1575
|
+
32,
|
|
1576
|
+
1,
|
|
1577
|
+
16,
|
|
1578
|
+
0,
|
|
1579
|
+
34,
|
|
1580
|
+
2,
|
|
1581
|
+
69,
|
|
1582
|
+
4,
|
|
1583
|
+
127,
|
|
1584
|
+
65,
|
|
1585
|
+
0,
|
|
1586
|
+
5,
|
|
1587
|
+
35,
|
|
1588
|
+
0,
|
|
1589
|
+
65,
|
|
1590
|
+
2,
|
|
1591
|
+
70,
|
|
1592
|
+
4,
|
|
1593
|
+
127,
|
|
1594
|
+
32,
|
|
1595
|
+
2,
|
|
1596
|
+
16,
|
|
1597
|
+
5,
|
|
1598
|
+
5,
|
|
1599
|
+
32,
|
|
1600
|
+
2,
|
|
1601
|
+
16,
|
|
1602
|
+
4,
|
|
1603
|
+
65,
|
|
1604
|
+
0,
|
|
1605
|
+
17,
|
|
1606
|
+
3,
|
|
1607
|
+
0,
|
|
1608
|
+
11,
|
|
1609
|
+
34,
|
|
1610
|
+
2,
|
|
1611
|
+
69,
|
|
1612
|
+
4,
|
|
1613
|
+
127,
|
|
1614
|
+
16,
|
|
1615
|
+
3,
|
|
1616
|
+
5,
|
|
1617
|
+
32,
|
|
1618
|
+
2,
|
|
1619
|
+
16,
|
|
1620
|
+
1,
|
|
1621
|
+
33,
|
|
1622
|
+
3,
|
|
1623
|
+
32,
|
|
1624
|
+
2,
|
|
1625
|
+
16,
|
|
1626
|
+
2,
|
|
1627
|
+
32,
|
|
1628
|
+
3,
|
|
1629
|
+
11,
|
|
1630
|
+
11,
|
|
1631
|
+
11
|
|
1632
|
+
];
|
|
1633
|
+
return new Uint8Array([
|
|
1634
|
+
0,
|
|
1635
|
+
97,
|
|
1636
|
+
115,
|
|
1637
|
+
109,
|
|
1638
|
+
1,
|
|
1639
|
+
0,
|
|
1640
|
+
0,
|
|
1641
|
+
0,
|
|
1642
|
+
...section(1, vector(types)),
|
|
1643
|
+
...section(2, vector([
|
|
1644
|
+
...imports.map(([namespace, name, type]) => [...text(namespace), ...text(name), 0, type]),
|
|
1645
|
+
[...text("control"), ...text("syncify"), 1, 112, 0, 1],
|
|
1646
|
+
[...text("control"), ...text("active"), 3, 127, 1]
|
|
1647
|
+
])),
|
|
1648
|
+
...section(3, vector([[4]])),
|
|
1649
|
+
...section(7, vector([[...text("call"), 0, 6]])),
|
|
1650
|
+
...section(10, vector([[...unsigned(code.length), ...code]]))
|
|
1651
|
+
]);
|
|
1652
|
+
}
|
|
1653
|
+
function createPythonJspiStatResult() {
|
|
1654
|
+
const types = [
|
|
1655
|
+
signature([127], 127),
|
|
1656
|
+
signature([127]),
|
|
1657
|
+
signature([127, 127], 127),
|
|
1658
|
+
signature([127, 127, 127]),
|
|
1659
|
+
signature([], 127)
|
|
1660
|
+
];
|
|
1661
|
+
const imports = [["create", 0], ["size", 0], ["item", 2], ["retain", 1], ["set", 3], ["invalid", 4]];
|
|
1662
|
+
const code = [
|
|
1663
|
+
1,
|
|
1664
|
+
3,
|
|
1665
|
+
127,
|
|
1666
|
+
32,
|
|
1667
|
+
1,
|
|
1668
|
+
16,
|
|
1669
|
+
1,
|
|
1670
|
+
35,
|
|
1671
|
+
0,
|
|
1672
|
+
71,
|
|
1673
|
+
4,
|
|
1674
|
+
64,
|
|
1675
|
+
16,
|
|
1676
|
+
5,
|
|
1677
|
+
15,
|
|
1678
|
+
11,
|
|
1679
|
+
32,
|
|
1680
|
+
0,
|
|
1681
|
+
16,
|
|
1682
|
+
0,
|
|
1683
|
+
34,
|
|
1684
|
+
2,
|
|
1685
|
+
69,
|
|
1686
|
+
4,
|
|
1687
|
+
127,
|
|
1688
|
+
65,
|
|
1689
|
+
0,
|
|
1690
|
+
5,
|
|
1691
|
+
2,
|
|
1692
|
+
64,
|
|
1693
|
+
3,
|
|
1694
|
+
64,
|
|
1695
|
+
32,
|
|
1696
|
+
3,
|
|
1697
|
+
35,
|
|
1698
|
+
0,
|
|
1699
|
+
79,
|
|
1700
|
+
13,
|
|
1701
|
+
1,
|
|
1702
|
+
32,
|
|
1703
|
+
1,
|
|
1704
|
+
32,
|
|
1705
|
+
3,
|
|
1706
|
+
16,
|
|
1707
|
+
2,
|
|
1708
|
+
34,
|
|
1709
|
+
4,
|
|
1710
|
+
16,
|
|
1711
|
+
3,
|
|
1712
|
+
32,
|
|
1713
|
+
2,
|
|
1714
|
+
32,
|
|
1715
|
+
3,
|
|
1716
|
+
32,
|
|
1717
|
+
4,
|
|
1718
|
+
16,
|
|
1719
|
+
4,
|
|
1720
|
+
32,
|
|
1721
|
+
3,
|
|
1722
|
+
65,
|
|
1723
|
+
1,
|
|
1724
|
+
106,
|
|
1725
|
+
33,
|
|
1726
|
+
3,
|
|
1727
|
+
12,
|
|
1728
|
+
0,
|
|
1729
|
+
11,
|
|
1730
|
+
11,
|
|
1731
|
+
32,
|
|
1732
|
+
2,
|
|
1733
|
+
11,
|
|
1734
|
+
11
|
|
1735
|
+
];
|
|
1736
|
+
return new Uint8Array([
|
|
1737
|
+
0,
|
|
1738
|
+
97,
|
|
1739
|
+
115,
|
|
1740
|
+
109,
|
|
1741
|
+
1,
|
|
1742
|
+
0,
|
|
1743
|
+
0,
|
|
1744
|
+
0,
|
|
1745
|
+
...section(1, vector(types)),
|
|
1746
|
+
...section(2, vector([
|
|
1747
|
+
...imports.map(([name, type]) => [...text("python"), ...text(name), 0, type]),
|
|
1748
|
+
[...text("python"), ...text("fields"), 3, 127, 0]
|
|
1749
|
+
])),
|
|
1750
|
+
...section(3, vector([[2]])),
|
|
1751
|
+
...section(7, vector([[...text("construct"), 0, 6]])),
|
|
1752
|
+
...section(10, vector([[...unsigned(code.length), ...code]]))
|
|
1753
|
+
]);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
// packages/safe-bash/src/commands/python/jspi-scheduler.ts
|
|
1757
|
+
init_platform();
|
|
1758
|
+
function createPythonJspiScheduler() {
|
|
1759
|
+
const queued = /* @__PURE__ */ new Map();
|
|
1760
|
+
const active = /* @__PURE__ */ new Set();
|
|
1761
|
+
const failures = [];
|
|
1762
|
+
let closed = false;
|
|
1763
|
+
let retirement;
|
|
1764
|
+
return {
|
|
1765
|
+
scheduleCallback(callback, delay = 0) {
|
|
1766
|
+
if (closed) {
|
|
1767
|
+
callback.destroy?.();
|
|
1768
|
+
throw new Error("Python scheduler is closed");
|
|
1769
|
+
}
|
|
1770
|
+
const timer = setTimeout(() => {
|
|
1771
|
+
queued.delete(timer);
|
|
1772
|
+
const work = Promise.resolve().then(() => callback()).then(() => {
|
|
1773
|
+
}, (error) => {
|
|
1774
|
+
failures.push(error);
|
|
1775
|
+
}).finally(() => {
|
|
1776
|
+
active.delete(work);
|
|
1777
|
+
});
|
|
1778
|
+
active.add(work);
|
|
1779
|
+
}, delay);
|
|
1780
|
+
queued.set(timer, callback);
|
|
1781
|
+
},
|
|
1782
|
+
close() {
|
|
1783
|
+
if (retirement) return retirement;
|
|
1784
|
+
if (!active.size) closed = true;
|
|
1785
|
+
retirement = Promise.resolve().then(async () => {
|
|
1786
|
+
while (active.size) await Promise.all(active);
|
|
1787
|
+
closed = true;
|
|
1788
|
+
for (const [timer, callback] of queued) {
|
|
1789
|
+
clearTimeout(timer);
|
|
1790
|
+
try {
|
|
1791
|
+
callback.destroy?.();
|
|
1792
|
+
} catch (error) {
|
|
1793
|
+
failures.push(error);
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
queued.clear();
|
|
1797
|
+
if (failures.length === 1) throw failures[0];
|
|
1798
|
+
if (failures.length) throw new AggregateError(failures, "Python callback retirement failed");
|
|
1799
|
+
});
|
|
1800
|
+
return retirement;
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1804
|
+
|
|
1805
|
+
// packages/safe-bash/src/commands/python/jspi.ts
|
|
1806
|
+
function createPythonJspiExecutor(options) {
|
|
1807
|
+
const engine = globalThis.WebAssembly;
|
|
1808
|
+
const active = new engine.Global({ value: "i32", mutable: true }, 0);
|
|
1809
|
+
const syncify = new engine.Table({ element: "anyfunc", initial: 1 });
|
|
1810
|
+
const controller = new AbortController();
|
|
1811
|
+
const scheduler = createPythonJspiScheduler();
|
|
1812
|
+
let admitted = false;
|
|
1813
|
+
let running;
|
|
1814
|
+
let retirement;
|
|
1815
|
+
let cleanup;
|
|
1816
|
+
let runtime;
|
|
1817
|
+
let native;
|
|
1818
|
+
let instanceBound = false;
|
|
1819
|
+
let importsBound = false;
|
|
1820
|
+
let schedulerBound = false;
|
|
1821
|
+
let methodDefinition = 0;
|
|
1822
|
+
let methodPointer;
|
|
1823
|
+
let statPointer;
|
|
1824
|
+
const originals = {};
|
|
1825
|
+
const execute = async (start) => {
|
|
1826
|
+
const signal = AbortSignal.any([start.signal, controller.signal]);
|
|
1827
|
+
const configuration = parsePythonInvocation(start.invocation.args, start.invocation.env);
|
|
1828
|
+
let qualified = false;
|
|
1829
|
+
let exitCode = 0;
|
|
1830
|
+
let finalized = 0;
|
|
1831
|
+
try {
|
|
1832
|
+
signal.throwIfAborted();
|
|
1833
|
+
if (start.packages?.requirements.length || start.installOnly) throw new PythonFailure("runtime-assets", { cause: new Error("JSPI runtime requires statically qualified packages") });
|
|
1834
|
+
runtime = await options.loadRuntime({
|
|
1835
|
+
jsglobals: /* @__PURE__ */ Object.create(null),
|
|
1836
|
+
args: configuration.startupArgs,
|
|
1837
|
+
env: configuration.env,
|
|
1838
|
+
bindImports(imports) {
|
|
1839
|
+
if (importsBound) throw new PythonFailure("runtime-abi");
|
|
1840
|
+
const namespaces = [...new Set(Object.values(imports))];
|
|
1841
|
+
for (const namespace of namespaces) {
|
|
1842
|
+
for (const [name, value] of Object.entries(namespace)) {
|
|
1843
|
+
if (typeof value !== "function") continue;
|
|
1844
|
+
if (name in pythonJspiSignatures) originals[name] = value;
|
|
1845
|
+
else if (name.startsWith("__syscall_") || name === "_maybe_connect_async") namespace[name] = () => -52;
|
|
1846
|
+
else if (name === "_emscripten_system") namespace[name] = (command) => command === 0 ? 0 : -52;
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
if (!originals.fd_read || !originals.fd_write || !originals.__syscall_openat) throw new PythonFailure("runtime-abi");
|
|
1850
|
+
const original = Object.fromEntries(Object.keys(pythonJspiSignatures).map((name) => [name, originals[name] ?? (() => -52)]));
|
|
1851
|
+
const request = Object.fromEntries(Object.keys(pythonJspiSignatures).map((name) => [
|
|
1852
|
+
name,
|
|
1853
|
+
(...args) => native.invoke(name, args)
|
|
1854
|
+
]));
|
|
1855
|
+
const shutdown = Object.fromEntries(Object.entries(request).map(([name, dispatch]) => [name, new engine.Suspending(dispatch)]));
|
|
1856
|
+
const bridge = new engine.Instance(options.trampoline, { original, request, shutdown, control: { active, syncify } });
|
|
1857
|
+
for (const namespace of namespaces) for (const name of Object.keys(originals)) {
|
|
1858
|
+
if (typeof namespace[name] === "function") namespace[name] = bridge.exports[name];
|
|
1859
|
+
}
|
|
1860
|
+
importsBound = true;
|
|
1861
|
+
},
|
|
1862
|
+
bindInstance(instance) {
|
|
1863
|
+
if (instanceBound || !importsBound || typeof instance.exports.syscall_syncify !== "function") throw new PythonFailure("runtime-abi");
|
|
1864
|
+
syncify.set(0, instance.exports.syscall_syncify);
|
|
1865
|
+
instanceBound = true;
|
|
1866
|
+
},
|
|
1867
|
+
bindScheduler(api) {
|
|
1868
|
+
if (schedulerBound) throw new PythonFailure("runtime-abi");
|
|
1869
|
+
api.scheduleCallback = scheduler.scheduleCallback;
|
|
1870
|
+
schedulerBound = true;
|
|
1871
|
+
}
|
|
1872
|
+
});
|
|
1873
|
+
if (!importsBound || !instanceBound || !schedulerBound || runtime.version !== "314.0.6" || !runtime._module.jspiSupported) throw new PythonFailure("runtime-abi");
|
|
1874
|
+
qualified = true;
|
|
1875
|
+
signal.throwIfAborted();
|
|
1876
|
+
runtime.runPython("import sys, os, json, runpy, traceback, types, warnings, textwrap, io, struct, linecache, importlib.machinery, shutil, stat, pyodide.ffi");
|
|
1877
|
+
runtime.globals.set("_safe_runtime_mount", start.runtimeMount);
|
|
1878
|
+
const filesystem = runtime.FS;
|
|
1879
|
+
const bootstrap = filesystem.root;
|
|
1880
|
+
filesystem.root = null;
|
|
1881
|
+
filesystem.mount(filesystem.filesystems.MEMFS, {}, "/");
|
|
1882
|
+
filesystem.mkdir(start.runtimeMount);
|
|
1883
|
+
filesystem.mount({ mount: () => bootstrap }, {}, start.runtimeMount);
|
|
1884
|
+
runtime.runPython(pythonRuntimeRelocation);
|
|
1885
|
+
filesystem.currentPath = start.invocation.cwd;
|
|
1886
|
+
native = createPythonNativeSyscalls({
|
|
1887
|
+
runtime: runtime._module,
|
|
1888
|
+
cwd: start.invocation.cwd,
|
|
1889
|
+
runtimeMount: start.runtimeMount,
|
|
1890
|
+
maxTransferBytes: start.maxTransferBytes,
|
|
1891
|
+
signal,
|
|
1892
|
+
dispatch: start.dispatch,
|
|
1893
|
+
original: (name, args) => originals[name](...args)
|
|
1894
|
+
});
|
|
1895
|
+
const errno = JSON.parse(runtime.runPython("__import__('json').dumps({name:value for name,value in vars(__import__('errno')).items() if name.startswith('E') and isinstance(value,int)})"));
|
|
1896
|
+
const encode = async (operation) => {
|
|
1897
|
+
try {
|
|
1898
|
+
return JSON.stringify(await operation());
|
|
1899
|
+
} catch (error) {
|
|
1900
|
+
return JSON.stringify({ errno: signal.aborted ? errno.EINTR : error.errno ?? errno[error.code ?? ""] ?? errno.EIO });
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
const absolute = (path) => path.startsWith("/") ? path : filesystem.cwd() + "/" + path;
|
|
1904
|
+
const bootstrapPath = (path) => path === start.runtimeMount || path.startsWith(start.runtimeMount + "/");
|
|
1905
|
+
const module = runtime._module;
|
|
1906
|
+
const send = async (pointer) => {
|
|
1907
|
+
let response = await encode(async () => {
|
|
1908
|
+
signal.throwIfAborted();
|
|
1909
|
+
const [operation, path, follow] = JSON.parse(module.UTF8ToString(pointer, 16384));
|
|
1910
|
+
if (operation === "stat") return native.metadata(path, follow);
|
|
1911
|
+
if (typeof path !== "string") throw Object.assign(new Error("Invalid native Python path"), { code: "EINVAL" });
|
|
1912
|
+
const target = absolute(path);
|
|
1913
|
+
if (operation === "directory") {
|
|
1914
|
+
const entries = bootstrapPath(target) ? filesystem.readdir(target).filter((name) => name !== "." && name !== "..") : (await start.dispatch({ op: "readdir", args: [target] })).map((entry) => entry.name);
|
|
1915
|
+
return { entries };
|
|
1916
|
+
}
|
|
1917
|
+
if (operation === "tree") {
|
|
1918
|
+
if (bootstrapPath(target) || !await start.dispatch({ op: "rmtreeSupported", args: [target] })) return { supported: false };
|
|
1919
|
+
try {
|
|
1920
|
+
await start.dispatch({ op: "rmtree", args: [target] });
|
|
1921
|
+
return { supported: true };
|
|
1922
|
+
} catch (error) {
|
|
1923
|
+
return { supported: true, errno: errno[error.code ?? ""] ?? errno.EIO };
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
throw Object.assign(new Error("Invalid native Python operation"), { code: "EINVAL" });
|
|
1927
|
+
});
|
|
1928
|
+
if (response.length > 1048576) response = JSON.stringify({ errno: errno.EFBIG });
|
|
1929
|
+
let bytes = new TextEncoder().encode(response);
|
|
1930
|
+
if (bytes.length > 1048576) bytes = new TextEncoder().encode(JSON.stringify({ errno: errno.EFBIG }));
|
|
1931
|
+
const output = module._malloc(bytes.length + 1);
|
|
1932
|
+
if (!output) return 0;
|
|
1933
|
+
module.HEAPU8.set(bytes, output);
|
|
1934
|
+
module.HEAPU8[output + bytes.length] = 0;
|
|
1935
|
+
return output;
|
|
1936
|
+
};
|
|
1937
|
+
const nativeCall = new engine.Instance(options.nativeCall, {
|
|
1938
|
+
python: {
|
|
1939
|
+
utf8: module._PyUnicode_AsUTF8,
|
|
1940
|
+
unicode: module._PyUnicode_FromString,
|
|
1941
|
+
free: module._free,
|
|
1942
|
+
noMemory: module._PyErr_NoMemory
|
|
1943
|
+
},
|
|
1944
|
+
request: { send },
|
|
1945
|
+
shutdown: { send: new engine.Suspending(send) },
|
|
1946
|
+
control: { active, syncify }
|
|
1947
|
+
});
|
|
1948
|
+
methodPointer = module.addFunction(nativeCall.exports.call, "iii");
|
|
1949
|
+
methodDefinition = module._malloc(128);
|
|
1950
|
+
if (!methodDefinition) throw new PythonFailure("runtime-assets");
|
|
1951
|
+
module.HEAPU8.fill(0, methodDefinition, methodDefinition + 128);
|
|
1952
|
+
module.HEAPU8.set(new TextEncoder().encode("request\0_safe_native_fs\0"), methodDefinition + 16);
|
|
1953
|
+
module.HEAPU32.set([methodDefinition + 16, methodPointer, 8, 0], methodDefinition / 4);
|
|
1954
|
+
const extension = module._PyImport_AddModule(methodDefinition + 24);
|
|
1955
|
+
const callable = module._PyCFunction_NewEx(methodDefinition, 0, 0);
|
|
1956
|
+
if (!extension || !callable || module._PyModule_AddObject(extension, methodDefinition + 16, callable) < 0) throw new PythonFailure("runtime-abi");
|
|
1957
|
+
const fields = Number(runtime.runPython("os.stat_result.n_fields"));
|
|
1958
|
+
const statResult = new engine.Instance(options.statResult, { python: {
|
|
1959
|
+
fields: new engine.Global({ value: "i32" }, fields),
|
|
1960
|
+
create: module._PyStructSequence_New,
|
|
1961
|
+
size: module._PyTuple_Size,
|
|
1962
|
+
item: module._PyTuple_GetItem,
|
|
1963
|
+
retain: module._Py_IncRef,
|
|
1964
|
+
set: module._PyStructSequence_SetItem,
|
|
1965
|
+
invalid: module._PyErr_BadArgument
|
|
1966
|
+
} });
|
|
1967
|
+
statPointer = module.addFunction(statResult.exports.construct, "iii");
|
|
1968
|
+
module.HEAPU8.set(new TextEncoder().encode("stat_result\0os\0"), methodDefinition + 80);
|
|
1969
|
+
module.HEAPU32.set([methodDefinition + 80, statPointer, 8, 0], (methodDefinition + 64) / 4);
|
|
1970
|
+
const osModule = module._PyImport_AddModule(methodDefinition + 92);
|
|
1971
|
+
const statType = module._PyObject_GetAttrString(osModule, methodDefinition + 80);
|
|
1972
|
+
const constructStat = module._PyCFunction_NewEx(methodDefinition + 64, statType, 0);
|
|
1973
|
+
module._Py_DecRef(statType);
|
|
1974
|
+
if (!constructStat || module._PyModule_AddObject(extension, methodDefinition + 80, constructStat) < 0) throw new PythonFailure("runtime-abi");
|
|
1975
|
+
runtime.runPython(`
|
|
1976
|
+
from _safe_native_fs import request as _safe_native_request
|
|
1977
|
+
def _safe_stat_projection(path, follow):
|
|
1978
|
+
return _safe_native_request(json.dumps(['stat', path, follow]))
|
|
1979
|
+
def _safe_import_stat(path):
|
|
1980
|
+
return _safe_stat_projection(path, True)
|
|
1981
|
+
def _safe_directory_entries(path):
|
|
1982
|
+
return _safe_native_request(json.dumps(['directory', path]))
|
|
1983
|
+
def _safe_tree_cleanup(path):
|
|
1984
|
+
return _safe_native_request(json.dumps(['tree', path]))
|
|
1985
|
+
`);
|
|
1986
|
+
for (const script of [pythonImportMetadata, pythonDirectoryEntries, pythonStatProjection, pythonTreeCleanup]) runtime.runPython(script);
|
|
1987
|
+
runtime.runPython(`
|
|
1988
|
+
from _safe_native_fs import stat_result as _safe_construct_stat
|
|
1989
|
+
_safe_stat_fields = os.stat_result.n_fields
|
|
1990
|
+
_safe_stat_probe = os.stat_result(tuple(range(_safe_stat_fields)))
|
|
1991
|
+
_safe_stat_indexes = {name: getattr(_safe_stat_probe, name) for name in dir(_safe_stat_probe) if name.startswith('st_')}
|
|
1992
|
+
def _safe_native_stat_type(values, extras):
|
|
1993
|
+
fields = list(values) + [None] * (_safe_stat_fields - len(values))
|
|
1994
|
+
for name, value in extras.items():
|
|
1995
|
+
if name in _safe_stat_indexes:
|
|
1996
|
+
fields[_safe_stat_indexes[name]] = value
|
|
1997
|
+
return _safe_construct_stat(tuple(fields))
|
|
1998
|
+
_safe_stat_type = _safe_native_stat_type
|
|
1999
|
+
`);
|
|
2000
|
+
runtime.globals.set("_safe_invocation_json", JSON.stringify(start.invocation));
|
|
2001
|
+
runtime.globals.set("_safe_execution_code", pythonExecution);
|
|
2002
|
+
runtime.globals.set("_safe_is_cancelled", () => signal.aborted);
|
|
2003
|
+
active.value = 1;
|
|
2004
|
+
start.onReady();
|
|
2005
|
+
exitCode = Number(await runtime.runPythonAsync(`
|
|
2006
|
+
try:
|
|
2007
|
+
exec(_safe_execution_code)
|
|
2008
|
+
except BaseException:
|
|
2009
|
+
if not _safe_is_cancelled():
|
|
2010
|
+
raise
|
|
2011
|
+
_safe_exit = 130
|
|
2012
|
+
_safe_exit
|
|
2013
|
+
`)) & 255;
|
|
2014
|
+
} finally {
|
|
2015
|
+
try {
|
|
2016
|
+
if (qualified) {
|
|
2017
|
+
try {
|
|
2018
|
+
await runtime.runPythonAsync(`
|
|
2019
|
+
import asyncio as _safe_asyncio
|
|
2020
|
+
async def _safe_quiesce_tasks():
|
|
2021
|
+
current = _safe_asyncio.current_task()
|
|
2022
|
+
while True:
|
|
2023
|
+
pending = [task for task in _safe_asyncio.all_tasks() if task is not current]
|
|
2024
|
+
if not pending:
|
|
2025
|
+
break
|
|
2026
|
+
for task in pending:
|
|
2027
|
+
task.cancel()
|
|
2028
|
+
await _safe_asyncio.gather(*pending, return_exceptions=True)
|
|
2029
|
+
loop = _safe_asyncio.get_running_loop()
|
|
2030
|
+
await loop.shutdown_asyncgens()
|
|
2031
|
+
await loop.shutdown_default_executor()
|
|
2032
|
+
await _safe_quiesce_tasks()
|
|
2033
|
+
`);
|
|
2034
|
+
} finally {
|
|
2035
|
+
try {
|
|
2036
|
+
await scheduler.close();
|
|
2037
|
+
} finally {
|
|
2038
|
+
active.value = native ? 2 : 0;
|
|
2039
|
+
finalized = Number(await engine.promising(runtime._module._Py_FinalizeEx)());
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
} finally {
|
|
2044
|
+
active.value = 0;
|
|
2045
|
+
cleanup = scheduler.close().finally(() => native?.close());
|
|
2046
|
+
try {
|
|
2047
|
+
await cleanup;
|
|
2048
|
+
} finally {
|
|
2049
|
+
if (methodDefinition) runtime?._module._free(methodDefinition);
|
|
2050
|
+
if (methodPointer !== void 0) runtime?._module.removeFunction(methodPointer);
|
|
2051
|
+
if (statPointer !== void 0) runtime?._module.removeFunction(statPointer);
|
|
2052
|
+
runtime = void 0;
|
|
2053
|
+
native = void 0;
|
|
2054
|
+
syncify.set(0, null);
|
|
2055
|
+
for (const name of Object.keys(originals)) delete originals[name];
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
signal.throwIfAborted();
|
|
2060
|
+
return finalized < 0 ? 120 : exitCode;
|
|
2061
|
+
};
|
|
2062
|
+
return {
|
|
2063
|
+
run(start) {
|
|
2064
|
+
if (admitted || retirement) return Promise.reject(new PythonFailure("executor-unavailable"));
|
|
2065
|
+
admitted = true;
|
|
2066
|
+
running = execute(start);
|
|
2067
|
+
return running;
|
|
2068
|
+
},
|
|
2069
|
+
terminate() {
|
|
2070
|
+
retirement ??= (async () => {
|
|
2071
|
+
controller.abort();
|
|
2072
|
+
await running?.catch(() => {
|
|
2073
|
+
});
|
|
2074
|
+
await cleanup;
|
|
2075
|
+
})();
|
|
2076
|
+
return retirement;
|
|
2077
|
+
}
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
// packages/safe-bash/src/commands/python/jspi-assets.ts
|
|
2082
|
+
init_platform();
|
|
2083
|
+
function createPythonJspiAssets(options) {
|
|
2084
|
+
const engine = globalThis.WebAssembly;
|
|
2085
|
+
const main = options.main;
|
|
2086
|
+
const registry = options.modules.map((entry) => ({ module: entry.module, bytes: Uint8Array.from(entry.bytes) }));
|
|
2087
|
+
if (![main, ...registry.map((entry) => entry.module)].every((module) => module instanceof engine.Module)) throw new TypeError("Expected precompiled Python Wasm modules");
|
|
2088
|
+
const stdlib = Uint8Array.from(options.stdlib);
|
|
2089
|
+
const responses = /* @__PURE__ */ new WeakMap();
|
|
2090
|
+
const approved = /* @__PURE__ */ new Set([main, ...registry.map((entry) => entry.module)]);
|
|
2091
|
+
const select = (source) => {
|
|
2092
|
+
const bytes = ArrayBuffer.isView(source) ? new Uint8Array(source.buffer, source.byteOffset, source.byteLength) : new Uint8Array(source);
|
|
2093
|
+
const entry = registry.find((candidate) => candidate.bytes.length === bytes.length && candidate.bytes.every((byte, index) => byte === bytes[index]));
|
|
2094
|
+
if (!entry) throw new engine.CompileError("Unapproved Python runtime Wasm bytes");
|
|
2095
|
+
return entry.module;
|
|
2096
|
+
};
|
|
2097
|
+
const WebAssembly = Object.create(engine);
|
|
2098
|
+
WebAssembly.Module = function(source) {
|
|
2099
|
+
return select(source);
|
|
2100
|
+
};
|
|
2101
|
+
Object.setPrototypeOf(WebAssembly.Module, engine.Module);
|
|
2102
|
+
WebAssembly.Module.prototype = engine.Module.prototype;
|
|
2103
|
+
WebAssembly.compile = async (source) => select(source);
|
|
2104
|
+
WebAssembly.compileStreaming = async () => {
|
|
2105
|
+
throw new engine.CompileError("Unapproved Python streaming compilation");
|
|
2106
|
+
};
|
|
2107
|
+
WebAssembly.instantiate = async (source, imports) => {
|
|
2108
|
+
if (source instanceof engine.Module) {
|
|
2109
|
+
if (!approved.has(source)) throw new engine.CompileError("Unapproved Python Wasm module");
|
|
2110
|
+
return new engine.Instance(source, imports);
|
|
2111
|
+
}
|
|
2112
|
+
const module = select(source);
|
|
2113
|
+
return { module, instance: new engine.Instance(module, imports) };
|
|
2114
|
+
};
|
|
2115
|
+
WebAssembly.instantiateStreaming = async (response, imports) => {
|
|
2116
|
+
const module = responses.get(await response);
|
|
2117
|
+
if (!module) throw new engine.CompileError("Unapproved Python Wasm response");
|
|
2118
|
+
return { module, instance: new engine.Instance(module, imports) };
|
|
2119
|
+
};
|
|
2120
|
+
const location = "https://safe-python.invalid/";
|
|
2121
|
+
return { WebAssembly, location, async fetch(url) {
|
|
2122
|
+
const target = new URL(url, location).href;
|
|
2123
|
+
if (target === location + "python_stdlib.zip") return new Response(stdlib);
|
|
2124
|
+
if (target === location + "pyodide.asm.wasm") {
|
|
2125
|
+
const response = new Response(null, { headers: { "Content-Type": "application/wasm" } });
|
|
2126
|
+
responses.set(response, main);
|
|
2127
|
+
return response;
|
|
2128
|
+
}
|
|
2129
|
+
throw new Error("Unapproved Python runtime asset");
|
|
2130
|
+
} };
|
|
2131
|
+
}
|
|
2132
|
+
|
|
1427
2133
|
// packages/safe-bash/src/commands/python/index.ts
|
|
1428
2134
|
var PythonInputChunkError = class extends RangeError {
|
|
1429
2135
|
};
|
|
@@ -1503,7 +2209,8 @@ function createPythonCommands(options) {
|
|
|
1503
2209
|
signal.removeEventListener("abort", aborted);
|
|
1504
2210
|
const subscription = Promise.resolve().then(() => unsubscribe?.());
|
|
1505
2211
|
const termination = Promise.resolve().then(() => executor ? executor.terminate() : endpoint?.terminate());
|
|
1506
|
-
const
|
|
2212
|
+
const filesystemRetirement = termination.finally(() => service.close());
|
|
2213
|
+
const results = await Promise.allSettled([subscription, termination, filesystemRetirement, stdoutOperation?.close(), stderrOperation?.close(), ...pending]);
|
|
1507
2214
|
await input.return?.(void 0);
|
|
1508
2215
|
fragment = void 0;
|
|
1509
2216
|
if (packages) environment.finish(packages);
|
|
@@ -1544,6 +2251,7 @@ function createPythonCommands(options) {
|
|
|
1544
2251
|
}
|
|
1545
2252
|
};
|
|
1546
2253
|
const dispatch = async (request) => {
|
|
2254
|
+
if (request.op === "close") return service.dispatch(request);
|
|
1547
2255
|
signal.throwIfAborted();
|
|
1548
2256
|
if (request.op.startsWith("package-")) return environment.dispatch(request.op, request.args, { fs: context.fs, cwd: context.cwd, signal });
|
|
1549
2257
|
if (request.op === "stdin") {
|
|
@@ -1620,10 +2328,13 @@ function createPythonCommands(options) {
|
|
|
1620
2328
|
}
|
|
1621
2329
|
},
|
|
1622
2330
|
async dispatch(request) {
|
|
1623
|
-
|
|
1624
|
-
|
|
2331
|
+
if (!request || typeof request.op !== "string" || !Array.isArray(request.args)) throw reportPythonFailure("transport-unavailable", void 0, options.onDiagnostic);
|
|
2332
|
+
const releasing = request.op === "close";
|
|
2333
|
+
if (!releasing) signal.throwIfAborted();
|
|
2334
|
+
if (closed && !releasing || !running || requesting) throw reportPythonFailure("transport-unavailable", void 0, options.onDiagnostic);
|
|
1625
2335
|
requesting = true;
|
|
1626
2336
|
const operation = Promise.resolve().then(() => dispatch(request)).catch(async (error) => {
|
|
2337
|
+
if (releasing) throw error;
|
|
1627
2338
|
signal.throwIfAborted();
|
|
1628
2339
|
if (error instanceof PythonInputChunkError) rejectRun?.(error);
|
|
1629
2340
|
if (request.op.startsWith("package-")) throw Object.assign(reportPythonFailure("runtime-assets", error, options.onDiagnostic), { code: "EPACKAGE" });
|
|
@@ -1863,7 +2574,12 @@ export {
|
|
|
1863
2574
|
pythonDocumentPackages,
|
|
1864
2575
|
createPythonPackageEnvironment,
|
|
1865
2576
|
createPythonExecutorPool,
|
|
2577
|
+
createPythonJspiTrampoline,
|
|
2578
|
+
createPythonJspiNativeCall,
|
|
2579
|
+
createPythonJspiStatResult,
|
|
2580
|
+
createPythonJspiExecutor,
|
|
2581
|
+
createPythonJspiAssets,
|
|
1866
2582
|
createPythonCommands,
|
|
1867
2583
|
pythonCommands
|
|
1868
2584
|
};
|
|
1869
|
-
//# sourceMappingURL=chunk-
|
|
2585
|
+
//# sourceMappingURL=chunk-BONY6MX5.js.map
|