@lvce-editor/pty-host 1.0.1 → 1.2.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/package.json +2 -2
- package/src/parts/CommandMap/CommandMap.js +4 -2
- package/src/parts/ErrorCodes/ErrorCodes.js +2 -1
- package/src/parts/ErrorHandling/ErrorHandling.js +10 -3
- package/src/parts/HandleWebSocket/HandleWebSocket.js +2 -2
- package/src/parts/IsIgnoredError/IsIgnoredError.js +5 -1
- package/src/parts/Main/Main.js +4 -1
- package/src/parts/NodePty/NodePty.js +48 -26
- package/src/parts/PrintPrettyError/PrintPrettyError.js +3 -1
- package/src/parts/PtyController/PtyController.js +7 -6
- package/src/parts/TerminalProcessCommandType/TerminalProcessCommandType.js +4 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/pty-host",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "src/ptyHostMain.js",
|
|
6
6
|
"bin": "bin/ptyHost.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"node": ">=18"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@lvce-editor/ipc": "^
|
|
22
|
+
"@lvce-editor/ipc": "^9.1.0",
|
|
23
23
|
"@lvce-editor/json-rpc": "^1.3.0",
|
|
24
24
|
"@lvce-editor/pretty-error": "^1.5.0",
|
|
25
25
|
"@lvce-editor/verror": "^1.2.0",
|
|
@@ -5,8 +5,10 @@ import * as PtyController from '../PtyController/PtyController.js'
|
|
|
5
5
|
import * as TerminalProcessCommandType from '../TerminalProcessCommandType/TerminalProcessCommandType.js'
|
|
6
6
|
|
|
7
7
|
export const commandMap = {
|
|
8
|
-
[TerminalProcessCommandType.HandleElectronMessagePort]:
|
|
9
|
-
|
|
8
|
+
[TerminalProcessCommandType.HandleElectronMessagePort]:
|
|
9
|
+
HandleElectronMessagePort.handleElectronMessagePort,
|
|
10
|
+
[TerminalProcessCommandType.HandleNodeMessagePort]:
|
|
11
|
+
HandleNodeMessagePort.handleNodeMessagePort,
|
|
10
12
|
[TerminalProcessCommandType.HandleWebSocket]: HandleWebSocket.handleWebSocket,
|
|
11
13
|
[TerminalProcessCommandType.TerminalCreate]: PtyController.create,
|
|
12
14
|
[TerminalProcessCommandType.TerminalResize]: PtyController.resize,
|
|
@@ -3,7 +3,8 @@ export const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND'
|
|
|
3
3
|
export const E_ICON_THEME_NOT_FOUND = 'E_ICON_THEME_NOT_FOUND'
|
|
4
4
|
export const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE'
|
|
5
5
|
export const E_MANIFEST_NOT_FOUND = 'E_MANIFEST_NOT_FOUND'
|
|
6
|
-
export const E_MODULES_NOT_SUPPORTED_IN_ELECTRON =
|
|
6
|
+
export const E_MODULES_NOT_SUPPORTED_IN_ELECTRON =
|
|
7
|
+
'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'
|
|
7
8
|
export const EACCES = 'EACCES'
|
|
8
9
|
export const ECONNRESET = 'ECONNRESET'
|
|
9
10
|
export const EEXIST = 'EEXIST'
|
|
@@ -20,7 +20,9 @@ const preparePrettyError = (error) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const printPrettyError = (prettyError) => {
|
|
23
|
-
console.error(
|
|
23
|
+
console.error(
|
|
24
|
+
`${prettyError.message}\n${prettyError.codeFrame}\n${prettyError.stack}`,
|
|
25
|
+
)
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export const handleError = (error) => {
|
|
@@ -62,7 +64,12 @@ export const handleUncaughtExceptionMonitor = (error, origin) => {
|
|
|
62
64
|
return
|
|
63
65
|
}
|
|
64
66
|
const prettyError = PrettyError.prepare(error)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
Logger.error(
|
|
68
|
+
// @ts-ignore
|
|
69
|
+
prettyError.codeFrame +
|
|
70
|
+
Character.NewLine +
|
|
71
|
+
prettyError.stack +
|
|
72
|
+
Character.NewLine,
|
|
73
|
+
)
|
|
67
74
|
Process.setExitCode(ExitCode.Error)
|
|
68
75
|
}
|
|
@@ -3,9 +3,9 @@ import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
|
3
3
|
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
4
4
|
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
5
5
|
|
|
6
|
-
export const handleWebSocket = async (
|
|
7
|
-
Assert.object(request)
|
|
6
|
+
export const handleWebSocket = async (handle, request) => {
|
|
8
7
|
Assert.object(handle)
|
|
8
|
+
Assert.object(request)
|
|
9
9
|
const ipc = await IpcChild.listen({
|
|
10
10
|
method: IpcChildType.WebSocket,
|
|
11
11
|
request,
|
|
@@ -6,7 +6,11 @@ export const isIgnoredError = (error) => {
|
|
|
6
6
|
// parent process is disposed, ignore
|
|
7
7
|
return true
|
|
8
8
|
}
|
|
9
|
-
if (
|
|
9
|
+
if (
|
|
10
|
+
error &&
|
|
11
|
+
error.code === ErrorCodes.ERR_IPC_CHANNEL_CLOSED &&
|
|
12
|
+
!Process.isConnected()
|
|
13
|
+
) {
|
|
10
14
|
// parent process is disposed, ignore
|
|
11
15
|
return true
|
|
12
16
|
}
|
package/src/parts/Main/Main.js
CHANGED
|
@@ -4,7 +4,10 @@ import * as Listen from '../Listen/Listen.js'
|
|
|
4
4
|
import * as ProcessListeners from '../ProcessListeners/ProcessListeners.js'
|
|
5
5
|
|
|
6
6
|
export const main = async () => {
|
|
7
|
-
process.on(
|
|
7
|
+
process.on(
|
|
8
|
+
'uncaughtExceptionMonitor',
|
|
9
|
+
ProcessListeners.handleUncaughtExceptionMonitor,
|
|
10
|
+
)
|
|
8
11
|
process.on('disconnect', ProcessListeners.handleDisconnect)
|
|
9
12
|
CommandState.registerCommands(CommandMap.commandMap)
|
|
10
13
|
await Listen.listen()
|
|
@@ -2,6 +2,52 @@ import { spawn } from 'node-pty'
|
|
|
2
2
|
import { VError } from '../VError/VError.js'
|
|
3
3
|
import * as Assert from '../Assert/Assert.js'
|
|
4
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
|
+
|
|
5
51
|
// @ts-ignore
|
|
6
52
|
export const create = ({ env = {}, cwd, command, args } = {}) => {
|
|
7
53
|
try {
|
|
@@ -14,33 +60,9 @@ export const create = ({ env = {}, cwd, command, args } = {}) => {
|
|
|
14
60
|
// cols: 10,
|
|
15
61
|
// rows: 10,
|
|
16
62
|
})
|
|
17
|
-
|
|
63
|
+
const wrapped = new Pty(pty)
|
|
64
|
+
return wrapped
|
|
18
65
|
} catch (error) {
|
|
19
66
|
throw new VError(error, `Failed to create terminal`)
|
|
20
67
|
}
|
|
21
68
|
}
|
|
22
|
-
|
|
23
|
-
export const onData = (pty, fn) => {
|
|
24
|
-
Assert.object(pty)
|
|
25
|
-
pty.onData(fn)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const write = (pty, data) => {
|
|
29
|
-
try {
|
|
30
|
-
Assert.object(pty)
|
|
31
|
-
pty.write(data)
|
|
32
|
-
} catch (error) {
|
|
33
|
-
throw new VError(error, `Failed to write data to terminal`)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export const resize = (pty, columns, rows) => {
|
|
38
|
-
Assert.object(pty)
|
|
39
|
-
Assert.number(columns)
|
|
40
|
-
Assert.number(rows)
|
|
41
|
-
pty.resize(columns, rows)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const dispose = (pty) => {
|
|
45
|
-
pty.kill()
|
|
46
|
-
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as Logger from '../Logger/Logger.js'
|
|
2
2
|
|
|
3
3
|
export const printPrettyError = (prettyError, prefix = '') => {
|
|
4
|
-
Logger.error(
|
|
4
|
+
Logger.error(
|
|
5
|
+
`${prefix}${prettyError.type}: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}\n`,
|
|
6
|
+
)
|
|
5
7
|
}
|
|
@@ -12,14 +12,15 @@ export const create = (ipc, id, cwd, command, args) => {
|
|
|
12
12
|
Assert.object(ipc)
|
|
13
13
|
Debug.debug(`create ${id} ${cwd}`)
|
|
14
14
|
const pty = Pty.create({ cwd, command, args })
|
|
15
|
-
const handleData = (
|
|
15
|
+
const handleData = (event) => {
|
|
16
16
|
ipc.send({
|
|
17
17
|
jsonrpc: '2.0',
|
|
18
18
|
method: 'Viewlet.send',
|
|
19
|
-
params: [id, 'handleData', data],
|
|
19
|
+
params: [id, 'handleData', event.data],
|
|
20
20
|
})
|
|
21
21
|
}
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
pty.addEventListener('data', handleData)
|
|
23
24
|
PtyState.set(id, pty)
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -28,7 +29,7 @@ export const write = (id, data) => {
|
|
|
28
29
|
if (!pty) {
|
|
29
30
|
throw new Error(`pty ${id} not found`)
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
+
pty.write(data)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export const resize = (id, columns, rows) => {
|
|
@@ -36,7 +37,7 @@ export const resize = (id, columns, rows) => {
|
|
|
36
37
|
if (!pty) {
|
|
37
38
|
throw new Error(`pty ${id} not found`)
|
|
38
39
|
}
|
|
39
|
-
|
|
40
|
+
pty.resize(columns, rows)
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export const dispose = (id) => {
|
|
@@ -44,7 +45,7 @@ export const dispose = (id) => {
|
|
|
44
45
|
if (!pty) {
|
|
45
46
|
throw new Error(`pty ${id} not found`)
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
pty.dispose()
|
|
48
49
|
PtyState.remove(id)
|
|
49
50
|
}
|
|
50
51
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export const HandleElectronMessagePort =
|
|
2
|
-
|
|
1
|
+
export const HandleElectronMessagePort =
|
|
2
|
+
'HandleElectronMessagePort.handleElectronMessagePort'
|
|
3
|
+
export const HandleNodeMessagePort =
|
|
4
|
+
'HandleNodeMessagePort.handleNodeMessagePort'
|
|
3
5
|
export const HandleWebSocket = 'HandleWebSocket.handleWebSocket'
|
|
4
6
|
export const TerminalCreate = 'Terminal.create'
|
|
5
7
|
export const TerminalResize = 'Terminal.resize'
|