@lvce-editor/pty-host 2.1.0 → 3.0.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 +3 -1
- package/bin/ptyHost.js +1 -1
- package/dist/ptyHostMain.js +386 -0
- package/package.json +7 -45
- package/src/parts/Assert/Assert.js +0 -59
- package/src/parts/AssertionError/AssertionError.js +0 -6
- package/src/parts/Callback/Callback.js +0 -1
- package/src/parts/Character/Character.js +0 -11
- package/src/parts/Command/Command.js +0 -9
- package/src/parts/CommandMap/CommandMap.js +0 -17
- package/src/parts/CommandState/CommandState.js +0 -17
- package/src/parts/Debug/Debug.js +0 -3
- package/src/parts/ErrorCodes/ErrorCodes.js +0 -19
- package/src/parts/ErrorHandling/ErrorHandling.js +0 -75
- package/src/parts/ExitCode/ExitCode.js +0 -5
- package/src/parts/GetNewLineIndex/GetNewLineIndex.js +0 -11
- package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.js +0 -13
- package/src/parts/HandleIpc/HandleIpc.js +0 -15
- package/src/parts/HandleMessage/HandleMessage.js +0 -25
- package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.js +0 -11
- package/src/parts/HandleWebSocket/HandleWebSocket.js +0 -15
- package/src/parts/IpcChild/IpcChild.js +0 -15
- package/src/parts/IpcChildModule/IpcChildModule.js +0 -25
- package/src/parts/IpcChildType/IpcChildType.js +0 -20
- package/src/parts/IsIgnoredError/IsIgnoredError.js +0 -18
- package/src/parts/JsonRpc/JsonRpc.js +0 -1
- package/src/parts/Listen/Listen.js +0 -8
- package/src/parts/Logger/Logger.js +0 -50
- package/src/parts/Main/Main.js +0 -14
- package/src/parts/NodePty/NodePty.js +0 -72
- package/src/parts/PrettyError/PrettyError.js +0 -1
- package/src/parts/PrintPrettyError/PrintPrettyError.js +0 -7
- package/src/parts/Process/Process.js +0 -17
- package/src/parts/ProcessListeners/ProcessListeners.js +0 -17
- package/src/parts/Pty/Pty.js +0 -1
- package/src/parts/PtyController/PtyController.js +0 -57
- package/src/parts/PtyState/PtyState.js +0 -19
- package/src/parts/RequiresSocket/RequiresSocket.js +0 -5
- package/src/parts/TerminalProcessCommandType/TerminalProcessCommandType.js +0 -9
- package/src/parts/VError/VError.js +0 -1
- package/src/ptyHostMain.js +0 -3
package/README.md
CHANGED
package/bin/ptyHost.js
CHANGED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import { execute, register } from '@lvce-editor/command';
|
|
2
|
+
import { object, string, array, number } from '@lvce-editor/assert';
|
|
3
|
+
import { handleJsonRpcMessage, resolve } from '@lvce-editor/json-rpc';
|
|
4
|
+
import { IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithWebSocket, IpcChildWithNodeWorker, IpcChildWithNodeForkedProcess } from '@lvce-editor/ipc';
|
|
5
|
+
import debugModule from 'debug';
|
|
6
|
+
import { spawn } from 'node-pty';
|
|
7
|
+
import { VError } from '@lvce-editor/verror';
|
|
8
|
+
import { Console } from 'node:console';
|
|
9
|
+
import { createWriteStream } from 'node:fs';
|
|
10
|
+
import { tmpdir } from 'node:os';
|
|
11
|
+
import { prepare } from '@lvce-editor/pretty-error';
|
|
12
|
+
|
|
13
|
+
const METHODS_THAT_REQUIRE_SOCKET = new Set(['Terminal.create']);
|
|
14
|
+
const requiresSocket = method => {
|
|
15
|
+
return METHODS_THAT_REQUIRE_SOCKET.has(method);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const preparePrettyError = error => {
|
|
19
|
+
return error;
|
|
20
|
+
};
|
|
21
|
+
const logError = () => {
|
|
22
|
+
// PrintPrettyError.printPrettyError(prettyError, `[terminal-process] `)
|
|
23
|
+
};
|
|
24
|
+
const handleMessage = event => {
|
|
25
|
+
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const handleIpc = ipc => {
|
|
29
|
+
object(ipc);
|
|
30
|
+
if ('addEventListener' in ipc) {
|
|
31
|
+
ipc.addEventListener('message', handleMessage);
|
|
32
|
+
} else if ('onmessage' in ipc) {
|
|
33
|
+
// deprecated
|
|
34
|
+
ipc.onmessage = handleMessage;
|
|
35
|
+
} else if ('on' in ipc) {
|
|
36
|
+
// deprecated
|
|
37
|
+
ipc.on('message', handleMessage);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const NodeWorker = 1;
|
|
42
|
+
const NodeForkedProcess = 2;
|
|
43
|
+
const WebSocket = 3;
|
|
44
|
+
const ElectronUtilityProcess = 4;
|
|
45
|
+
const ElectronMessagePort = 5;
|
|
46
|
+
const NodeMessagePort = 6;
|
|
47
|
+
const Auto = () => {
|
|
48
|
+
const {
|
|
49
|
+
argv
|
|
50
|
+
} = process;
|
|
51
|
+
if (argv.includes('--ipc-type=node-worker')) {
|
|
52
|
+
return NodeWorker;
|
|
53
|
+
}
|
|
54
|
+
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
55
|
+
return NodeForkedProcess;
|
|
56
|
+
}
|
|
57
|
+
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
58
|
+
return ElectronUtilityProcess;
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`[pty-host] unknown ipc type`);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getModule = method => {
|
|
64
|
+
switch (method) {
|
|
65
|
+
case NodeForkedProcess:
|
|
66
|
+
return IpcChildWithNodeForkedProcess;
|
|
67
|
+
case NodeWorker:
|
|
68
|
+
return IpcChildWithNodeWorker;
|
|
69
|
+
case WebSocket:
|
|
70
|
+
return IpcChildWithWebSocket;
|
|
71
|
+
case ElectronUtilityProcess:
|
|
72
|
+
return IpcChildWithElectronUtilityProcess;
|
|
73
|
+
case ElectronMessagePort:
|
|
74
|
+
return IpcChildWithElectronMessagePort;
|
|
75
|
+
default:
|
|
76
|
+
throw new Error('unexpected ipc type');
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const listen$1 = async ({
|
|
81
|
+
method,
|
|
82
|
+
...params
|
|
83
|
+
}) => {
|
|
84
|
+
const module = getModule(method);
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
const rawIpc = await module.listen(params);
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
if (module.signal) {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
module.signal(rawIpc);
|
|
91
|
+
}
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
const ipc = module.wrap(rawIpc);
|
|
94
|
+
return ipc;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const handleElectronMessagePort = async messagePort => {
|
|
98
|
+
object(messagePort);
|
|
99
|
+
const ipc = await listen$1({
|
|
100
|
+
method: ElectronMessagePort,
|
|
101
|
+
messagePort
|
|
102
|
+
});
|
|
103
|
+
handleIpc(ipc);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const handleNodeMessagePort = async messagePort => {
|
|
107
|
+
const ipc = await listen$1({
|
|
108
|
+
method: NodeMessagePort,
|
|
109
|
+
messagePort
|
|
110
|
+
});
|
|
111
|
+
handleIpc(ipc);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const handleWebSocket = async (handle, request) => {
|
|
115
|
+
object(handle);
|
|
116
|
+
object(request);
|
|
117
|
+
const ipc = await listen$1({
|
|
118
|
+
method: WebSocket,
|
|
119
|
+
request,
|
|
120
|
+
handle
|
|
121
|
+
});
|
|
122
|
+
handleIpc(ipc);
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const debug = debugModule('pty-host');
|
|
126
|
+
|
|
127
|
+
class DataEvent extends Event {
|
|
128
|
+
constructor(data) {
|
|
129
|
+
super('data');
|
|
130
|
+
this.data = data;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
class ExitEvent extends Event {
|
|
134
|
+
constructor(data) {
|
|
135
|
+
super('exit');
|
|
136
|
+
this.data = data;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
class Pty extends EventTarget {
|
|
140
|
+
/**
|
|
141
|
+
*
|
|
142
|
+
* @param {import('node-pty').IPty} pty
|
|
143
|
+
*/
|
|
144
|
+
constructor(pty) {
|
|
145
|
+
super();
|
|
146
|
+
this.pty = pty;
|
|
147
|
+
const handleData = data => {
|
|
148
|
+
this.dispatchEvent(new DataEvent(data));
|
|
149
|
+
};
|
|
150
|
+
const handleExit = data => {
|
|
151
|
+
this.dispatchEvent(new ExitEvent(data));
|
|
152
|
+
};
|
|
153
|
+
this.pty.onData(handleData);
|
|
154
|
+
this.pty.onExit(handleExit);
|
|
155
|
+
}
|
|
156
|
+
resize(columns, rows) {
|
|
157
|
+
this.pty.resize(columns, rows);
|
|
158
|
+
}
|
|
159
|
+
dispose() {
|
|
160
|
+
this.pty.kill();
|
|
161
|
+
}
|
|
162
|
+
write(data) {
|
|
163
|
+
this.pty.write(data);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
*
|
|
169
|
+
* @param {*} param0
|
|
170
|
+
* @returns {any}
|
|
171
|
+
*/
|
|
172
|
+
const create$1 = ({
|
|
173
|
+
cwd,
|
|
174
|
+
command,
|
|
175
|
+
args
|
|
176
|
+
} = {}) => {
|
|
177
|
+
try {
|
|
178
|
+
string(cwd);
|
|
179
|
+
string(command);
|
|
180
|
+
array(args);
|
|
181
|
+
const pty = spawn(command, args, {
|
|
182
|
+
encoding: null,
|
|
183
|
+
cwd
|
|
184
|
+
// cols: 10,
|
|
185
|
+
// rows: 10,
|
|
186
|
+
});
|
|
187
|
+
const wrapped = new Pty(pty);
|
|
188
|
+
return wrapped;
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw new VError(error, `Failed to create terminal`);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const state$1 = {
|
|
195
|
+
ptyMap: Object.create(null)
|
|
196
|
+
};
|
|
197
|
+
const set = (id, pty) => {
|
|
198
|
+
state$1.ptyMap[id] = pty;
|
|
199
|
+
};
|
|
200
|
+
const get = id => {
|
|
201
|
+
return state$1.ptyMap[id];
|
|
202
|
+
};
|
|
203
|
+
const remove = id => {
|
|
204
|
+
delete state$1.ptyMap[id];
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// TODO maybe merge pty and pty controller
|
|
208
|
+
const create = (ipc, id, cwd, command, args) => {
|
|
209
|
+
number(id);
|
|
210
|
+
string(cwd);
|
|
211
|
+
string(command);
|
|
212
|
+
array(args);
|
|
213
|
+
object(ipc);
|
|
214
|
+
debug(`create ${id} ${cwd}`);
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
const pty = create$1({
|
|
217
|
+
cwd,
|
|
218
|
+
command,
|
|
219
|
+
args
|
|
220
|
+
});
|
|
221
|
+
const handleData = event => {
|
|
222
|
+
ipc.send({
|
|
223
|
+
jsonrpc: '2.0',
|
|
224
|
+
method: 'Viewlet.send',
|
|
225
|
+
params: [id, 'handleData', event.data]
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
pty.addEventListener('data', handleData);
|
|
229
|
+
set(id, pty);
|
|
230
|
+
};
|
|
231
|
+
const write = (id, data) => {
|
|
232
|
+
const pty = get(id);
|
|
233
|
+
if (!pty) {
|
|
234
|
+
throw new Error(`pty ${id} not found`);
|
|
235
|
+
}
|
|
236
|
+
pty.write(data);
|
|
237
|
+
};
|
|
238
|
+
const resize = (id, columns, rows) => {
|
|
239
|
+
const pty = get(id);
|
|
240
|
+
if (!pty) {
|
|
241
|
+
throw new Error(`pty ${id} not found`);
|
|
242
|
+
}
|
|
243
|
+
pty.resize(columns, rows);
|
|
244
|
+
};
|
|
245
|
+
const dispose = id => {
|
|
246
|
+
const pty = get(id);
|
|
247
|
+
if (!pty) {
|
|
248
|
+
throw new Error(`pty ${id} not found`);
|
|
249
|
+
}
|
|
250
|
+
pty.dispose();
|
|
251
|
+
remove(id);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const HandleElectronMessagePort = 'HandleElectronMessagePort.handleElectronMessagePort';
|
|
255
|
+
const HandleNodeMessagePort = 'HandleNodeMessagePort.handleNodeMessagePort';
|
|
256
|
+
const HandleWebSocket = 'HandleWebSocket.handleWebSocket';
|
|
257
|
+
const TerminalCreate = 'Terminal.create';
|
|
258
|
+
const TerminalResize = 'Terminal.resize';
|
|
259
|
+
const TerminalWrite = 'Terminal.write';
|
|
260
|
+
const TerminalDispose = 'Terminal.dispose';
|
|
261
|
+
|
|
262
|
+
const commandMap = {
|
|
263
|
+
[HandleElectronMessagePort]: handleElectronMessagePort,
|
|
264
|
+
[HandleNodeMessagePort]: handleNodeMessagePort,
|
|
265
|
+
[HandleWebSocket]: handleWebSocket,
|
|
266
|
+
[TerminalCreate]: create,
|
|
267
|
+
[TerminalResize]: resize,
|
|
268
|
+
[TerminalWrite]: write,
|
|
269
|
+
[TerminalDispose]: dispose
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const listen = async () => {
|
|
273
|
+
const ipc = await listen$1({
|
|
274
|
+
method: Auto()
|
|
275
|
+
});
|
|
276
|
+
handleIpc(ipc);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const NewLine = '\n';
|
|
280
|
+
|
|
281
|
+
const Error$1 = 1;
|
|
282
|
+
const Success = 0;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
*
|
|
286
|
+
* @param {string} string
|
|
287
|
+
* @param {number|undefined} startIndex
|
|
288
|
+
* @returns
|
|
289
|
+
*/
|
|
290
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
291
|
+
return string.indexOf(NewLine, startIndex);
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
const EPIPE = 'EPIPE';
|
|
295
|
+
const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED';
|
|
296
|
+
|
|
297
|
+
const exit = code => {
|
|
298
|
+
process.exit(code);
|
|
299
|
+
};
|
|
300
|
+
const setExitCode = exitCode => {
|
|
301
|
+
process.exitCode = exitCode;
|
|
302
|
+
};
|
|
303
|
+
const isConnected = () => {
|
|
304
|
+
return process.connected;
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const isIgnoredError = error => {
|
|
308
|
+
if (error && error.code === EPIPE && !process.connected) {
|
|
309
|
+
// parent process is disposed, ignore
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
if (error && error.code === ERR_IPC_CHANNEL_CLOSED && !isConnected()) {
|
|
313
|
+
// parent process is disposed, ignore
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// TODO mock this module when used in unit tests
|
|
320
|
+
|
|
321
|
+
const state = {
|
|
322
|
+
console: undefined
|
|
323
|
+
};
|
|
324
|
+
const createConsole = () => {
|
|
325
|
+
const logFile = `${tmpdir()}/log-terminal-process.txt`;
|
|
326
|
+
const writeStream = createWriteStream(logFile);
|
|
327
|
+
const logger = new Console(writeStream);
|
|
328
|
+
return logger;
|
|
329
|
+
};
|
|
330
|
+
const getOrCreateLogger = () => {
|
|
331
|
+
if (!state.console) {
|
|
332
|
+
state.console = createConsole();
|
|
333
|
+
}
|
|
334
|
+
return state.console;
|
|
335
|
+
};
|
|
336
|
+
const info = (...args) => {
|
|
337
|
+
const logger = getOrCreateLogger();
|
|
338
|
+
logger.info(...args);
|
|
339
|
+
console.info(...args);
|
|
340
|
+
};
|
|
341
|
+
const error = (...args) => {
|
|
342
|
+
const logger = getOrCreateLogger();
|
|
343
|
+
logger.error(...args);
|
|
344
|
+
console.error(...args);
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const firstErrorLine = error => {
|
|
348
|
+
if (error.stack) {
|
|
349
|
+
return error.stack.slice(0, getNewLineIndex(error.stack));
|
|
350
|
+
}
|
|
351
|
+
if (error.message) {
|
|
352
|
+
return error.message;
|
|
353
|
+
}
|
|
354
|
+
return `${error}`;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
// @ts-ignore
|
|
358
|
+
const handleUncaughtExceptionMonitor$1 = error$1 => {
|
|
359
|
+
info(`[pty host] uncaught exception: ${firstErrorLine(error$1)}`);
|
|
360
|
+
if (isIgnoredError(error$1)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const prettyError = prepare(error$1);
|
|
364
|
+
error(
|
|
365
|
+
// @ts-ignore
|
|
366
|
+
prettyError.codeFrame + NewLine + prettyError.stack + NewLine);
|
|
367
|
+
setExitCode(Error$1);
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const handleDisconnect = () => {
|
|
371
|
+
console.info('[pty host] disconnected');
|
|
372
|
+
exit(Success);
|
|
373
|
+
};
|
|
374
|
+
const handleUncaughtExceptionMonitor = error => {
|
|
375
|
+
// @ts-ignore
|
|
376
|
+
handleUncaughtExceptionMonitor$1(error);
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const main = async () => {
|
|
380
|
+
process.on('uncaughtExceptionMonitor', handleUncaughtExceptionMonitor);
|
|
381
|
+
process.on('disconnect', handleDisconnect);
|
|
382
|
+
register(commandMap);
|
|
383
|
+
await listen();
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/pty-host",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "dist/ptyHostMain.js",
|
|
6
6
|
"bin": "bin/ptyHost.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"keywords": [
|
|
@@ -19,53 +19,15 @@
|
|
|
19
19
|
"node": ">=18"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@lvce-editor/
|
|
23
|
-
"@lvce-editor/
|
|
22
|
+
"@lvce-editor/assert": "^1.3.0",
|
|
23
|
+
"@lvce-editor/command": "^1.2.0",
|
|
24
|
+
"@lvce-editor/ipc": "^11.3.0",
|
|
25
|
+
"@lvce-editor/json-rpc": "^5.2.0",
|
|
24
26
|
"@lvce-editor/pretty-error": "^1.6.0",
|
|
25
|
-
"@lvce-editor/verror": "^1.
|
|
27
|
+
"@lvce-editor/verror": "^1.6.0",
|
|
26
28
|
"debug": "^4.3.7"
|
|
27
29
|
},
|
|
28
30
|
"optionalDependencies": {
|
|
29
31
|
"node-pty": "^1.1.0-beta20"
|
|
30
|
-
},
|
|
31
|
-
"xo": {
|
|
32
|
-
"rules": {
|
|
33
|
-
"unicorn/filename-case": "off",
|
|
34
|
-
"indent": "off",
|
|
35
|
-
"semi": "off",
|
|
36
|
-
"no-unused-vars": "off",
|
|
37
|
-
"unicorn/numeric-separators-style": "off",
|
|
38
|
-
"no-extra-semi": "off",
|
|
39
|
-
"arrow-body-style": "off",
|
|
40
|
-
"padded-blocks": "off",
|
|
41
|
-
"capitalized-comments": "off",
|
|
42
|
-
"padding-line-between-statements": "off",
|
|
43
|
-
"arrow-parens": "off",
|
|
44
|
-
"no-warning-comments": "off",
|
|
45
|
-
"array-bracket-spacing": "off",
|
|
46
|
-
"comma-spacing": "off",
|
|
47
|
-
"unicorn/no-array-callback-reference": "off",
|
|
48
|
-
"comma-dangle": "off",
|
|
49
|
-
"operator-linebreak": "off",
|
|
50
|
-
"no-case-declarations": "off",
|
|
51
|
-
"no-undef": "off",
|
|
52
|
-
"object-curly-spacing": "off",
|
|
53
|
-
"object-shorthand": "off",
|
|
54
|
-
"complexity": "off",
|
|
55
|
-
"no-labels": "off",
|
|
56
|
-
"no-multi-assign": "off",
|
|
57
|
-
"max-params": "off",
|
|
58
|
-
"no-bitwise": "off",
|
|
59
|
-
"unicorn/prefer-math-trunc": "off",
|
|
60
|
-
"no-await-in-loop": "off",
|
|
61
|
-
"unicorn/prefer-add-event-listener": "off",
|
|
62
|
-
"no-unused-expressions": "off",
|
|
63
|
-
"node/prefer-global/process": "off",
|
|
64
|
-
"unicorn/no-for-loop": "off",
|
|
65
|
-
"unicorn/prevent-abbreviations": "off"
|
|
66
|
-
},
|
|
67
|
-
"ignores": [
|
|
68
|
-
"distmin"
|
|
69
|
-
]
|
|
70
32
|
}
|
|
71
33
|
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { AssertionError } from '../AssertionError/AssertionError.js'
|
|
2
|
-
|
|
3
|
-
const getType = (value) => {
|
|
4
|
-
switch (typeof value) {
|
|
5
|
-
case 'number':
|
|
6
|
-
return 'number'
|
|
7
|
-
case 'function':
|
|
8
|
-
return 'function'
|
|
9
|
-
case 'string':
|
|
10
|
-
return 'string'
|
|
11
|
-
case 'object':
|
|
12
|
-
if (value === null) {
|
|
13
|
-
return 'null'
|
|
14
|
-
}
|
|
15
|
-
if (Array.isArray(value)) {
|
|
16
|
-
return 'array'
|
|
17
|
-
}
|
|
18
|
-
return 'object'
|
|
19
|
-
case 'boolean':
|
|
20
|
-
return 'boolean'
|
|
21
|
-
default:
|
|
22
|
-
return 'unknown'
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const object = (value) => {
|
|
27
|
-
const type = getType(value)
|
|
28
|
-
if (type !== 'object') {
|
|
29
|
-
throw new AssertionError('expected value to be of type object')
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const number = (value) => {
|
|
34
|
-
const type = getType(value)
|
|
35
|
-
if (type !== 'number') {
|
|
36
|
-
throw new AssertionError('expected value to be of type number')
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const array = (value) => {
|
|
41
|
-
const type = getType(value)
|
|
42
|
-
if (type !== 'array') {
|
|
43
|
-
throw new AssertionError('expected value to be of type array')
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const string = (value) => {
|
|
48
|
-
const type = getType(value)
|
|
49
|
-
if (type !== 'string') {
|
|
50
|
-
throw new AssertionError('expected value to be of type string')
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const boolean = (value) => {
|
|
55
|
-
const type = getType(value)
|
|
56
|
-
if (type !== 'boolean') {
|
|
57
|
-
throw new AssertionError('expected value to be of type boolean')
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { resolve } from '@lvce-editor/json-rpc'
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const Backslash = '\\'
|
|
2
|
-
export const Dash = '-'
|
|
3
|
-
export const Dot = '.'
|
|
4
|
-
export const EmptyString = ''
|
|
5
|
-
export const NewLine = '\n'
|
|
6
|
-
export const OpenAngleBracket = '<'
|
|
7
|
-
export const Slash = '/'
|
|
8
|
-
export const Space = ' '
|
|
9
|
-
export const Tab = '\t'
|
|
10
|
-
export const Underline = '_'
|
|
11
|
-
export const T = 't'
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as HandleElectronMessagePort from '../HandleElectronMessagePort/HandleElectronMessagePort.js'
|
|
2
|
-
import * as HandleNodeMessagePort from '../HandleNodeMessagePort/HandleNodeMessagePort.js'
|
|
3
|
-
import * as HandleWebSocket from '../HandleWebSocket/HandleWebSocket.js'
|
|
4
|
-
import * as PtyController from '../PtyController/PtyController.js'
|
|
5
|
-
import * as TerminalProcessCommandType from '../TerminalProcessCommandType/TerminalProcessCommandType.js'
|
|
6
|
-
|
|
7
|
-
export const commandMap = {
|
|
8
|
-
[TerminalProcessCommandType.HandleElectronMessagePort]:
|
|
9
|
-
HandleElectronMessagePort.handleElectronMessagePort,
|
|
10
|
-
[TerminalProcessCommandType.HandleNodeMessagePort]:
|
|
11
|
-
HandleNodeMessagePort.handleNodeMessagePort,
|
|
12
|
-
[TerminalProcessCommandType.HandleWebSocket]: HandleWebSocket.handleWebSocket,
|
|
13
|
-
[TerminalProcessCommandType.TerminalCreate]: PtyController.create,
|
|
14
|
-
[TerminalProcessCommandType.TerminalResize]: PtyController.resize,
|
|
15
|
-
[TerminalProcessCommandType.TerminalWrite]: PtyController.write,
|
|
16
|
-
[TerminalProcessCommandType.TerminalDispose]: PtyController.dispose,
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const state = {
|
|
2
|
-
commands: Object.create(null),
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const registerCommand = (key, fn) => {
|
|
6
|
-
state.commands[key] = fn
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const registerCommands = (commandMap) => {
|
|
10
|
-
for (const [key, value] of Object.entries(commandMap)) {
|
|
11
|
-
registerCommand(key, value)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const getCommand = (key) => {
|
|
16
|
-
return state.commands[key]
|
|
17
|
-
}
|
package/src/parts/Debug/Debug.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export const E_COLOR_THEME_NOT_FOUND = 'E_COLOR_THEME_NOT_FOUND'
|
|
2
|
-
export const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND'
|
|
3
|
-
export const E_ICON_THEME_NOT_FOUND = 'E_ICON_THEME_NOT_FOUND'
|
|
4
|
-
export const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE'
|
|
5
|
-
export const E_MANIFEST_NOT_FOUND = 'E_MANIFEST_NOT_FOUND'
|
|
6
|
-
export const E_MODULES_NOT_SUPPORTED_IN_ELECTRON =
|
|
7
|
-
'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'
|
|
8
|
-
export const EACCES = 'EACCES'
|
|
9
|
-
export const ECONNRESET = 'ECONNRESET'
|
|
10
|
-
export const EEXIST = 'EEXIST'
|
|
11
|
-
export const EISDIR = 'EISDIR'
|
|
12
|
-
export const ELOOP = 'ELOOP'
|
|
13
|
-
export const ENOENT = 'ENOENT'
|
|
14
|
-
export const ENOTDIR = 'ENOTDIR'
|
|
15
|
-
export const EPERM = 'EPERM'
|
|
16
|
-
export const EPIPE = 'EPIPE'
|
|
17
|
-
export const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED'
|
|
18
|
-
export const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND'
|
|
19
|
-
export const EXDEV = 'EXDEV'
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import * as Character from '../Character/Character.js'
|
|
2
|
-
import * as ExitCode from '../ExitCode/ExitCode.js'
|
|
3
|
-
import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
|
|
4
|
-
import * as IsIgnoredError from '../IsIgnoredError/IsIgnoredError.js'
|
|
5
|
-
import * as Logger from '../Logger/Logger.js'
|
|
6
|
-
import * as PrettyError from '../PrettyError/PrettyError.js'
|
|
7
|
-
import * as Process from '../Process/Process.js'
|
|
8
|
-
|
|
9
|
-
export const state = {
|
|
10
|
-
seenErrors: [],
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const preparePrettyError = (error) => {
|
|
14
|
-
const cause = error.cause()
|
|
15
|
-
return {
|
|
16
|
-
message: error.message,
|
|
17
|
-
codeFrame: cause.codeFrame,
|
|
18
|
-
stack: cause.stack,
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const printPrettyError = (prettyError) => {
|
|
23
|
-
console.error(
|
|
24
|
-
`${prettyError.message}\n${prettyError.codeFrame}\n${prettyError.stack}`,
|
|
25
|
-
)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const handleError = (error) => {
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
if (state.seenErrors.includes(error.message)) {
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
state.seenErrors.push(error.message)
|
|
35
|
-
const prettyError = preparePrettyError(error)
|
|
36
|
-
// Socket.send({
|
|
37
|
-
// jsonrpc: JsonRpcVersion.Two,
|
|
38
|
-
// method: /* Dialog.showErrorDialogWithOptions */ 'Dialog.showMessage',
|
|
39
|
-
// params: [
|
|
40
|
-
// {
|
|
41
|
-
// message: prettyError.message,
|
|
42
|
-
// codeFrame: prettyError.codeFrame,
|
|
43
|
-
// stack: prettyError.stack,
|
|
44
|
-
// },
|
|
45
|
-
// ],
|
|
46
|
-
// })
|
|
47
|
-
printPrettyError(prettyError)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const firstErrorLine = (error) => {
|
|
51
|
-
if (error.stack) {
|
|
52
|
-
return error.stack.slice(0, GetNewLineIndex.getNewLineIndex(error.stack))
|
|
53
|
-
}
|
|
54
|
-
if (error.message) {
|
|
55
|
-
return error.message
|
|
56
|
-
}
|
|
57
|
-
return `${error}`
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
export const handleUncaughtExceptionMonitor = (error, origin) => {
|
|
62
|
-
Logger.info(`[pty host] uncaught exception: ${firstErrorLine(error)}`)
|
|
63
|
-
if (IsIgnoredError.isIgnoredError(error)) {
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
const prettyError = PrettyError.prepare(error)
|
|
67
|
-
Logger.error(
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
prettyError.codeFrame +
|
|
70
|
-
Character.NewLine +
|
|
71
|
-
prettyError.stack +
|
|
72
|
-
Character.NewLine,
|
|
73
|
-
)
|
|
74
|
-
Process.setExitCode(ExitCode.Error)
|
|
75
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as Character from '../Character/Character.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param {string} string
|
|
6
|
-
* @param {number|undefined} startIndex
|
|
7
|
-
* @returns
|
|
8
|
-
*/
|
|
9
|
-
export const getNewLineIndex = (string, startIndex = undefined) => {
|
|
10
|
-
return string.indexOf(Character.NewLine, startIndex)
|
|
11
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import * as Assert from '../Assert/Assert.js'
|
|
2
|
-
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
3
|
-
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
4
|
-
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
5
|
-
|
|
6
|
-
export const handleElectronMessagePort = async (messagePort) => {
|
|
7
|
-
Assert.object(messagePort)
|
|
8
|
-
const ipc = await IpcChild.listen({
|
|
9
|
-
method: IpcChildType.ElectronMessagePort,
|
|
10
|
-
messagePort,
|
|
11
|
-
})
|
|
12
|
-
HandleIpc.handleIpc(ipc)
|
|
13
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as Assert from '../Assert/Assert.js'
|
|
2
|
-
import * as HandleMessage from '../HandleMessage/HandleMessage.js'
|
|
3
|
-
|
|
4
|
-
export const handleIpc = (ipc) => {
|
|
5
|
-
Assert.object(ipc)
|
|
6
|
-
if ('addEventListener' in ipc) {
|
|
7
|
-
ipc.addEventListener('message', HandleMessage.handleMessage)
|
|
8
|
-
} else if ('onmessage' in ipc) {
|
|
9
|
-
// deprecated
|
|
10
|
-
ipc.onmessage = HandleMessage.handleMessage
|
|
11
|
-
} else if ('on' in ipc) {
|
|
12
|
-
// deprecated
|
|
13
|
-
ipc.on('message', HandleMessage.handleMessage)
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import * as Callback from '../Callback/Callback.js'
|
|
2
|
-
import * as Command from '../Command/Command.js'
|
|
3
|
-
import * as JsonRpc from '../JsonRpc/JsonRpc.js'
|
|
4
|
-
import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
|
|
5
|
-
import * as RequiresSocket from '../RequiresSocket/RequiresSocket.js'
|
|
6
|
-
|
|
7
|
-
const preparePrettyError = (error) => {
|
|
8
|
-
return error
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const logError = (error, prettyError) => {
|
|
12
|
-
PrintPrettyError.printPrettyError(prettyError, `[terminal-process] `)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const handleMessage = (event) => {
|
|
16
|
-
return JsonRpc.handleJsonRpcMessage(
|
|
17
|
-
event.target,
|
|
18
|
-
event.data,
|
|
19
|
-
Command.execute,
|
|
20
|
-
Callback.resolve,
|
|
21
|
-
preparePrettyError,
|
|
22
|
-
logError,
|
|
23
|
-
RequiresSocket.requiresSocket,
|
|
24
|
-
)
|
|
25
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
2
|
-
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
3
|
-
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
4
|
-
|
|
5
|
-
export const handleNodeMessagePort = async (messagePort) => {
|
|
6
|
-
const ipc = await IpcChild.listen({
|
|
7
|
-
method: IpcChildType.NodeMessagePort,
|
|
8
|
-
messagePort,
|
|
9
|
-
})
|
|
10
|
-
HandleIpc.handleIpc(ipc)
|
|
11
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as Assert from '../Assert/Assert.js'
|
|
2
|
-
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
3
|
-
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
4
|
-
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
5
|
-
|
|
6
|
-
export const handleWebSocket = async (handle, request) => {
|
|
7
|
-
Assert.object(handle)
|
|
8
|
-
Assert.object(request)
|
|
9
|
-
const ipc = await IpcChild.listen({
|
|
10
|
-
method: IpcChildType.WebSocket,
|
|
11
|
-
request,
|
|
12
|
-
handle,
|
|
13
|
-
})
|
|
14
|
-
HandleIpc.handleIpc(ipc)
|
|
15
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as IpcChildModule from '../IpcChildModule/IpcChildModule.js'
|
|
2
|
-
|
|
3
|
-
export const listen = async ({ method, ...params }) => {
|
|
4
|
-
const module = await IpcChildModule.getModule(method)
|
|
5
|
-
// @ts-ignore
|
|
6
|
-
const rawIpc = await module.listen(params)
|
|
7
|
-
// @ts-ignore
|
|
8
|
-
if (module.signal) {
|
|
9
|
-
// @ts-ignore
|
|
10
|
-
module.signal(rawIpc)
|
|
11
|
-
}
|
|
12
|
-
// @ts-ignore
|
|
13
|
-
const ipc = module.wrap(rawIpc)
|
|
14
|
-
return ipc
|
|
15
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
IpcChildWithElectronMessagePort,
|
|
3
|
-
IpcChildWithElectronUtilityProcess,
|
|
4
|
-
IpcChildWithNodeForkedProcess,
|
|
5
|
-
IpcChildWithNodeWorker,
|
|
6
|
-
IpcChildWithWebSocket,
|
|
7
|
-
} from '@lvce-editor/ipc'
|
|
8
|
-
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
9
|
-
|
|
10
|
-
export const getModule = (method) => {
|
|
11
|
-
switch (method) {
|
|
12
|
-
case IpcChildType.NodeForkedProcess:
|
|
13
|
-
return IpcChildWithNodeForkedProcess
|
|
14
|
-
case IpcChildType.NodeWorker:
|
|
15
|
-
return IpcChildWithNodeWorker
|
|
16
|
-
case IpcChildType.WebSocket:
|
|
17
|
-
return IpcChildWithWebSocket
|
|
18
|
-
case IpcChildType.ElectronUtilityProcess:
|
|
19
|
-
return IpcChildWithElectronUtilityProcess
|
|
20
|
-
case IpcChildType.ElectronMessagePort:
|
|
21
|
-
return IpcChildWithElectronMessagePort
|
|
22
|
-
default:
|
|
23
|
-
throw new Error('unexpected ipc type')
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export const NodeWorker = 1
|
|
2
|
-
export const NodeForkedProcess = 2
|
|
3
|
-
export const WebSocket = 3
|
|
4
|
-
export const ElectronUtilityProcess = 4
|
|
5
|
-
export const ElectronMessagePort = 5
|
|
6
|
-
export const NodeMessagePort = 6
|
|
7
|
-
|
|
8
|
-
export const Auto = () => {
|
|
9
|
-
const { argv } = process
|
|
10
|
-
if (argv.includes('--ipc-type=node-worker')) {
|
|
11
|
-
return NodeWorker
|
|
12
|
-
}
|
|
13
|
-
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
14
|
-
return NodeForkedProcess
|
|
15
|
-
}
|
|
16
|
-
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
17
|
-
return ElectronUtilityProcess
|
|
18
|
-
}
|
|
19
|
-
throw new Error(`[pty-host] unknown ipc type`)
|
|
20
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
|
|
2
|
-
import * as Process from '../Process/Process.js'
|
|
3
|
-
|
|
4
|
-
export const isIgnoredError = (error) => {
|
|
5
|
-
if (error && error.code === ErrorCodes.EPIPE && !process.connected) {
|
|
6
|
-
// parent process is disposed, ignore
|
|
7
|
-
return true
|
|
8
|
-
}
|
|
9
|
-
if (
|
|
10
|
-
error &&
|
|
11
|
-
error.code === ErrorCodes.ERR_IPC_CHANNEL_CLOSED &&
|
|
12
|
-
!Process.isConnected()
|
|
13
|
-
) {
|
|
14
|
-
// parent process is disposed, ignore
|
|
15
|
-
return true
|
|
16
|
-
}
|
|
17
|
-
return false
|
|
18
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@lvce-editor/json-rpc'
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
2
|
-
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
3
|
-
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
4
|
-
|
|
5
|
-
export const listen = async () => {
|
|
6
|
-
const ipc = await IpcChild.listen({ method: IpcChildType.Auto() })
|
|
7
|
-
HandleIpc.handleIpc(ipc)
|
|
8
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Console } from 'node:console'
|
|
2
|
-
import { createWriteStream } from 'node:fs'
|
|
3
|
-
import { tmpdir } from 'node:os'
|
|
4
|
-
|
|
5
|
-
// TODO mock this module when used in unit tests
|
|
6
|
-
|
|
7
|
-
const state = {
|
|
8
|
-
/**
|
|
9
|
-
* @type {Console|undefined}
|
|
10
|
-
*/
|
|
11
|
-
console: undefined,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const createConsole = () => {
|
|
15
|
-
const logFile = `${tmpdir()}/log-terminal-process.txt`
|
|
16
|
-
const writeStream = createWriteStream(logFile)
|
|
17
|
-
const logger = new Console(writeStream)
|
|
18
|
-
return logger
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const getOrCreateLogger = () => {
|
|
22
|
-
if (!state.console) {
|
|
23
|
-
state.console = createConsole()
|
|
24
|
-
}
|
|
25
|
-
return state.console
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const log = (...args) => {
|
|
29
|
-
const logger = getOrCreateLogger()
|
|
30
|
-
logger.log(...args)
|
|
31
|
-
console.log(...args)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export const info = (...args) => {
|
|
35
|
-
const logger = getOrCreateLogger()
|
|
36
|
-
logger.info(...args)
|
|
37
|
-
console.info(...args)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const warn = (...args) => {
|
|
41
|
-
const logger = getOrCreateLogger()
|
|
42
|
-
logger.warn(...args)
|
|
43
|
-
console.warn(...args)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const error = (...args) => {
|
|
47
|
-
const logger = getOrCreateLogger()
|
|
48
|
-
logger.error(...args)
|
|
49
|
-
console.error(...args)
|
|
50
|
-
}
|
package/src/parts/Main/Main.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as CommandMap from '../CommandMap/CommandMap.js'
|
|
2
|
-
import * as CommandState from '../CommandState/CommandState.js'
|
|
3
|
-
import * as Listen from '../Listen/Listen.js'
|
|
4
|
-
import * as ProcessListeners from '../ProcessListeners/ProcessListeners.js'
|
|
5
|
-
|
|
6
|
-
export const main = async () => {
|
|
7
|
-
process.on(
|
|
8
|
-
'uncaughtExceptionMonitor',
|
|
9
|
-
ProcessListeners.handleUncaughtExceptionMonitor,
|
|
10
|
-
)
|
|
11
|
-
process.on('disconnect', ProcessListeners.handleDisconnect)
|
|
12
|
-
CommandState.registerCommands(CommandMap.commandMap)
|
|
13
|
-
await Listen.listen()
|
|
14
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node-pty'
|
|
2
|
-
import { VError } from '../VError/VError.js'
|
|
3
|
-
import * as Assert from '../Assert/Assert.js'
|
|
4
|
-
|
|
5
|
-
class DataEvent extends Event {
|
|
6
|
-
constructor(data) {
|
|
7
|
-
super('data')
|
|
8
|
-
this.data = data
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
class ExitEvent extends Event {
|
|
13
|
-
constructor(data) {
|
|
14
|
-
super('exit')
|
|
15
|
-
this.data = data
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
class Pty extends EventTarget {
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
* @param {import('node-pty').IPty} pty
|
|
23
|
-
*/
|
|
24
|
-
constructor(pty) {
|
|
25
|
-
super()
|
|
26
|
-
this.pty = pty
|
|
27
|
-
|
|
28
|
-
const handleData = (data) => {
|
|
29
|
-
this.dispatchEvent(new DataEvent(data))
|
|
30
|
-
}
|
|
31
|
-
const handleExit = (data) => {
|
|
32
|
-
this.dispatchEvent(new ExitEvent(data))
|
|
33
|
-
}
|
|
34
|
-
this.pty.onData(handleData)
|
|
35
|
-
this.pty.onExit(handleExit)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
resize(columns, rows) {
|
|
39
|
-
this.pty.resize(columns, rows)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
dispose() {
|
|
43
|
-
this.pty.kill()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
write(data) {
|
|
47
|
-
this.pty.write(data)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
* @param {*} param0
|
|
54
|
-
* @returns {any}
|
|
55
|
-
*/
|
|
56
|
-
export const create = ({ env = {}, cwd, command, args } = {}) => {
|
|
57
|
-
try {
|
|
58
|
-
Assert.string(cwd)
|
|
59
|
-
Assert.string(command)
|
|
60
|
-
Assert.array(args)
|
|
61
|
-
const pty = spawn(command, args, {
|
|
62
|
-
encoding: null,
|
|
63
|
-
cwd,
|
|
64
|
-
// cols: 10,
|
|
65
|
-
// rows: 10,
|
|
66
|
-
})
|
|
67
|
-
const wrapped = new Pty(pty)
|
|
68
|
-
return wrapped
|
|
69
|
-
} catch (error) {
|
|
70
|
-
throw new VError(error, `Failed to create terminal`)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { prepare, prepareJsonError } from '@lvce-editor/pretty-error'
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export const exit = (code) => {
|
|
2
|
-
process.exit(code)
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const setExitCode = (exitCode) => {
|
|
6
|
-
process.exitCode = exitCode
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const { argv } = process
|
|
10
|
-
|
|
11
|
-
export const isConnected = () => {
|
|
12
|
-
return process.connected
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const getPid = () => {
|
|
16
|
-
return process.pid
|
|
17
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as ErrorHandling from '../ErrorHandling/ErrorHandling.js'
|
|
2
|
-
import * as ExitCode from '../ExitCode/ExitCode.js'
|
|
3
|
-
import * as Process from '../Process/Process.js'
|
|
4
|
-
|
|
5
|
-
export const handleDisconnect = () => {
|
|
6
|
-
console.info('[pty host] disconnected')
|
|
7
|
-
Process.exit(ExitCode.Success)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const handleSigTerm = () => {
|
|
11
|
-
console.info('[pty host] sigterm')
|
|
12
|
-
Process.exit(ExitCode.Success)
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const handleUncaughtExceptionMonitor = (error) => {
|
|
16
|
-
ErrorHandling.handleUncaughtExceptionMonitor(error)
|
|
17
|
-
}
|
package/src/parts/Pty/Pty.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '../NodePty/NodePty.js'
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as Assert from '../Assert/Assert.js'
|
|
2
|
-
import * as Debug from '../Debug/Debug.js'
|
|
3
|
-
import * as Pty from '../Pty/Pty.js'
|
|
4
|
-
import * as PtyState from '../PtyState/PtyState.js'
|
|
5
|
-
|
|
6
|
-
// TODO maybe merge pty and pty controller
|
|
7
|
-
export const create = (ipc, id, cwd, command, args) => {
|
|
8
|
-
Assert.number(id)
|
|
9
|
-
Assert.string(cwd)
|
|
10
|
-
Assert.string(command)
|
|
11
|
-
Assert.array(args)
|
|
12
|
-
Assert.object(ipc)
|
|
13
|
-
Debug.debug(`create ${id} ${cwd}`)
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
const pty = Pty.create({ cwd, command, args })
|
|
16
|
-
const handleData = (event) => {
|
|
17
|
-
ipc.send({
|
|
18
|
-
jsonrpc: '2.0',
|
|
19
|
-
method: 'Viewlet.send',
|
|
20
|
-
params: [id, 'handleData', event.data],
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
pty.addEventListener('data', handleData)
|
|
25
|
-
PtyState.set(id, pty)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const write = (id, data) => {
|
|
29
|
-
const pty = PtyState.get(id)
|
|
30
|
-
if (!pty) {
|
|
31
|
-
throw new Error(`pty ${id} not found`)
|
|
32
|
-
}
|
|
33
|
-
pty.write(data)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const resize = (id, columns, rows) => {
|
|
37
|
-
const pty = PtyState.get(id)
|
|
38
|
-
if (!pty) {
|
|
39
|
-
throw new Error(`pty ${id} not found`)
|
|
40
|
-
}
|
|
41
|
-
pty.resize(columns, rows)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const dispose = (id) => {
|
|
45
|
-
const pty = PtyState.get(id)
|
|
46
|
-
if (!pty) {
|
|
47
|
-
throw new Error(`pty ${id} not found`)
|
|
48
|
-
}
|
|
49
|
-
pty.dispose()
|
|
50
|
-
PtyState.remove(id)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const disposeAll = () => {
|
|
54
|
-
for (const id in PtyState.getAll()) {
|
|
55
|
-
dispose(id)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export const state = {
|
|
2
|
-
ptyMap: Object.create(null),
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const set = (id, pty) => {
|
|
6
|
-
state.ptyMap[id] = pty
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const get = (id) => {
|
|
10
|
-
return state.ptyMap[id]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const remove = (id) => {
|
|
14
|
-
delete state.ptyMap[id]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const getAll = () => {
|
|
18
|
-
return state.ptyMap
|
|
19
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const HandleElectronMessagePort =
|
|
2
|
-
'HandleElectronMessagePort.handleElectronMessagePort'
|
|
3
|
-
export const HandleNodeMessagePort =
|
|
4
|
-
'HandleNodeMessagePort.handleNodeMessagePort'
|
|
5
|
-
export const HandleWebSocket = 'HandleWebSocket.handleWebSocket'
|
|
6
|
-
export const TerminalCreate = 'Terminal.create'
|
|
7
|
-
export const TerminalResize = 'Terminal.resize'
|
|
8
|
-
export const TerminalWrite = 'Terminal.write'
|
|
9
|
-
export const TerminalDispose = 'Terminal.dispose'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@lvce-editor/verror'
|
package/src/ptyHostMain.js
DELETED