@lvce-editor/shared-process 0.15.16 → 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 +8 -0
- package/config/defaultSettings.json +2 -0
- package/extensions/builtin.language-basics-python/extension.json +1 -1
- package/extensions/builtin.language-basics-xml/extension.json +2 -1
- package/extensions/builtin.language-basics-xml/src/tokenizeXml.js +1 -1
- package/extensions/builtin.theme-atom-one-dark/color-theme.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/ChildProcessError/ChildProcessError.js +4 -1
- 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.ipc.js +8 -0
- package/src/parts/ElectronInitialize/ElectronInitialize.js +11 -0
- package/src/parts/ErrorCodes/ErrorCodes.js +2 -0
- package/src/parts/ErrorHandling/ErrorHandling.js +12 -14
- package/src/parts/FirstWebSocketEventType/FirstWebSocketEventType.js +2 -0
- package/src/parts/GetActualPath/GetActualPath.js +8 -0
- package/src/parts/GetErrorResponse/GetErrorResponse.js +6 -3
- package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +41 -0
- package/src/parts/GetHelpfulChildProcessError/GetHelpfulChildProcessError.js +13 -3
- 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 +30 -0
- package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.ipc.js +7 -0
- package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.js +12 -0
- package/src/parts/HandleWebSocket/HandleWebSocket.ipc.js +7 -0
- package/src/parts/HandleWebSocket/HandleWebSocket.js +26 -0
- package/src/parts/HandleWebSocketForExtensionHost/HandleWebSocketForExtensionHost.js +15 -0
- package/src/parts/HandleWebSocketForExtensionHostHelperProcess/HandleWebSocketForExtensionHostHelperProcess.js +6 -0
- package/src/parts/HandleWebSocketForSharedProcess/HandleWebSocketForSharedProcess.js +23 -0
- package/src/parts/HandleWebSocketForTerminalProcess/HandleWebSocketForTerminalProcess.js +22 -0
- package/src/parts/HandleWebSocketForUnknown/HandleWebSocketForUnknown.js +10 -0
- package/src/parts/HandleWebSocketModule/HandleWebSocketModule.js +20 -0
- package/src/parts/Id/Id.js +7 -0
- package/src/parts/IpcChild/IpcChild.js +5 -2
- package/src/parts/IpcChildModule/IpcChildModule.js +8 -0
- package/src/parts/IpcChildType/IpcChildType.js +7 -0
- package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +41 -0
- package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +51 -0
- package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +25 -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/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js +7 -3
- package/src/parts/IsElectron/IsElectron.js +3 -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 +19 -7
- package/src/parts/Module/Module.js +14 -0
- package/src/parts/ModuleId/ModuleId.js +7 -0
- package/src/parts/ModuleMap/ModuleMap.js +18 -0
- package/src/parts/ParentIpc/ParentIpc.js +10 -188
- package/src/parts/PrettyError/PrettyError.js +4 -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/ProtocolType/ProtocolType.js +2 -1
- package/src/parts/PtyHost/PtyHost.js +81 -0
- package/src/parts/RebuildNodePty/RebuildNodePty.ipc.js +7 -0
- package/src/parts/RebuildNodePty/RebuildNodePty.js +48 -0
- package/src/parts/Signal/Signal.js +2 -0
- package/src/parts/Terminal/Terminal.js +52 -130
- package/src/parts/TerminalState/TerminalState.js +15 -0
- package/src/parts/WebSocketServer/WebSocketServer.js +11 -25
- package/src/sharedProcessMain.cjs +1 -0
- package/src/sharedProcessMain.js +3 -2
- package/extensions/builtin.language-basics-json5/README.md +0 -16
- package/extensions/builtin.language-basics-json5/extension.json +0 -12
- package/extensions/builtin.language-basics-json5/src/tokenizeJson5.js +0 -321
- package/src/parts/Socket/Socket.js +0 -77
- /package/src/parts/{GetWindowsNsisDOwnloadUrl → GetWindowsNsisDownloadUrl}/GetWindowsNsisDownloadUrl.js +0 -0
|
@@ -226,6 +226,14 @@
|
|
|
226
226
|
"id": "Developer.toggleDeveloperTools",
|
|
227
227
|
"label": "Developer: Toggle Developer Tools"
|
|
228
228
|
},
|
|
229
|
+
{
|
|
230
|
+
"id": "RebuildNodePty.rebuildNodePty",
|
|
231
|
+
"label": "Developer: Rebuild Node Pty"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"id": "DebugSharedProcess.debugSharedProcess",
|
|
235
|
+
"label": "Developer: Debug Shared Process"
|
|
236
|
+
},
|
|
229
237
|
{
|
|
230
238
|
"id": "Window.reload",
|
|
231
239
|
"label": "Window: Reload",
|
|
@@ -81,7 +81,7 @@ const RE_SLASH = /^\//
|
|
|
81
81
|
const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
|
|
82
82
|
const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
|
|
83
83
|
const RE_TAG_TEXT = /^[^\s>]+/
|
|
84
|
-
const RE_TAGNAME = /^[!\w
|
|
84
|
+
const RE_TAGNAME = /^[!\w\-\:]+/
|
|
85
85
|
const RE_TEXT = /^[^<>\n]+/
|
|
86
86
|
const RE_WHITESPACE = /^\s+/
|
|
87
87
|
const RE_WORD = /^[^\s]+/
|
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
|
}
|
|
@@ -2,8 +2,11 @@ import * as GetHelpfulChildProcessError from '../GetHelpfulChildProcessError/Get
|
|
|
2
2
|
|
|
3
3
|
export class ChildProcessError extends Error {
|
|
4
4
|
constructor(stderr) {
|
|
5
|
-
const message = GetHelpfulChildProcessError.getHelpfulChildProcessError('', stderr)
|
|
5
|
+
const { message, code } = GetHelpfulChildProcessError.getHelpfulChildProcessError('', stderr)
|
|
6
6
|
super(message)
|
|
7
7
|
this.name = 'ChildProcessError'
|
|
8
|
+
if (code) {
|
|
9
|
+
this.code = code
|
|
10
|
+
}
|
|
8
11
|
}
|
|
9
12
|
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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 electronInitialize = async (port, folder) => {
|
|
6
|
+
const ipc = await IpcChild.listen({
|
|
7
|
+
method: IpcChildType.NodeMessagePort,
|
|
8
|
+
messagePort: port,
|
|
9
|
+
})
|
|
10
|
+
HandleIpc.handleIpc(ipc)
|
|
11
|
+
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export const E_COLOR_THEME_NOT_FOUND = 'E_COLOR_THEME_NOT_FOUND'
|
|
2
2
|
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
|
+
export const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE'
|
|
4
5
|
export const E_MANIFEST_NOT_FOUND = 'E_MANIFEST_NOT_FOUND'
|
|
6
|
+
export const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'
|
|
5
7
|
export const EACCES = 'EACCES'
|
|
6
8
|
export const ECONNRESET = 'ECONNRESET'
|
|
7
9
|
export const EEXIST = 'EEXIST'
|
|
@@ -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,
|
|
@@ -49,6 +51,7 @@ export const getErrorResponse = (message, error) => {
|
|
|
49
51
|
stack: prettyError.stack,
|
|
50
52
|
codeFrame: prettyError.codeFrame,
|
|
51
53
|
type: prettyError.type,
|
|
54
|
+
code: prettyError.code,
|
|
52
55
|
},
|
|
53
56
|
},
|
|
54
57
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as SplitLines from '../SplitLines/SplitLines.js'
|
|
2
|
+
import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
|
|
2
3
|
|
|
3
4
|
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/
|
|
4
5
|
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/
|
|
@@ -29,7 +30,10 @@ const getMessageCodeBlock = (stderr) => {
|
|
|
29
30
|
|
|
30
31
|
const getNativeModuleErrorMessage = (stderr) => {
|
|
31
32
|
const message = getMessageCodeBlock(stderr)
|
|
32
|
-
return
|
|
33
|
+
return {
|
|
34
|
+
message: `Incompatible native node module: ${message}`,
|
|
35
|
+
code: ErrorCodes.E_INCOMPATIBLE_NATIVE_MODULE,
|
|
36
|
+
}
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
const isModulesSyntaxError = (stderr) => {
|
|
@@ -40,7 +44,10 @@ const isModulesSyntaxError = (stderr) => {
|
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
const getModuleSyntaxError = (stderr) => {
|
|
43
|
-
return
|
|
47
|
+
return {
|
|
48
|
+
message: `ES Modules are not supported in electron`,
|
|
49
|
+
code: ErrorCodes.E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
export const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
@@ -50,5 +57,8 @@ export const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
|
50
57
|
if (isModulesSyntaxError(stderr)) {
|
|
51
58
|
return getModuleSyntaxError(stderr)
|
|
52
59
|
}
|
|
53
|
-
return
|
|
60
|
+
return {
|
|
61
|
+
message: `child process error: ${stderr}`,
|
|
62
|
+
code: '',
|
|
63
|
+
}
|
|
54
64
|
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as Callback from '../Callback/Callback.js'
|
|
2
|
+
import * as Command from '../Command/Command.js'
|
|
3
|
+
import * as GetResponse from '../GetResponse/GetResponse.js'
|
|
4
|
+
|
|
5
|
+
const handleJsonRpcResult = (message) => {
|
|
6
|
+
Callback.resolve(message.id, message.result)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const handleIpc = (ipc) => {
|
|
10
|
+
const handleJsonRpcMessage = async (message) => {
|
|
11
|
+
if (message.method) {
|
|
12
|
+
const response = await GetResponse.getResponse(message, ipc)
|
|
13
|
+
ipc.send(response)
|
|
14
|
+
} else {
|
|
15
|
+
// TODO handle error
|
|
16
|
+
Command.execute(message.method, ...message.params)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const handleMessageFromParentProcess = async (message) => {
|
|
21
|
+
if (message.result) {
|
|
22
|
+
return handleJsonRpcResult(message)
|
|
23
|
+
}
|
|
24
|
+
if (message.method) {
|
|
25
|
+
return handleJsonRpcMessage(message)
|
|
26
|
+
}
|
|
27
|
+
console.warn('unknown message', message)
|
|
28
|
+
}
|
|
29
|
+
ipc.on('message', handleMessageFromParentProcess)
|
|
30
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as DestroyWebSocket from '../DestroySocket/DestroySocket.js'
|
|
3
|
+
import * as HandleWebSocketModule from '../HandleWebSocketModule/HandleWebSocketModule.js'
|
|
4
|
+
import { VError } from '../VError/VError.js'
|
|
5
|
+
|
|
6
|
+
export const handleWebSocket = async (message, handle) => {
|
|
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()
|
|
19
|
+
const module = await HandleWebSocketModule.load(protocol)
|
|
20
|
+
await module.handleWebSocket(message, handle, protocol)
|
|
21
|
+
handle.resume()
|
|
22
|
+
} catch (error) {
|
|
23
|
+
DestroyWebSocket.destroySocket(handle)
|
|
24
|
+
throw new VError(error, `Failed to connect to websocket`)
|
|
25
|
+
}
|
|
26
|
+
}
|