@lvce-editor/pty-host 8.8.1 → 8.9.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/dist/ptyHostMain.js +202 -108
- package/package.json +1 -1
package/dist/ptyHostMain.js
CHANGED
|
@@ -1378,88 +1378,6 @@ const NodeWebSocketRpcClient = {
|
|
|
1378
1378
|
create: create$2
|
|
1379
1379
|
};
|
|
1380
1380
|
|
|
1381
|
-
const METHODS_THAT_REQUIRE_SOCKET = new Set(['Terminal.create']);
|
|
1382
|
-
const requiresSocket = method => {
|
|
1383
|
-
return METHODS_THAT_REQUIRE_SOCKET.has(method);
|
|
1384
|
-
};
|
|
1385
|
-
|
|
1386
|
-
const handleElectronMessagePort = async messagePort => {
|
|
1387
|
-
object(messagePort);
|
|
1388
|
-
await create$5({
|
|
1389
|
-
commandMap: {},
|
|
1390
|
-
messagePort,
|
|
1391
|
-
requiresSocket: requiresSocket
|
|
1392
|
-
});
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
|
-
const NodeWorker = 1;
|
|
1396
|
-
const NodeForkedProcess = 2;
|
|
1397
|
-
const WebSocket = 3;
|
|
1398
|
-
const ElectronUtilityProcess = 4;
|
|
1399
|
-
const ElectronMessagePort = 5;
|
|
1400
|
-
const NodeMessagePort = 6;
|
|
1401
|
-
const Auto = () => {
|
|
1402
|
-
const {
|
|
1403
|
-
argv
|
|
1404
|
-
} = process;
|
|
1405
|
-
if (argv.includes('--ipc-type=node-worker')) {
|
|
1406
|
-
return NodeWorker;
|
|
1407
|
-
}
|
|
1408
|
-
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
1409
|
-
return NodeForkedProcess;
|
|
1410
|
-
}
|
|
1411
|
-
if (argv.includes('--ipc-type=websocket')) {
|
|
1412
|
-
return WebSocket;
|
|
1413
|
-
}
|
|
1414
|
-
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
1415
|
-
return ElectronUtilityProcess;
|
|
1416
|
-
}
|
|
1417
|
-
throw new Error(`[pty-host] unknown ipc type`);
|
|
1418
|
-
};
|
|
1419
|
-
|
|
1420
|
-
const getModule = method => {
|
|
1421
|
-
switch (method) {
|
|
1422
|
-
case ElectronMessagePort:
|
|
1423
|
-
return ElectronMessagePortRpcClient;
|
|
1424
|
-
case ElectronUtilityProcess:
|
|
1425
|
-
return ElectronUtilityProcessRpcClient;
|
|
1426
|
-
case NodeForkedProcess:
|
|
1427
|
-
return NodeForkedProcessRpcClient;
|
|
1428
|
-
case WebSocket:
|
|
1429
|
-
return NodeWebSocketRpcClient;
|
|
1430
|
-
default:
|
|
1431
|
-
throw new Error('unexpected ipc type');
|
|
1432
|
-
}
|
|
1433
|
-
};
|
|
1434
|
-
|
|
1435
|
-
const listen$1 = async ({
|
|
1436
|
-
method,
|
|
1437
|
-
...params
|
|
1438
|
-
}) => {
|
|
1439
|
-
const module = getModule(method);
|
|
1440
|
-
// @ts-ignore
|
|
1441
|
-
const rpc = await module.create(params);
|
|
1442
|
-
return rpc;
|
|
1443
|
-
};
|
|
1444
|
-
|
|
1445
|
-
const handleNodeMessagePort = async messagePort => {
|
|
1446
|
-
await listen$1({
|
|
1447
|
-
messagePort,
|
|
1448
|
-
method: NodeMessagePort
|
|
1449
|
-
});
|
|
1450
|
-
};
|
|
1451
|
-
|
|
1452
|
-
const handleWebSocket = async (handle, request) => {
|
|
1453
|
-
object(handle);
|
|
1454
|
-
object(request);
|
|
1455
|
-
await create$2({
|
|
1456
|
-
commandMap: {},
|
|
1457
|
-
handle,
|
|
1458
|
-
request,
|
|
1459
|
-
requiresSocket: requiresSocket
|
|
1460
|
-
});
|
|
1461
|
-
};
|
|
1462
|
-
|
|
1463
1381
|
class DataEvent extends Event {
|
|
1464
1382
|
constructor(data) {
|
|
1465
1383
|
super('data');
|
|
@@ -1539,17 +1457,35 @@ const create$1 = async ({
|
|
|
1539
1457
|
}
|
|
1540
1458
|
};
|
|
1541
1459
|
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1460
|
+
const connections$1 = new WeakMap();
|
|
1461
|
+
const set = (ipc, id, pty) => {
|
|
1462
|
+
let terminals = connections$1.get(ipc);
|
|
1463
|
+
if (!terminals) {
|
|
1464
|
+
terminals = new Map();
|
|
1465
|
+
connections$1.set(ipc, terminals);
|
|
1466
|
+
}
|
|
1467
|
+
terminals.set(id, pty);
|
|
1547
1468
|
};
|
|
1548
|
-
const get = id =>
|
|
1549
|
-
|
|
1469
|
+
const get = (ipc, id) => connections$1.get(ipc)?.get(id);
|
|
1470
|
+
const remove = (ipc, id) => {
|
|
1471
|
+
connections$1.get(ipc)?.delete(id);
|
|
1550
1472
|
};
|
|
1551
|
-
|
|
1552
|
-
|
|
1473
|
+
|
|
1474
|
+
const connections = new WeakMap();
|
|
1475
|
+
const cleanup = new WeakMap();
|
|
1476
|
+
const closedConnections = new WeakSet();
|
|
1477
|
+
const disposeConnection = ipc => {
|
|
1478
|
+
closedConnections.add(ipc);
|
|
1479
|
+
const entries = connections.get(ipc);
|
|
1480
|
+
connections.delete(ipc);
|
|
1481
|
+
if (!entries) return;
|
|
1482
|
+
for (const entry of entries) {
|
|
1483
|
+
entry.closed = true;
|
|
1484
|
+
if (entry.pty) {
|
|
1485
|
+
cleanup.get(entry.pty)?.();
|
|
1486
|
+
entry.pty.dispose();
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1553
1489
|
};
|
|
1554
1490
|
|
|
1555
1491
|
// TODO maybe merge pty and pty controller
|
|
@@ -1559,13 +1495,34 @@ const createWithDependencies = async (ipc, id, cwd, command, args, createPty) =>
|
|
|
1559
1495
|
string(command);
|
|
1560
1496
|
array(args);
|
|
1561
1497
|
object(ipc);
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
}
|
|
1498
|
+
if (closedConnections.has(ipc)) throw new Error('Terminal connection closed');
|
|
1499
|
+
let entries = connections.get(ipc);
|
|
1500
|
+
if (!entries) {
|
|
1501
|
+
entries = new Set();
|
|
1502
|
+
connections.set(ipc, entries);
|
|
1503
|
+
}
|
|
1504
|
+
const entry = {
|
|
1505
|
+
closed: false
|
|
1506
|
+
};
|
|
1507
|
+
entries.add(entry);
|
|
1508
|
+
let pty;
|
|
1509
|
+
try {
|
|
1510
|
+
pty = await createPty({
|
|
1511
|
+
args,
|
|
1512
|
+
command,
|
|
1513
|
+
cwd
|
|
1514
|
+
});
|
|
1515
|
+
} catch (error) {
|
|
1516
|
+
entries.delete(entry);
|
|
1517
|
+
throw error;
|
|
1518
|
+
}
|
|
1519
|
+
entry.pty = pty;
|
|
1520
|
+
if (entry.closed) {
|
|
1521
|
+
pty.dispose();
|
|
1522
|
+
throw new Error('Terminal connection closed');
|
|
1523
|
+
}
|
|
1568
1524
|
const handleData = event => {
|
|
1525
|
+
if (entry.closed) return;
|
|
1569
1526
|
ipc.send({
|
|
1570
1527
|
jsonrpc: '2.0',
|
|
1571
1528
|
method: 'Viewlet.send',
|
|
@@ -1573,43 +1530,178 @@ const createWithDependencies = async (ipc, id, cwd, command, args, createPty) =>
|
|
|
1573
1530
|
});
|
|
1574
1531
|
};
|
|
1575
1532
|
const handleExit = event => {
|
|
1576
|
-
|
|
1533
|
+
entries.delete(entry);
|
|
1534
|
+
if (get(ipc, id) === pty) remove(ipc, id);
|
|
1535
|
+
if (entry.closed) return;
|
|
1577
1536
|
ipc.send({
|
|
1578
1537
|
jsonrpc: '2.0',
|
|
1579
1538
|
method: 'Viewlet.send',
|
|
1580
1539
|
params: [id, 'handleExit', event.data]
|
|
1581
1540
|
});
|
|
1582
1541
|
};
|
|
1542
|
+
cleanup.set(pty, () => {
|
|
1543
|
+
entry.closed = true;
|
|
1544
|
+
entries.delete(entry);
|
|
1545
|
+
pty.removeEventListener('data', handleData);
|
|
1546
|
+
pty.removeEventListener('exit', handleExit);
|
|
1547
|
+
if (get(ipc, id) === pty) remove(ipc, id);
|
|
1548
|
+
cleanup.delete(pty);
|
|
1549
|
+
});
|
|
1583
1550
|
pty.addEventListener('data', handleData);
|
|
1584
1551
|
pty.addEventListener('exit', handleExit, {
|
|
1585
1552
|
once: true
|
|
1586
1553
|
});
|
|
1587
|
-
set(id, pty);
|
|
1554
|
+
set(ipc, id, pty);
|
|
1588
1555
|
};
|
|
1589
1556
|
const create = (ipc, id, cwd, command, args) => {
|
|
1590
1557
|
return createWithDependencies(ipc, id, cwd, command, args, create$1);
|
|
1591
1558
|
};
|
|
1592
|
-
const write = (id, data) => {
|
|
1593
|
-
const pty = get(id);
|
|
1559
|
+
const write = (ipc, id, data) => {
|
|
1560
|
+
const pty = get(ipc, id);
|
|
1594
1561
|
if (!pty) {
|
|
1595
1562
|
throw new Error(`pty ${id} not found`);
|
|
1596
1563
|
}
|
|
1597
1564
|
pty.write(data);
|
|
1598
1565
|
};
|
|
1599
|
-
const resize = (id, columns, rows) => {
|
|
1600
|
-
const pty = get(id);
|
|
1566
|
+
const resize = (ipc, id, columns, rows) => {
|
|
1567
|
+
const pty = get(ipc, id);
|
|
1601
1568
|
if (!pty) {
|
|
1602
1569
|
throw new Error(`pty ${id} not found`);
|
|
1603
1570
|
}
|
|
1604
1571
|
pty.resize(columns, rows);
|
|
1605
1572
|
};
|
|
1606
|
-
const dispose = id => {
|
|
1607
|
-
const pty = get(id);
|
|
1573
|
+
const dispose = (ipc, id) => {
|
|
1574
|
+
const pty = get(ipc, id);
|
|
1608
1575
|
if (!pty) {
|
|
1609
1576
|
return;
|
|
1610
1577
|
}
|
|
1578
|
+
cleanup.get(pty)?.();
|
|
1611
1579
|
pty.dispose();
|
|
1612
|
-
remove(id);
|
|
1580
|
+
if (get(ipc, id) === pty) remove(ipc, id);
|
|
1581
|
+
};
|
|
1582
|
+
|
|
1583
|
+
const ready = Promise.withResolvers();
|
|
1584
|
+
const state$1 = {};
|
|
1585
|
+
const setParent = rpc => {
|
|
1586
|
+
state$1.parent = rpc;
|
|
1587
|
+
ready.resolve();
|
|
1588
|
+
};
|
|
1589
|
+
const release = async id => {
|
|
1590
|
+
if (!state$1.parent) await ready.promise;
|
|
1591
|
+
state$1.parent.send('PtyHost.release', id);
|
|
1592
|
+
};
|
|
1593
|
+
const connect = async (handle, id, create) => {
|
|
1594
|
+
let closed = false;
|
|
1595
|
+
let rpc;
|
|
1596
|
+
const onClose = () => {
|
|
1597
|
+
if (closed) return;
|
|
1598
|
+
closed = true;
|
|
1599
|
+
handle.off('close', onClose);
|
|
1600
|
+
try {
|
|
1601
|
+
if (rpc) disposeConnection(rpc.ipc);
|
|
1602
|
+
} finally {
|
|
1603
|
+
if (id !== undefined) void release(id);
|
|
1604
|
+
}
|
|
1605
|
+
};
|
|
1606
|
+
handle.on('close', onClose);
|
|
1607
|
+
try {
|
|
1608
|
+
if (handle.destroyed) throw new Error('Terminal connection closed');
|
|
1609
|
+
rpc = await create();
|
|
1610
|
+
if (closed) {
|
|
1611
|
+
disposeConnection(rpc.ipc);
|
|
1612
|
+
await rpc.dispose();
|
|
1613
|
+
}
|
|
1614
|
+
} catch (error) {
|
|
1615
|
+
onClose();
|
|
1616
|
+
handle.destroy?.();
|
|
1617
|
+
handle.close?.();
|
|
1618
|
+
throw error;
|
|
1619
|
+
}
|
|
1620
|
+
};
|
|
1621
|
+
|
|
1622
|
+
const METHODS_THAT_REQUIRE_SOCKET = new Set(['Terminal.create', 'Terminal.write', 'Terminal.resize', 'Terminal.dispose']);
|
|
1623
|
+
const requiresSocket = method => {
|
|
1624
|
+
return METHODS_THAT_REQUIRE_SOCKET.has(method);
|
|
1625
|
+
};
|
|
1626
|
+
|
|
1627
|
+
const handleElectronMessagePort = async (messagePort, connectionId) => {
|
|
1628
|
+
object(messagePort);
|
|
1629
|
+
await connect(messagePort, connectionId, () => create$5({
|
|
1630
|
+
commandMap: {},
|
|
1631
|
+
messagePort,
|
|
1632
|
+
requiresSocket: requiresSocket
|
|
1633
|
+
}));
|
|
1634
|
+
};
|
|
1635
|
+
|
|
1636
|
+
const NodeWorker = 1;
|
|
1637
|
+
const NodeForkedProcess = 2;
|
|
1638
|
+
const WebSocket = 3;
|
|
1639
|
+
const ElectronUtilityProcess = 4;
|
|
1640
|
+
const ElectronMessagePort = 5;
|
|
1641
|
+
const NodeMessagePort = 6;
|
|
1642
|
+
const Auto = () => {
|
|
1643
|
+
const {
|
|
1644
|
+
argv
|
|
1645
|
+
} = process;
|
|
1646
|
+
if (argv.includes('--ipc-type=node-worker')) {
|
|
1647
|
+
return NodeWorker;
|
|
1648
|
+
}
|
|
1649
|
+
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
1650
|
+
return NodeForkedProcess;
|
|
1651
|
+
}
|
|
1652
|
+
if (argv.includes('--ipc-type=websocket')) {
|
|
1653
|
+
return WebSocket;
|
|
1654
|
+
}
|
|
1655
|
+
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
1656
|
+
return ElectronUtilityProcess;
|
|
1657
|
+
}
|
|
1658
|
+
throw new Error(`[pty-host] unknown ipc type`);
|
|
1659
|
+
};
|
|
1660
|
+
|
|
1661
|
+
const getModule = method => {
|
|
1662
|
+
switch (method) {
|
|
1663
|
+
case ElectronMessagePort:
|
|
1664
|
+
return ElectronMessagePortRpcClient;
|
|
1665
|
+
case ElectronUtilityProcess:
|
|
1666
|
+
return ElectronUtilityProcessRpcClient;
|
|
1667
|
+
case NodeForkedProcess:
|
|
1668
|
+
return NodeForkedProcessRpcClient;
|
|
1669
|
+
case WebSocket:
|
|
1670
|
+
return NodeWebSocketRpcClient;
|
|
1671
|
+
default:
|
|
1672
|
+
throw new Error('unexpected ipc type');
|
|
1673
|
+
}
|
|
1674
|
+
};
|
|
1675
|
+
|
|
1676
|
+
const listen$1 = async ({
|
|
1677
|
+
method,
|
|
1678
|
+
...params
|
|
1679
|
+
}) => {
|
|
1680
|
+
const module = getModule(method);
|
|
1681
|
+
// @ts-ignore
|
|
1682
|
+
const rpc = await module.create(params);
|
|
1683
|
+
if (params.requiresSocket) {
|
|
1684
|
+
rpc.ipc.requiresSocket = params.requiresSocket;
|
|
1685
|
+
}
|
|
1686
|
+
return rpc;
|
|
1687
|
+
};
|
|
1688
|
+
|
|
1689
|
+
const handleNodeMessagePort = async messagePort => {
|
|
1690
|
+
await listen$1({
|
|
1691
|
+
messagePort,
|
|
1692
|
+
method: NodeMessagePort
|
|
1693
|
+
});
|
|
1694
|
+
};
|
|
1695
|
+
|
|
1696
|
+
const handleWebSocket = async (handle, request, connectionId) => {
|
|
1697
|
+
object(handle);
|
|
1698
|
+
object(request);
|
|
1699
|
+
await connect(handle, connectionId, () => create$2({
|
|
1700
|
+
commandMap: {},
|
|
1701
|
+
handle,
|
|
1702
|
+
request,
|
|
1703
|
+
requiresSocket: requiresSocket
|
|
1704
|
+
}));
|
|
1613
1705
|
};
|
|
1614
1706
|
|
|
1615
1707
|
const HandleElectronMessagePort = 'HandleElectronMessagePort.handleElectronMessagePort';
|
|
@@ -1633,9 +1725,11 @@ const commandMap = {
|
|
|
1633
1725
|
};
|
|
1634
1726
|
|
|
1635
1727
|
const listen = async () => {
|
|
1636
|
-
await listen$1({
|
|
1637
|
-
method: Auto()
|
|
1728
|
+
const rpc = await listen$1({
|
|
1729
|
+
method: Auto(),
|
|
1730
|
+
requiresSocket: requiresSocket
|
|
1638
1731
|
});
|
|
1732
|
+
setParent(rpc);
|
|
1639
1733
|
};
|
|
1640
1734
|
|
|
1641
1735
|
const NewLine$1 = '\n';
|