@lvce-editor/shared-process 0.15.17 → 0.15.18
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/config/builtinCommands.json +4 -0
- package/package.json +4 -4
- package/src/parts/AttachDebugger/AttachDebugger.ipc.js +7 -0
- package/src/parts/AttachDebugger/AttachDebugger.js +6 -0
- package/src/parts/Callback/Callback.js +17 -26
- package/src/parts/CleanStack/CleanStack.js +4 -0
- package/src/parts/CommandNotFoundError/CommandNotFoundError.js +2 -1
- package/src/parts/CreateCpuProfile/CreateCpuProfile.js +59 -0
- package/src/parts/DestroySocket/DestroySocket.js +5 -0
- package/src/parts/DevtoolsProtocolRpc/DevtoolsProtocolRpc.js +32 -0
- package/src/parts/ElectronInitialize/ElectronInitialize.js +9 -38
- package/src/parts/ErrorHandling/ErrorHandling.js +12 -14
- package/src/parts/GetActualPath/GetActualPath.js +8 -0
- package/src/parts/GetErrorResponse/GetErrorResponse.js +5 -3
- package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +41 -0
- package/src/parts/GetResponse/GetResponse.js +3 -3
- package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.ipc.js +7 -0
- package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.js +14 -0
- package/src/parts/HandleIpc/HandleIpc.js +4 -4
- package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.ipc.js +7 -0
- package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.js +12 -0
- package/src/parts/HandleWebSocket/HandleWebSocket.js +15 -14
- package/src/parts/HandleWebSocketForSharedProcess/HandleWebSocketForSharedProcess.js +10 -3
- package/src/parts/Id/Id.js +7 -0
- package/src/parts/IpcChild/IpcChild.js +3 -2
- package/src/parts/IpcChildModule/IpcChildModule.js +6 -0
- package/src/parts/IpcChildType/IpcChildType.js +3 -0
- package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +41 -0
- package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +25 -1
- package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +21 -1
- package/src/parts/IpcChildWithNodeMessagePort/IpcChildWithNodeMessagePort.js +41 -0
- package/src/parts/IpcChildWithNodeWorker/IpcChildWithNodeWorker.js +17 -1
- package/src/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +51 -0
- package/src/parts/IpcError/IpcError.js +6 -0
- package/src/parts/IsMessagePort/IsMessagePort.js +3 -0
- package/src/parts/IsMessagePortMain/IsMessagePortMain.js +3 -0
- package/src/parts/IsSocket/IsSocket.js +5 -0
- package/src/parts/IsWebSocketOpen/IsWebSocketOpen.js +5 -0
- package/src/parts/JsonRpc/JsonRpc.js +18 -22
- package/src/parts/Module/Module.js +8 -0
- package/src/parts/ModuleId/ModuleId.js +4 -0
- package/src/parts/ModuleMap/ModuleMap.js +12 -0
- package/src/parts/PrettyError/PrettyError.js +3 -19
- package/src/parts/Process/Process.ipc.js +1 -0
- package/src/parts/Process/Process.js +8 -0
- package/src/parts/ProcessDisplayName/ProcessDisplayName.js +1 -0
- package/src/parts/RequiresSocket/RequiresSocket.js +0 -1
- package/src/parts/Signal/Signal.js +2 -0
- package/src/parts/Terminal/Terminal.js +29 -16
- package/src/parts/TerminalState/TerminalState.js +15 -0
- package/src/parts/WebSocketServer/WebSocketServer.js +7 -2
- package/src/sharedProcessMain.cjs +1 -0
- package/src/sharedProcessMain.js +2 -1
- package/src/parts/Socket/Socket.js +0 -77
|
@@ -230,6 +230,10 @@
|
|
|
230
230
|
"id": "RebuildNodePty.rebuildNodePty",
|
|
231
231
|
"label": "Developer: Rebuild Node Pty"
|
|
232
232
|
},
|
|
233
|
+
{
|
|
234
|
+
"id": "DebugSharedProcess.debugSharedProcess",
|
|
235
|
+
"label": "Developer: Debug Shared Process"
|
|
236
|
+
},
|
|
233
237
|
{
|
|
234
238
|
"id": "Window.reload",
|
|
235
239
|
"label": "Window: Reload",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.18",
|
|
4
4
|
"description": "Utility package for @lvce-editor/server",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@babel/code-frame": "^7.21.4",
|
|
20
|
-
"@lvce-editor/extension-host": "0.15.
|
|
21
|
-
"@lvce-editor/extension-host-helper-process": "0.15.
|
|
22
|
-
"@lvce-editor/pty-host": "0.15.
|
|
20
|
+
"@lvce-editor/extension-host": "0.15.18",
|
|
21
|
+
"@lvce-editor/extension-host-helper-process": "0.15.18",
|
|
22
|
+
"@lvce-editor/pty-host": "0.15.18",
|
|
23
23
|
"debug": "^4.3.4",
|
|
24
24
|
"execa": "^7.1.1",
|
|
25
25
|
"exit-hook": "^3.2.0",
|
|
@@ -1,48 +1,39 @@
|
|
|
1
|
+
import * as Id from '../Id/Id.js'
|
|
2
|
+
|
|
1
3
|
export const state = {
|
|
2
4
|
callbacks: Object.create(null),
|
|
3
5
|
onceListeners: new Set(),
|
|
4
|
-
id: 2,
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export const register = (resolve, reject) => {
|
|
8
|
-
state.callbacks[++state.id] = {
|
|
9
|
-
resolve,
|
|
10
|
-
reject,
|
|
11
|
-
}
|
|
12
|
-
return state.id
|
|
13
6
|
}
|
|
14
7
|
|
|
15
|
-
export const
|
|
16
|
-
|
|
8
|
+
export const registerPromise = () => {
|
|
9
|
+
const id = Id.create()
|
|
10
|
+
const promise = new Promise((resolve, reject) => {
|
|
11
|
+
state.callbacks[id] = { resolve, reject }
|
|
12
|
+
})
|
|
13
|
+
return { id, promise }
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
// TODO merge resolve and resolveEmpty
|
|
20
17
|
export const resolve = (id, args) => {
|
|
21
|
-
|
|
18
|
+
const { callbacks } = state
|
|
19
|
+
if (!(id in callbacks)) {
|
|
22
20
|
console.warn(`callback ${id} may already be disposed`)
|
|
23
21
|
return
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export const resolveEmpty = (id) => {
|
|
29
|
-
if (!(id in state.callbacks)) {
|
|
30
|
-
console.warn(`callback (resolved) ${id} may already be disposed`)
|
|
31
|
-
return
|
|
32
|
-
}
|
|
33
|
-
state.callbacks[id].resolve()
|
|
23
|
+
callbacks[id].resolve(args)
|
|
24
|
+
delete callbacks[id]
|
|
34
25
|
}
|
|
35
26
|
|
|
36
27
|
export const reject = (id, error) => {
|
|
37
|
-
|
|
28
|
+
const { callbacks } = state
|
|
29
|
+
if (!(id in callbacks)) {
|
|
38
30
|
console.warn(`callback (rejected) ${id} may already be disposed`)
|
|
39
31
|
return
|
|
40
32
|
}
|
|
41
|
-
|
|
33
|
+
callbacks[id].reject(error)
|
|
34
|
+
delete callbacks[id]
|
|
42
35
|
}
|
|
43
36
|
|
|
44
37
|
export const isAllEmpty = () => {
|
|
45
|
-
return (
|
|
46
|
-
Object.keys(state.callbacks).length === 0 && state.onceListeners.size === 0
|
|
47
|
-
)
|
|
38
|
+
return Object.keys(state.callbacks).length === 0 && state.onceListeners.size === 0
|
|
48
39
|
}
|
|
@@ -7,6 +7,7 @@ const RE_GET_RESPONSE = /^\s*at async getResponse/
|
|
|
7
7
|
const RE_WEBSOCKET_HANDLE_MESSAGE = /^\s*at async WebSocket.handleMessage/
|
|
8
8
|
const RE_EXECUTE_COMMAND_ASYNC = /^\s*at executeCommandAsync/
|
|
9
9
|
const RE_HANDLE_OTHER_MESSAGES_FROM_MESSAGE_PORT = /^\s*at async MessagePort\.handleOtherMessagesFromMessagePort/
|
|
10
|
+
const RE_ASSERT = /^\s*at .*\/Assert\.js/
|
|
10
11
|
|
|
11
12
|
const isInternalLine = (line) => {
|
|
12
13
|
return line.includes('node:') || RE_AT_PROMISE_INDEX.test(line) || line.includes('node_modules/ws')
|
|
@@ -18,6 +19,9 @@ const isRelevantLine = (line) => {
|
|
|
18
19
|
|
|
19
20
|
const isApplicationUsefulLine = (line, index) => {
|
|
20
21
|
if (index === 0) {
|
|
22
|
+
if (RE_ASSERT.test(line)) {
|
|
23
|
+
return false
|
|
24
|
+
}
|
|
21
25
|
return true
|
|
22
26
|
}
|
|
23
27
|
if (RE_GET_RESPONSE.test(line)) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
|
|
2
|
+
import * as ProcessDisplayName from '../ProcessDisplayName/ProcessDisplayName.js'
|
|
2
3
|
|
|
3
4
|
export class CommandNotFoundError extends Error {
|
|
4
5
|
constructor(id) {
|
|
5
|
-
super(`command ${id} not found`)
|
|
6
|
+
super(`command ${id} not found in ${ProcessDisplayName.processDisplayName}`)
|
|
6
7
|
this.name = 'CommandNotFoundError'
|
|
7
8
|
this.code = ErrorCodes.E_COMMAND_NOT_FOUND
|
|
8
9
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { writeFile } from 'fs/promises'
|
|
2
|
+
import got from 'got'
|
|
3
|
+
import { tmpdir } from 'os'
|
|
4
|
+
import { join } from 'path'
|
|
5
|
+
import { WebSocket } from 'ws'
|
|
6
|
+
import * as DevtoolsProtocolRpc from '../DevtoolsProtocolRpc/DevtoolsProtocolRpc.js'
|
|
7
|
+
|
|
8
|
+
const createConnection = (webSocketDebuggerUrl) => {
|
|
9
|
+
const webSocket = new WebSocket(webSocketDebuggerUrl)
|
|
10
|
+
// console.log({ webSocket })
|
|
11
|
+
return {
|
|
12
|
+
on(event, listener) {
|
|
13
|
+
if (event === 'message') {
|
|
14
|
+
const wrappedListener = (string) => {
|
|
15
|
+
listener(JSON.parse(string))
|
|
16
|
+
}
|
|
17
|
+
webSocket.on(event, wrappedListener)
|
|
18
|
+
} else {
|
|
19
|
+
webSocket.on(event, listener)
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
send(message) {
|
|
23
|
+
webSocket.send(JSON.stringify(message))
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const createCpuProfile = async (pid) => {
|
|
29
|
+
// AttachDebugger.attachDebugger(pid)
|
|
30
|
+
const response = await got('http://localhost:9229/json/list').json()
|
|
31
|
+
const first = response[0]
|
|
32
|
+
const webSocketDebuggerUrl = first.webSocketDebuggerUrl
|
|
33
|
+
const ipc = createConnection(webSocketDebuggerUrl)
|
|
34
|
+
|
|
35
|
+
await new Promise((r) => {
|
|
36
|
+
ipc.on('open', r)
|
|
37
|
+
})
|
|
38
|
+
const rpc = DevtoolsProtocolRpc.create(ipc)
|
|
39
|
+
const result = await rpc.invoke('Debugger.enable')
|
|
40
|
+
const debuggerId = result.result.debuggerId
|
|
41
|
+
console.log({ debuggerId })
|
|
42
|
+
const p = await rpc.invoke('Profiler.enable')
|
|
43
|
+
await rpc.invoke('Profiler.start')
|
|
44
|
+
await new Promise((r) => {
|
|
45
|
+
setTimeout(r, 10000)
|
|
46
|
+
})
|
|
47
|
+
const profileResult = await rpc.invoke('Profiler.stop')
|
|
48
|
+
console.log({ profileResult })
|
|
49
|
+
const profile = profileResult.result.profile
|
|
50
|
+
const profilePath = join(tmpdir(), 'node-profile.cpuprofile')
|
|
51
|
+
const profileString = JSON.stringify(profile)
|
|
52
|
+
await writeFile(profilePath, profileString)
|
|
53
|
+
console.log('finished')
|
|
54
|
+
// const value = await rpc.invoke('Runtime.evaluate', {
|
|
55
|
+
// expression: '1+1',
|
|
56
|
+
// })
|
|
57
|
+
// await rpc.invoke('Debugger.pause')
|
|
58
|
+
// console.log({ value })
|
|
59
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const Id = {
|
|
2
|
+
id: 1,
|
|
3
|
+
create() {
|
|
4
|
+
return this.id++
|
|
5
|
+
},
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const create = (ipc) => {
|
|
9
|
+
const callbacks = Object.create(null)
|
|
10
|
+
const handleMessage = (message) => {
|
|
11
|
+
if ('result' in message) {
|
|
12
|
+
const callback = callbacks[message.id]
|
|
13
|
+
callback(message)
|
|
14
|
+
delete callbacks[message.id]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
ipc.on('message', handleMessage)
|
|
18
|
+
return {
|
|
19
|
+
invoke(method, params = {}) {
|
|
20
|
+
const id = Id.create()
|
|
21
|
+
const promise = new Promise((resolve, reject) => {
|
|
22
|
+
callbacks[id] = resolve
|
|
23
|
+
})
|
|
24
|
+
ipc.send({
|
|
25
|
+
method,
|
|
26
|
+
id,
|
|
27
|
+
params,
|
|
28
|
+
})
|
|
29
|
+
return promise
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -1,40 +1,11 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
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
4
|
|
|
5
|
-
export const electronInitialize = (port, folder) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
case 'close':
|
|
12
|
-
port.on('close', listener)
|
|
13
|
-
break
|
|
14
|
-
case 'message':
|
|
15
|
-
port.on('message', listener)
|
|
16
|
-
break
|
|
17
|
-
default:
|
|
18
|
-
console.warn('socket event not implemented', event, listener)
|
|
19
|
-
break
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
const handleOtherMessagesFromMessagePort = async (message) => {
|
|
24
|
-
// console.log('got port message', message)
|
|
25
|
-
if (message.result) {
|
|
26
|
-
Callback.resolve(message.id, message.result)
|
|
27
|
-
} else if (message.method) {
|
|
28
|
-
if (message.id) {
|
|
29
|
-
const response = await GetResponse.getResponse(message, fakeSocket)
|
|
30
|
-
port.postMessage(response)
|
|
31
|
-
} else {
|
|
32
|
-
console.warn(`[shared process] sending messages without id is deprecated: ${message.method}`)
|
|
33
|
-
Command.execute(message.method, fakeSocket, ...message.params)
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
console.warn('unknown message', message)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
port.on('message', handleOtherMessagesFromMessagePort)
|
|
5
|
+
export const electronInitialize = async (port, folder) => {
|
|
6
|
+
const ipc = await IpcChild.listen({
|
|
7
|
+
method: IpcChildType.NodeMessagePort,
|
|
8
|
+
messagePort: port,
|
|
9
|
+
})
|
|
10
|
+
HandleIpc.handleIpc(ipc)
|
|
40
11
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import * as ExitCode from '../ExitCode/ExitCode.js'
|
|
2
|
+
import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
|
|
2
3
|
import * as IsIgnoredError from '../IsIgnoredError/IsIgnoredError.js'
|
|
3
|
-
import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
|
|
4
4
|
import * as Logger from '../Logger/Logger.js'
|
|
5
5
|
import * as PrettyError from '../PrettyError/PrettyError.js'
|
|
6
6
|
import * as Process from '../Process/Process.js'
|
|
7
|
-
import * as Socket from '../Socket/Socket.js'
|
|
8
|
-
import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
|
|
9
7
|
|
|
10
8
|
export const state = {
|
|
11
9
|
seenErrors: [],
|
|
@@ -30,17 +28,17 @@ export const handleError = (error) => {
|
|
|
30
28
|
}
|
|
31
29
|
state.seenErrors.push(error.message)
|
|
32
30
|
const prettyError = preparePrettyError(error)
|
|
33
|
-
Socket.send({
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
31
|
+
// Socket.send({
|
|
32
|
+
// jsonrpc: JsonRpcVersion.Two,
|
|
33
|
+
// method: /* Dialog.showErrorDialogWithOptions */ 'Dialog.showMessage',
|
|
34
|
+
// params: [
|
|
35
|
+
// {
|
|
36
|
+
// message: prettyError.message,
|
|
37
|
+
// codeFrame: prettyError.codeFrame,
|
|
38
|
+
// stack: prettyError.stack,
|
|
39
|
+
// },
|
|
40
|
+
// ],
|
|
41
|
+
// })
|
|
44
42
|
printPrettyError(prettyError)
|
|
45
43
|
}
|
|
46
44
|
|
|
@@ -12,7 +12,11 @@ const shouldLogError = (error) => {
|
|
|
12
12
|
return true
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export const getErrorResponse = (message, error) => {
|
|
15
|
+
export const getErrorResponse = (message, error, ipc) => {
|
|
16
|
+
const prettyError = PrettyError.prepare(error)
|
|
17
|
+
if (shouldLogError(error) && (!ipc || ipc.shouldLogError !== false)) {
|
|
18
|
+
PrintPrettyError.printPrettyError(prettyError, `[shared-process] `)
|
|
19
|
+
}
|
|
16
20
|
if (error && error instanceof CommandNotFoundError) {
|
|
17
21
|
return {
|
|
18
22
|
jsonrpc: JsonRpcVersion.Two,
|
|
@@ -37,8 +41,6 @@ export const getErrorResponse = (message, error) => {
|
|
|
37
41
|
},
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
|
-
const prettyError = PrettyError.prepare(error)
|
|
41
|
-
PrintPrettyError.printPrettyError(prettyError, `[shared-process] `)
|
|
42
44
|
return {
|
|
43
45
|
jsonrpc: JsonRpcVersion.Two,
|
|
44
46
|
id: message.id,
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as FirstWebSocketEventType from '../FirstWebSocketEventType/FirstWebSocketEventType.js'
|
|
2
|
+
import { WebSocket } from 'ws'
|
|
3
|
+
|
|
4
|
+
export const getFirstWebSocketEvent = async (webSocket) => {
|
|
5
|
+
switch (webSocket.readyState) {
|
|
6
|
+
case WebSocket.OPEN:
|
|
7
|
+
return {
|
|
8
|
+
type: FirstWebSocketEventType.Open,
|
|
9
|
+
event: undefined,
|
|
10
|
+
}
|
|
11
|
+
case WebSocket.CLOSED:
|
|
12
|
+
return {
|
|
13
|
+
type: FirstWebSocketEventType.Close,
|
|
14
|
+
event: undefined,
|
|
15
|
+
}
|
|
16
|
+
default:
|
|
17
|
+
break
|
|
18
|
+
}
|
|
19
|
+
const { type, event } = await new Promise((resolve) => {
|
|
20
|
+
const cleanup = (value) => {
|
|
21
|
+
webSocket.off('open', handleOpen)
|
|
22
|
+
webSocket.off('close', handleClose)
|
|
23
|
+
resolve(value)
|
|
24
|
+
}
|
|
25
|
+
const handleOpen = (event) => {
|
|
26
|
+
cleanup({
|
|
27
|
+
type: FirstWebSocketEventType.Open,
|
|
28
|
+
event,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
const handleClose = (event) => {
|
|
32
|
+
cleanup({
|
|
33
|
+
type: FirstWebSocketEventType.Close,
|
|
34
|
+
event,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
webSocket.on('open', handleOpen)
|
|
38
|
+
webSocket.on('close', handleClose)
|
|
39
|
+
})
|
|
40
|
+
return { type, event }
|
|
41
|
+
}
|
|
@@ -3,13 +3,13 @@ import * as GetErrorResponse from '../GetErrorResponse/GetErrorResponse.js'
|
|
|
3
3
|
import * as GetSuccessResponse from '../GetSuccessResponse/GetSuccessResponse.js'
|
|
4
4
|
import * as RequiresSocket from '../RequiresSocket/RequiresSocket.js'
|
|
5
5
|
|
|
6
|
-
export const getResponse = async (message,
|
|
6
|
+
export const getResponse = async (message, ipc) => {
|
|
7
7
|
try {
|
|
8
8
|
const result = RequiresSocket.requiresSocket(message.method)
|
|
9
|
-
? await Command.execute(message.method,
|
|
9
|
+
? await Command.execute(message.method, ipc, ...message.params)
|
|
10
10
|
: await Command.execute(message.method, ...message.params)
|
|
11
11
|
return GetSuccessResponse.getSuccessResponse(message, result)
|
|
12
12
|
} catch (error) {
|
|
13
|
-
return GetErrorResponse.getErrorResponse(message, error)
|
|
13
|
+
return GetErrorResponse.getErrorResponse(message, error, ipc)
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
messagePort.start()
|
|
14
|
+
}
|
|
@@ -7,9 +7,9 @@ const handleJsonRpcResult = (message) => {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const handleIpc = (ipc) => {
|
|
10
|
-
const handleJsonRpcMessage = async (message
|
|
10
|
+
const handleJsonRpcMessage = async (message) => {
|
|
11
11
|
if (message.method) {
|
|
12
|
-
const response = await GetResponse.getResponse(message,
|
|
12
|
+
const response = await GetResponse.getResponse(message, ipc)
|
|
13
13
|
ipc.send(response)
|
|
14
14
|
} else {
|
|
15
15
|
// TODO handle error
|
|
@@ -17,12 +17,12 @@ export const handleIpc = (ipc) => {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const handleMessageFromParentProcess = async (message
|
|
20
|
+
const handleMessageFromParentProcess = async (message) => {
|
|
21
21
|
if (message.result) {
|
|
22
22
|
return handleJsonRpcResult(message)
|
|
23
23
|
}
|
|
24
24
|
if (message.method) {
|
|
25
|
-
return handleJsonRpcMessage(message
|
|
25
|
+
return handleJsonRpcMessage(message)
|
|
26
26
|
}
|
|
27
27
|
console.warn('unknown message', message)
|
|
28
28
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
messagePort.start()
|
|
12
|
+
}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as DestroyWebSocket from '../DestroySocket/DestroySocket.js'
|
|
2
3
|
import * as HandleWebSocketModule from '../HandleWebSocketModule/HandleWebSocketModule.js'
|
|
3
4
|
import { VError } from '../VError/VError.js'
|
|
4
5
|
|
|
5
|
-
export const handleWebSocket = async (
|
|
6
|
-
Assert.object(message)
|
|
7
|
-
Assert.object(handle)
|
|
8
|
-
const headers = message.headers
|
|
9
|
-
if (!headers) {
|
|
10
|
-
throw new VError('missing websocket headers')
|
|
11
|
-
}
|
|
12
|
-
const protocol = headers['sec-websocket-protocol']
|
|
13
|
-
if (!protocol) {
|
|
14
|
-
throw new VError('missing sec websocket protocol header')
|
|
15
|
-
}
|
|
6
|
+
export const handleWebSocket = async (message, handle) => {
|
|
16
7
|
try {
|
|
8
|
+
Assert.object(message)
|
|
9
|
+
Assert.object(handle)
|
|
10
|
+
const headers = message.headers
|
|
11
|
+
if (!headers) {
|
|
12
|
+
throw new VError('missing websocket headers')
|
|
13
|
+
}
|
|
14
|
+
const protocol = headers['sec-websocket-protocol']
|
|
15
|
+
if (!protocol) {
|
|
16
|
+
throw new VError('missing sec websocket protocol header')
|
|
17
|
+
}
|
|
18
|
+
handle.pause()
|
|
17
19
|
const module = await HandleWebSocketModule.load(protocol)
|
|
18
20
|
await module.handleWebSocket(message, handle, protocol)
|
|
21
|
+
handle.resume()
|
|
19
22
|
} catch (error) {
|
|
20
|
-
|
|
21
|
-
handle.destroy()
|
|
22
|
-
} catch {}
|
|
23
|
+
DestroyWebSocket.destroySocket(handle)
|
|
23
24
|
throw new VError(error, `Failed to connect to websocket`)
|
|
24
25
|
}
|
|
25
26
|
}
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
|
|
2
|
-
import * as
|
|
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
|
+
import * as Logger from '../Logger/Logger.js'
|
|
3
6
|
import * as WebSocketServer from '../WebSocketServer/WebSocketServer.js'
|
|
4
7
|
|
|
5
8
|
const handleSocketError = (error) => {
|
|
6
9
|
if (error && error.code === ErrorCodes.ECONNRESET) {
|
|
7
10
|
return
|
|
8
11
|
}
|
|
9
|
-
|
|
12
|
+
Logger.info('[info shared process: handle error]', error)
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export const handleWebSocket = async (message, handle) => {
|
|
13
16
|
handle.on('error', handleSocketError)
|
|
14
17
|
const webSocket = await WebSocketServer.handleUpgrade(message, handle)
|
|
15
|
-
|
|
18
|
+
const ipc = await IpcChild.listen({
|
|
19
|
+
method: IpcChildType.WebSocket,
|
|
20
|
+
webSocket,
|
|
21
|
+
})
|
|
22
|
+
HandleIpc.handleIpc(ipc)
|
|
16
23
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as IpcChildModule from '../IpcChildModule/IpcChildModule.js'
|
|
2
2
|
|
|
3
|
-
export const listen = async ({ method }) => {
|
|
3
|
+
export const listen = async ({ method, ...params }) => {
|
|
4
4
|
const module = await IpcChildModule.getModule(method)
|
|
5
|
-
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
const rawIpc = await module.listen(params)
|
|
6
7
|
const ipc = module.wrap(rawIpc)
|
|
7
8
|
return ipc
|
|
8
9
|
}
|
|
@@ -8,6 +8,12 @@ export const getModule = (method) => {
|
|
|
8
8
|
return import('../IpcChildWithNodeWorker/IpcChildWithNodeWorker.js')
|
|
9
9
|
case IpcChildType.ElectronUtilityProcess:
|
|
10
10
|
return import('../IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js')
|
|
11
|
+
case IpcChildType.ElectronMessagePort:
|
|
12
|
+
return import('../IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js')
|
|
13
|
+
case IpcChildType.NodeMessagePort:
|
|
14
|
+
return import('../IpcChildWithNodeMessagePort/IpcChildWithNodeMessagePort.js')
|
|
15
|
+
case IpcChildType.WebSocket:
|
|
16
|
+
return import('../IpcChildWithWebSocket/IpcChildWithWebSocket.js')
|
|
11
17
|
default:
|
|
12
18
|
throw new Error('unexpected ipc type')
|
|
13
19
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export const NodeWorker = 1
|
|
2
2
|
export const NodeForkedProcess = 2
|
|
3
3
|
export const ElectronUtilityProcess = 3
|
|
4
|
+
export const ElectronMessagePort = 4
|
|
5
|
+
export const NodeMessagePort = 5
|
|
6
|
+
export const WebSocket = 6
|
|
4
7
|
|
|
5
8
|
export const Auto = () => {
|
|
6
9
|
const { argv } = process
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IpcError } from '../IpcError/IpcError.js'
|
|
2
|
+
import * as IsMessagePortMain from '../IsMessagePortMain/IsMessagePortMain.js'
|
|
3
|
+
|
|
4
|
+
export const listen = ({ messagePort }) => {
|
|
5
|
+
if (!IsMessagePortMain.isMessagePortMain(messagePort)) {
|
|
6
|
+
throw new IpcError('port must be of type MessagePortMain')
|
|
7
|
+
}
|
|
8
|
+
return messagePort
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const getActualData = (event) => {
|
|
12
|
+
return event.data
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const wrap = (messagePort) => {
|
|
16
|
+
return {
|
|
17
|
+
messagePort,
|
|
18
|
+
on(event, listener) {
|
|
19
|
+
if (event === 'message') {
|
|
20
|
+
const wrappedListener = (event) => {
|
|
21
|
+
const actualData = getActualData(event)
|
|
22
|
+
listener(actualData)
|
|
23
|
+
}
|
|
24
|
+
this.messagePort.on(event, wrappedListener)
|
|
25
|
+
} else if (event === 'close') {
|
|
26
|
+
this.messagePort.on('close', listener)
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error('unsupported event type')
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
off(event, listener) {
|
|
32
|
+
this.messagePort.off(event, listener)
|
|
33
|
+
},
|
|
34
|
+
send(message) {
|
|
35
|
+
this.messagePort.postMessage(message)
|
|
36
|
+
},
|
|
37
|
+
dispose() {
|
|
38
|
+
this.messagePort.close()
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
}
|