@lvce-editor/extension-host-helper-process 0.14.15 → 0.15.1
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 +3 -1
- package/src/extensionHostHelperProcessMain.cjs +5 -0
- package/src/extensionHostHelperProcessMain.js +33 -1
- package/src/parts/CleanImportError/CleanImportError.js +20 -0
- package/src/parts/GetErrorResponse/GetErrorResponse.js +33 -0
- package/src/parts/GetModulesErrorStack/GetModulesErrorStack.js +49 -0
- package/src/parts/GetNewLineIndex/GetNewLineIndex.js +9 -0
- package/src/parts/GetResponse/GetResponse.js +6 -35
- package/src/parts/GetSuccessResponse/GetSuccessResponse.js +9 -0
- package/src/parts/ImportScript/ImportScript.js +12 -0
- package/src/parts/IpcChild/IpcChild.js +5 -18
- package/src/parts/IpcChildModule/IpcChildModule.js +20 -0
- package/src/parts/IpcChildType/IpcChildType.js +27 -13
- package/src/parts/{IpcChild → IpcChildWithElectronMessagePort}/IpcChildWithElectronMessagePort.js +5 -1
- package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +27 -0
- package/src/parts/IpcChildWithElectronUtilityProcessMessagePort/IpcChildWithElectronUtilityProcessMessagePort.js +63 -0
- package/src/parts/{IpcChild → IpcChildWithMessagePort}/IpcChildWithMessagePort.js +5 -0
- package/src/parts/{CreateProcessIpc/CreateProcessIpc.js → IpcChildWithParent/IpcChildWithParent.js} +8 -3
- package/src/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +45 -0
- package/src/parts/JoinLines/JoinLines.js +3 -0
- package/src/parts/JsonRpc/JsonRpc.js +0 -2
- package/src/parts/JsonRpcErrorCode/JsonRpcErrorCode.js +2 -0
- package/src/parts/JsonRpcVersion/JsonRpcVersion.js +1 -0
- package/src/parts/Logger/Logger.js +50 -0
- package/src/parts/MergeStacks/MergeStacks.js +20 -0
- package/src/parts/NormalizeErrorLine/NormalizeErrorLine.js +9 -0
- package/src/parts/ParseCliArgs/ParseCliArgs.js +7 -0
- package/src/parts/PrettyError/PrettyError.js +1 -0
- package/src/parts/PrintPrettyError/PrintPrettyError.js +5 -0
- package/src/parts/Rpc/Rpc.js +4 -5
- package/src/parts/SplitLines/SplitLines.js +8 -0
- package/src/parts/VError/VError.js +27 -0
- package/src/parts/CreateWebSocketIpc/CreateWebSocketIpc.js +0 -23
- package/src/parts/IpcChild/IpcChildWithParent.js +0 -5
- package/src/parts/IpcChild/IpcChildWithWebSocket.js +0 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/extension-host-helper-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"execa": "^6.1.0",
|
|
22
22
|
"got": "^12.5.3",
|
|
23
23
|
"lines-and-columns": "^2.0.3",
|
|
24
|
+
"minimist": "^1.2.8",
|
|
25
|
+
"verror": "^1.10.1",
|
|
24
26
|
"ws": "^8.11.0"
|
|
25
27
|
}
|
|
26
28
|
}
|
|
@@ -1,10 +1,42 @@
|
|
|
1
|
+
import * as GetErrorResponse from './parts/GetErrorResponse/GetErrorResponse.js'
|
|
2
|
+
import * as GetSuccessResponse from './parts/GetSuccessResponse/GetSuccessResponse.js'
|
|
3
|
+
import * as ImportScript from './parts/ImportScript/ImportScript.js'
|
|
1
4
|
import * as IpcChild from './parts/IpcChild/IpcChild.js'
|
|
2
5
|
import * as IpcChildType from './parts/IpcChildType/IpcChildType.js'
|
|
3
6
|
import * as Rpc from './parts/Rpc/Rpc.js'
|
|
7
|
+
import * as GetResponse from './parts/GetResponse/GetResponse.js'
|
|
8
|
+
|
|
9
|
+
const waitForFirstMessage = async (ipc) => {
|
|
10
|
+
const { message } = await new Promise((resolve) => {
|
|
11
|
+
const cleanup = (value) => {
|
|
12
|
+
ipc.off('message', handleMessage)
|
|
13
|
+
resolve(value)
|
|
14
|
+
}
|
|
15
|
+
const handleMessage = (message) => {
|
|
16
|
+
cleanup({ message })
|
|
17
|
+
}
|
|
18
|
+
ipc.on('message', handleMessage)
|
|
19
|
+
})
|
|
20
|
+
return message
|
|
21
|
+
}
|
|
4
22
|
|
|
5
23
|
const main = async () => {
|
|
6
24
|
const ipc = await IpcChild.listen({ method: IpcChildType.Auto() })
|
|
7
|
-
|
|
25
|
+
const firstMessage = await waitForFirstMessage(ipc)
|
|
26
|
+
let module
|
|
27
|
+
try {
|
|
28
|
+
module = await ImportScript.importScript(firstMessage.params[0])
|
|
29
|
+
if (!module || !module.execute) {
|
|
30
|
+
throw new Error(`missing export const execute function`)
|
|
31
|
+
}
|
|
32
|
+
const response = GetSuccessResponse.getSuccessResponse(firstMessage, null)
|
|
33
|
+
ipc.send(response)
|
|
34
|
+
} catch (error) {
|
|
35
|
+
const response = await GetErrorResponse.getErrorResponse(firstMessage, error)
|
|
36
|
+
ipc.send(response)
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
Rpc.listen(ipc, module.execute)
|
|
8
40
|
}
|
|
9
41
|
|
|
10
42
|
main()
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as GetModulesErrorStack from '../GetModulesErrorStack/GetModulesErrorStack.js'
|
|
2
|
+
import * as JoinLines from '../JoinLines/JoinLines.js'
|
|
3
|
+
import * as SplitLines from '../SplitLines/SplitLines.js'
|
|
4
|
+
|
|
5
|
+
const cleanImportSyntaxError = (error) => {
|
|
6
|
+
const cleanStackLines = GetModulesErrorStack.getModulesErrorStack(error.stack)
|
|
7
|
+
const cleanError = new SyntaxError(error.message)
|
|
8
|
+
const currentStack = JoinLines.joinLines(SplitLines.splitLines(new Error().stack).slice(3))
|
|
9
|
+
const cleanStack = JoinLines.joinLines(cleanStackLines)
|
|
10
|
+
const mergedStack = cleanStack + '\n' + currentStack
|
|
11
|
+
cleanError.stack = mergedStack
|
|
12
|
+
return cleanError
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const cleanImportError = (error) => {
|
|
16
|
+
if (error && error instanceof SyntaxError) {
|
|
17
|
+
return cleanImportSyntaxError(error)
|
|
18
|
+
}
|
|
19
|
+
return error
|
|
20
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as JsonRpcErrorCode from '../JsonRpcErrorCode/JsonRpcErrorCode.js'
|
|
2
|
+
import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
|
|
3
|
+
import * as PrettyError from '../PrettyError/PrettyError.js'
|
|
4
|
+
import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
|
|
5
|
+
|
|
6
|
+
export const getErrorResponse = (message, error) => {
|
|
7
|
+
if (error && error instanceof Error && error.message && error.message.startsWith('method not found')) {
|
|
8
|
+
return {
|
|
9
|
+
jsonrpc: JsonRpcVersion.Two,
|
|
10
|
+
id: message.id,
|
|
11
|
+
error: {
|
|
12
|
+
code: JsonRpcErrorCode.MethodNotFound,
|
|
13
|
+
message: error.message,
|
|
14
|
+
data: error.stack,
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const prettyError = PrettyError.prepare(error)
|
|
19
|
+
PrintPrettyError.printPrettyError(prettyError, `[extension-host-helper-process] `)
|
|
20
|
+
return {
|
|
21
|
+
jsonrpc: JsonRpcVersion.Two,
|
|
22
|
+
id: message.id,
|
|
23
|
+
error: {
|
|
24
|
+
code: JsonRpcErrorCode.Custom,
|
|
25
|
+
message: prettyError.message,
|
|
26
|
+
data: {
|
|
27
|
+
stack: prettyError.stack,
|
|
28
|
+
codeFrame: prettyError.codeFrame,
|
|
29
|
+
type: prettyError.type,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as SplitLines from '../SplitLines/SplitLines.js'
|
|
2
|
+
|
|
3
|
+
const RE_AT = /^ at /
|
|
4
|
+
const RE_JUST_PATH = /^(?:\/|\\).*\:\d+$/
|
|
5
|
+
|
|
6
|
+
const isStackLine = (line) => {
|
|
7
|
+
return RE_AT.test(line)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const isJustPath = (line) => {
|
|
11
|
+
return RE_JUST_PATH.test(line)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const getModulesErrorStack = (stderr) => {
|
|
15
|
+
const lines = SplitLines.splitLines(stderr)
|
|
16
|
+
let startIndex = -1
|
|
17
|
+
const extraLines = []
|
|
18
|
+
for (let i = 0; i < lines.length; i++) {
|
|
19
|
+
const line = lines[i]
|
|
20
|
+
if (isJustPath(line)) {
|
|
21
|
+
extraLines.push(` at ${line}`)
|
|
22
|
+
break
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
for (let i = 0; i < lines.length; i++) {
|
|
26
|
+
const line = lines[i]
|
|
27
|
+
if (isStackLine(line)) {
|
|
28
|
+
startIndex = i
|
|
29
|
+
break
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (startIndex === -1) {
|
|
33
|
+
return []
|
|
34
|
+
}
|
|
35
|
+
let endIndex = -1
|
|
36
|
+
for (let i = startIndex + 1; i < lines.length; i++) {
|
|
37
|
+
const line = lines[i]
|
|
38
|
+
if (!isStackLine(line)) {
|
|
39
|
+
endIndex = i
|
|
40
|
+
break
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (endIndex === -1) {
|
|
44
|
+
endIndex = lines.length - 1
|
|
45
|
+
}
|
|
46
|
+
const stackLines = lines.slice(startIndex, endIndex)
|
|
47
|
+
const stack = [lines[startIndex - 1], ...extraLines, ...stackLines]
|
|
48
|
+
return stack
|
|
49
|
+
}
|
|
@@ -1,40 +1,11 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as
|
|
3
|
-
import * as PrettyError from '../PrettyError/PrettyError.js'
|
|
1
|
+
import * as GetErrorResponse from '../GetErrorResponse/GetErrorResponse.js'
|
|
2
|
+
import * as GetSuccessResponse from '../GetSuccessResponse/GetSuccessResponse.js'
|
|
4
3
|
|
|
5
|
-
export const getResponse = async (message) => {
|
|
4
|
+
export const getResponse = async (message, execute) => {
|
|
6
5
|
try {
|
|
7
|
-
const result = await
|
|
8
|
-
return
|
|
9
|
-
jsonrpc: JsonRpc.Version,
|
|
10
|
-
id: message.id,
|
|
11
|
-
result,
|
|
12
|
-
}
|
|
6
|
+
const result = await execute(message.method, ...message.params)
|
|
7
|
+
return GetSuccessResponse.getSuccessResponse(message, result)
|
|
13
8
|
} catch (error) {
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
jsonrpc: JsonRpc.Version,
|
|
17
|
-
id: message.id,
|
|
18
|
-
error: {
|
|
19
|
-
code: JsonRpc.ErrorMethodNotFound,
|
|
20
|
-
message: error.message,
|
|
21
|
-
data: error.stack,
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
const prettyError = PrettyError.prepare(error)
|
|
26
|
-
return {
|
|
27
|
-
jsonrpc: JsonRpc.Version,
|
|
28
|
-
id: message.id,
|
|
29
|
-
error: {
|
|
30
|
-
code: -32001,
|
|
31
|
-
message: prettyError.message,
|
|
32
|
-
data: {
|
|
33
|
-
stack: prettyError.stack,
|
|
34
|
-
codeFrame: prettyError.codeFrame,
|
|
35
|
-
code: prettyError.code,
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
}
|
|
9
|
+
return GetErrorResponse.getErrorResponse(message, error)
|
|
39
10
|
}
|
|
40
11
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VError } from '../VError/VError.js'
|
|
2
|
+
import * as CleanImportError from '../CleanImportError/CleanImportError.js'
|
|
3
|
+
|
|
4
|
+
export const importScript = async (path) => {
|
|
5
|
+
try {
|
|
6
|
+
const module = await import(path)
|
|
7
|
+
return module
|
|
8
|
+
} catch (error) {
|
|
9
|
+
const cleanError = CleanImportError.cleanImportError(error)
|
|
10
|
+
throw new VError(cleanError, `Failed to load ${path}`)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,21 +1,8 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
|
|
3
|
-
const getModule = (method) => {
|
|
4
|
-
switch (method) {
|
|
5
|
-
case IpcChildType.MessagePort:
|
|
6
|
-
return import('./IpcChildWithMessagePort.js')
|
|
7
|
-
case IpcChildType.WebSocket:
|
|
8
|
-
return import('./IpcChildWithWebSocket.js')
|
|
9
|
-
case IpcChildType.Parent:
|
|
10
|
-
return import('./IpcChildWithParent.js')
|
|
11
|
-
case IpcChildType.ElectronMessagePort:
|
|
12
|
-
return import('./IpcChildWithElectronMessagePort.js')
|
|
13
|
-
default:
|
|
14
|
-
throw new Error('unexpected ipc type')
|
|
15
|
-
}
|
|
16
|
-
}
|
|
1
|
+
import * as IpcChildModule from '../IpcChildModule/IpcChildModule.js'
|
|
17
2
|
|
|
18
3
|
export const listen = async ({ method }) => {
|
|
19
|
-
const module = await getModule(method)
|
|
20
|
-
|
|
4
|
+
const module = await IpcChildModule.getModule(method)
|
|
5
|
+
const rawIpc = await module.listen()
|
|
6
|
+
const ipc = module.wrap(rawIpc)
|
|
7
|
+
return ipc
|
|
21
8
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
2
|
+
|
|
3
|
+
export const getModule = (method) => {
|
|
4
|
+
switch (method) {
|
|
5
|
+
case IpcChildType.MessagePort:
|
|
6
|
+
return import('../IpcChildWithMessagePort/IpcChildWithMessagePort.js')
|
|
7
|
+
case IpcChildType.WebSocket:
|
|
8
|
+
return import('../IpcChildWithWebSocket/IpcChildWithWebSocket.js')
|
|
9
|
+
case IpcChildType.Parent:
|
|
10
|
+
return import('../IpcChildWithParent/IpcChildWithParent.js')
|
|
11
|
+
case IpcChildType.ElectronMessagePort:
|
|
12
|
+
return import('../IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js')
|
|
13
|
+
case IpcChildType.ElectronUtilityProcess:
|
|
14
|
+
return import('../IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js')
|
|
15
|
+
case IpcChildType.ElectronUtilityProcessMessagePort:
|
|
16
|
+
return import('../IpcChildWithElectronUtilityProcessMessagePort/IpcChildWithElectronUtilityProcessMessagePort.js')
|
|
17
|
+
default:
|
|
18
|
+
throw new Error('unexpected ipc type')
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,21 +1,35 @@
|
|
|
1
|
+
import * as ParseCliArgs from '../ParseCliArgs/ParseCliArgs.js'
|
|
2
|
+
|
|
1
3
|
export const WebSocket = 1
|
|
2
4
|
export const MessagePort = 2
|
|
3
5
|
export const Parent = 3
|
|
4
6
|
export const ElectronMessagePort = 4
|
|
7
|
+
export const ElectronUtilityProcess = 5
|
|
8
|
+
export const ElectronUtilityProcessMessagePort = 6
|
|
5
9
|
|
|
6
|
-
|
|
10
|
+
const getRawIpcType = () => {
|
|
7
11
|
const { argv } = process
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
const parsedArgs = ParseCliArgs.parseCliArgs(argv.slice(2))
|
|
13
|
+
const ipcType = parsedArgs['ipc-type']
|
|
14
|
+
return ipcType
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const Auto = () => {
|
|
18
|
+
const ipcType = getRawIpcType()
|
|
19
|
+
switch (ipcType) {
|
|
20
|
+
case 'websocket':
|
|
21
|
+
return WebSocket
|
|
22
|
+
case 'message-port':
|
|
23
|
+
return MessagePort
|
|
24
|
+
case 'parent':
|
|
25
|
+
return Parent
|
|
26
|
+
case 'electron-message-port':
|
|
27
|
+
return ElectronMessagePort
|
|
28
|
+
case 'electron-utility-process':
|
|
29
|
+
return ElectronUtilityProcess
|
|
30
|
+
case 'electron-utility-process-message-port':
|
|
31
|
+
return ElectronUtilityProcessMessagePort
|
|
32
|
+
default:
|
|
33
|
+
throw new Error(`[extension-host-helper-process] unknown ipc type ${ipcType}`)
|
|
19
34
|
}
|
|
20
|
-
throw new Error('[extension-host-helper-process] unknown ipc type')
|
|
21
35
|
}
|
package/src/parts/{IpcChild → IpcChildWithElectronMessagePort}/IpcChildWithElectronMessagePort.js
RENAMED
|
@@ -2,10 +2,14 @@ import { once } from 'events'
|
|
|
2
2
|
|
|
3
3
|
export const listen = async () => {
|
|
4
4
|
// const [message, handle] = await once(process, 'message')
|
|
5
|
-
// console.log({ message, handle })
|
|
6
5
|
// if (process.send) {
|
|
7
6
|
// process.send('ready')
|
|
8
7
|
// }
|
|
9
8
|
// return {
|
|
10
9
|
// }
|
|
11
10
|
}
|
|
11
|
+
|
|
12
|
+
export const wrap = () => {
|
|
13
|
+
// TODO
|
|
14
|
+
return {}
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export const listen = () => {
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
const parentPort = process.parentPort
|
|
4
|
+
if (!parentPort) {
|
|
5
|
+
throw new Error('parent port must be defined')
|
|
6
|
+
}
|
|
7
|
+
parentPort.postMessage('ready')
|
|
8
|
+
return parentPort
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const wrap = (parentPort) => {
|
|
12
|
+
return {
|
|
13
|
+
parentPort,
|
|
14
|
+
on(event, listener) {
|
|
15
|
+
this.parentPort.on(event, listener)
|
|
16
|
+
},
|
|
17
|
+
off(event, listener) {
|
|
18
|
+
this.parentPort.off(event, listener)
|
|
19
|
+
},
|
|
20
|
+
send(message) {
|
|
21
|
+
this.parentPort.postMessage(message)
|
|
22
|
+
},
|
|
23
|
+
dispose() {
|
|
24
|
+
this.parentPort.close()
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as IpcChildWithElectronUtilityProcess from '../IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js'
|
|
2
|
+
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
3
|
+
|
|
4
|
+
const waitForFirstMessage = async (parentPort) => {
|
|
5
|
+
const { type, event } = await new Promise((resolve) => {
|
|
6
|
+
const cleanup = (value) => {
|
|
7
|
+
parentPort.off('message', handleMessage)
|
|
8
|
+
resolve(value)
|
|
9
|
+
}
|
|
10
|
+
const handleMessage = (event) => {
|
|
11
|
+
cleanup({ type: 'message', event })
|
|
12
|
+
}
|
|
13
|
+
parentPort.on('message', handleMessage)
|
|
14
|
+
})
|
|
15
|
+
return {
|
|
16
|
+
type,
|
|
17
|
+
event,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const listen = async () => {
|
|
22
|
+
const parentPort = IpcChildWithElectronUtilityProcess.listen()
|
|
23
|
+
const { type, event } = await waitForFirstMessage(parentPort)
|
|
24
|
+
if (type !== 'message') {
|
|
25
|
+
throw new Error('expected message event')
|
|
26
|
+
}
|
|
27
|
+
const { ports } = event
|
|
28
|
+
if (ports.length === 0) {
|
|
29
|
+
throw new Error(`expected message port to be passed`)
|
|
30
|
+
}
|
|
31
|
+
const port = ports[0]
|
|
32
|
+
port.start()
|
|
33
|
+
return port
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const wrap = (port) => {
|
|
37
|
+
return {
|
|
38
|
+
type: IpcChildType.ElectronUtilityProcessMessagePort,
|
|
39
|
+
port,
|
|
40
|
+
on(event, listener) {
|
|
41
|
+
switch (event) {
|
|
42
|
+
case 'message':
|
|
43
|
+
const wrappedListener = (event) => {
|
|
44
|
+
listener(event.data)
|
|
45
|
+
}
|
|
46
|
+
this.port.on(event, wrappedListener)
|
|
47
|
+
break
|
|
48
|
+
default:
|
|
49
|
+
this.port.on(event, listener)
|
|
50
|
+
break
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
off(event, listener) {
|
|
54
|
+
this.port.off(event, listener)
|
|
55
|
+
},
|
|
56
|
+
send(message) {
|
|
57
|
+
this.port.postMessage(message)
|
|
58
|
+
},
|
|
59
|
+
dispose() {
|
|
60
|
+
this.port.close()
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/parts/{CreateProcessIpc/CreateProcessIpc.js → IpcChildWithParent/IpcChildWithParent.js}
RENAMED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const listen = () => {
|
|
2
|
+
return process
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export const wrap = (process) => {
|
|
2
6
|
return {
|
|
7
|
+
process,
|
|
3
8
|
send(message) {
|
|
4
|
-
process.send(message)
|
|
9
|
+
this.process.send(message)
|
|
5
10
|
},
|
|
6
11
|
on(event, listener) {
|
|
7
12
|
switch (event) {
|
|
8
13
|
case 'message':
|
|
9
|
-
process.on('message', listener)
|
|
14
|
+
this.process.on('message', listener)
|
|
10
15
|
break
|
|
11
16
|
default:
|
|
12
17
|
throw new Error('unknown event listener type')
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { once } from 'events'
|
|
2
|
+
import * as GetWebSocket from '../GetWebSocket/GetWebSocket.js'
|
|
3
|
+
import * as Json from '../Json/Json.js'
|
|
4
|
+
|
|
5
|
+
export const listen = async () => {
|
|
6
|
+
const [message, handle] = await once(process, 'message')
|
|
7
|
+
const webSocket = await GetWebSocket.getWebSocket(message, handle)
|
|
8
|
+
return webSocket
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const wrap = (webSocket) => {
|
|
12
|
+
return {
|
|
13
|
+
webSocket,
|
|
14
|
+
/**
|
|
15
|
+
* @type {any}
|
|
16
|
+
*/
|
|
17
|
+
wrappedListener: undefined,
|
|
18
|
+
send(message) {
|
|
19
|
+
const stringifiedMessage = Json.stringify(message)
|
|
20
|
+
this.webSocket.send(stringifiedMessage)
|
|
21
|
+
},
|
|
22
|
+
on(event, listener) {
|
|
23
|
+
switch (event) {
|
|
24
|
+
case 'message':
|
|
25
|
+
this.wrappedListener = (message) => {
|
|
26
|
+
const parsed = Json.parse(message.toString())
|
|
27
|
+
listener(parsed)
|
|
28
|
+
}
|
|
29
|
+
this.webSocket.on('message', this.wrappedListener)
|
|
30
|
+
break
|
|
31
|
+
default:
|
|
32
|
+
throw new Error('unknown event listener type')
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
off(event, listener) {
|
|
36
|
+
switch (event) {
|
|
37
|
+
case 'message':
|
|
38
|
+
this.webSocket.off('message', this.wrappedListener)
|
|
39
|
+
break
|
|
40
|
+
default:
|
|
41
|
+
throw new Error('unknown event listener type')
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const Two = '2.0'
|
|
@@ -0,0 +1,50 @@
|
|
|
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-extension-host-helper-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
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
|
|
2
|
+
import * as NormalizeErrorLine from '../NormalizeErrorLine/NormalizeErrorLine.js'
|
|
3
|
+
|
|
4
|
+
export const mergeStacks = (parent, child) => {
|
|
5
|
+
if (!child) {
|
|
6
|
+
return parent
|
|
7
|
+
}
|
|
8
|
+
const parentNewLineIndex = GetNewLineIndex.getNewLineIndex(parent)
|
|
9
|
+
const childNewLineIndex = GetNewLineIndex.getNewLineIndex(child)
|
|
10
|
+
if (childNewLineIndex === -1) {
|
|
11
|
+
return parent
|
|
12
|
+
}
|
|
13
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex)
|
|
14
|
+
const childRest = child.slice(childNewLineIndex)
|
|
15
|
+
const childFirstLine = NormalizeErrorLine.normalizeLine(child.slice(0, childNewLineIndex))
|
|
16
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
17
|
+
return parentFirstLine + childRest
|
|
18
|
+
}
|
|
19
|
+
return child
|
|
20
|
+
}
|
package/src/parts/Rpc/Rpc.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as GetResponse from '../GetResponse/GetResponse.js'
|
|
2
2
|
|
|
3
|
-
export const listen = (ipc) => {
|
|
3
|
+
export const listen = (ipc, execute) => {
|
|
4
4
|
const handleMessage = async (message) => {
|
|
5
5
|
if ('method' in message) {
|
|
6
|
-
const response = await GetResponse.getResponse(message)
|
|
6
|
+
const response = await GetResponse.getResponse(message, execute)
|
|
7
7
|
ipc.send(response)
|
|
8
|
+
} else {
|
|
9
|
+
console.log({ message })
|
|
8
10
|
}
|
|
9
11
|
}
|
|
10
12
|
ipc.on('message', handleMessage)
|
|
11
|
-
if (process.send) {
|
|
12
|
-
process.send('ready')
|
|
13
|
-
}
|
|
14
13
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as MergeStacks from '../MergeStacks/MergeStacks.js'
|
|
2
|
+
import * as NormalizeErrorLine from '../NormalizeErrorLine/NormalizeErrorLine.js'
|
|
3
|
+
|
|
4
|
+
const getCombinedMessage = (error, message) => {
|
|
5
|
+
const stringifiedError = NormalizeErrorLine.normalizeLine(`${error}`)
|
|
6
|
+
if (message) {
|
|
7
|
+
return `${message}: ${stringifiedError}`
|
|
8
|
+
}
|
|
9
|
+
return stringifiedError
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class VError extends Error {
|
|
13
|
+
constructor(error, message) {
|
|
14
|
+
const combinedMessage = getCombinedMessage(error, message)
|
|
15
|
+
super(combinedMessage)
|
|
16
|
+
this.name = 'VError'
|
|
17
|
+
if (error instanceof Error) {
|
|
18
|
+
this.stack = MergeStacks.mergeStacks(this.stack, error.stack)
|
|
19
|
+
}
|
|
20
|
+
if (error.codeFrame) {
|
|
21
|
+
this.codeFrame = error.codeFrame
|
|
22
|
+
}
|
|
23
|
+
if (error.code) {
|
|
24
|
+
this.code = error.code
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as Json from '../Json/Json.js'
|
|
2
|
-
|
|
3
|
-
export const createWebSocketIpc = (webSocket) => {
|
|
4
|
-
return {
|
|
5
|
-
send(message) {
|
|
6
|
-
const stringifiedMessage = Json.stringify(message)
|
|
7
|
-
webSocket.send(stringifiedMessage)
|
|
8
|
-
},
|
|
9
|
-
on(event, listener) {
|
|
10
|
-
switch (event) {
|
|
11
|
-
case 'message':
|
|
12
|
-
const wrappedListener = (message) => {
|
|
13
|
-
const parsed = Json.parse(message.toString())
|
|
14
|
-
listener(parsed)
|
|
15
|
-
}
|
|
16
|
-
webSocket.on('message', wrappedListener)
|
|
17
|
-
break
|
|
18
|
-
default:
|
|
19
|
-
throw new Error('unknown event listener type')
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
}
|
|
23
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { once } from 'events'
|
|
2
|
-
import * as CreateWebSocketIpc from '../CreateWebSocketIpc/CreateWebSocketIpc.js'
|
|
3
|
-
import * as GetWebSocket from '../GetWebSocket/GetWebSocket.js'
|
|
4
|
-
|
|
5
|
-
export const listen = async () => {
|
|
6
|
-
const [message, handle] = await once(process, 'message')
|
|
7
|
-
const webSocket = await GetWebSocket.getWebSocket(message, handle)
|
|
8
|
-
const ipc = CreateWebSocketIpc.createWebSocketIpc(webSocket)
|
|
9
|
-
return ipc
|
|
10
|
-
}
|