@lvce-editor/extension-host-helper-process 0.15.21 → 0.15.22
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 +1 -1
- package/src/extensionHostHelperProcessMain.js +2 -41
- package/src/parts/Ajax/Ajax.js +3 -0
- package/src/parts/Callback/Callback.js +42 -0
- package/src/parts/Command/Command.js +6 -78
- package/src/parts/CommandMap/CommandMap.js +11 -0
- package/src/parts/CommandNotFoundError/CommandNotFoundError.js +9 -0
- package/src/parts/CommandState/CommandState.js +34 -0
- package/src/parts/ErrorCodes/ErrorCodes.js +18 -0
- package/src/parts/Exec/Exec.js +3 -0
- package/src/parts/FirstWebSocketEventType/FirstWebSocketEventType.js +2 -0
- package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +41 -0
- package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.js +14 -0
- package/src/parts/HandleIpc/HandleIpc.js +12 -0
- package/src/parts/HandleJsonRpcMessage/HandleJsonRpcMessage.js +10 -0
- package/src/parts/HandleWebSocket/HandleWebSocket.js +18 -0
- package/src/parts/Id/Id.js +7 -0
- package/src/parts/IpcChildModule/IpcChildModule.js +2 -0
- package/src/parts/IpcChildType/IpcChildType.js +3 -0
- package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +35 -11
- package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +3 -1
- package/src/parts/IpcChildWithElectronUtilityProcessMessagePort/IpcChildWithElectronUtilityProcessMessagePort.js +1 -0
- package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +36 -0
- package/src/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +28 -21
- 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/IsWebSocket/IsWebSocket.js +5 -0
- package/src/parts/IsWebSocketOpen/IsWebSocketOpen.js +5 -0
- package/src/parts/LoadFile/LoadFile.js +21 -0
- package/src/parts/Main/Main.js +11 -0
- package/src/parts/WebSocketSerialization/WebSocketSerialization.js +7 -0
- package/src/parts/WebSocketServer/WebSocketServer.ipc.js +7 -0
- package/src/parts/WebSocketServer/WebSocketServer.js +21 -0
- package/src/extensionHostHelperProcessMain.cjs +0 -5
- package/src/parts/IpcChildWithMessagePort/IpcChildWithMessagePort.js +0 -9
- package/src/parts/IpcChildWithParent/IpcChildWithParent.js +0 -21
- package/src/parts/Rpc/Rpc.js +0 -13
package/package.json
CHANGED
|
@@ -1,42 +1,3 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import * as GetSuccessResponse from './parts/GetSuccessResponse/GetSuccessResponse.js'
|
|
3
|
-
import * as ImportScript from './parts/ImportScript/ImportScript.js'
|
|
4
|
-
import * as IpcChild from './parts/IpcChild/IpcChild.js'
|
|
5
|
-
import * as IpcChildType from './parts/IpcChildType/IpcChildType.js'
|
|
6
|
-
import * as Rpc from './parts/Rpc/Rpc.js'
|
|
7
|
-
import * as GetResponse from './parts/GetResponse/GetResponse.js'
|
|
1
|
+
import * as Main from './parts/Main/Main.js'
|
|
8
2
|
|
|
9
|
-
|
|
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
|
-
}
|
|
22
|
-
|
|
23
|
-
const main = async () => {
|
|
24
|
-
const ipc = await IpcChild.listen({ method: IpcChildType.Auto() })
|
|
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)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
main()
|
|
3
|
+
Main.main()
|
package/src/parts/Ajax/Ajax.js
CHANGED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as Id from '../Id/Id.js'
|
|
3
|
+
|
|
4
|
+
export const state = {
|
|
5
|
+
callbacks: Object.create(null),
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const registerPromise = () => {
|
|
9
|
+
const id = Id.create()
|
|
10
|
+
const promise = new Promise((resolve, reject) => {
|
|
11
|
+
state.callbacks[id] = {
|
|
12
|
+
resolve,
|
|
13
|
+
reject,
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
return { id, promise }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const unregister = (id) => {
|
|
20
|
+
delete state.callbacks[id]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const resolve = (id, args) => {
|
|
24
|
+
Assert.number(id)
|
|
25
|
+
if (!(id in state.callbacks)) {
|
|
26
|
+
console.log(args)
|
|
27
|
+
console.warn(`callback ${id} may already be disposed`)
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
state.callbacks[id].resolve(args)
|
|
31
|
+
delete state.callbacks[id]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const reject = (id, error) => {
|
|
35
|
+
Assert.number(id)
|
|
36
|
+
if (!(id in state.callbacks)) {
|
|
37
|
+
console.warn(`callback ${id} may already be disposed`)
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
state.callbacks[id].reject(error)
|
|
41
|
+
delete state.callbacks[id]
|
|
42
|
+
}
|
|
@@ -1,82 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as
|
|
3
|
-
|
|
4
|
-
const commands = Object.create(null)
|
|
5
|
-
const pendingModules = Object.create(null)
|
|
6
|
-
|
|
7
|
-
const initializeModule = (module) => {
|
|
8
|
-
if (module.Commands) {
|
|
9
|
-
for (const [key, value] of Object.entries(module.Commands)) {
|
|
10
|
-
if (module.name) {
|
|
11
|
-
const actualKey = `${module.name}.${key}`
|
|
12
|
-
register(actualKey, value)
|
|
13
|
-
} else {
|
|
14
|
-
register(key, value)
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
throw new Error(`module ${module.name} is missing commands`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const getOrLoadModule = (moduleId) => {
|
|
23
|
-
if (!pendingModules[moduleId]) {
|
|
24
|
-
const importPromise = Module.load(moduleId)
|
|
25
|
-
pendingModules[moduleId] = importPromise
|
|
26
|
-
.then(initializeModule)
|
|
27
|
-
.catch((error) => {
|
|
28
|
-
console.error(error)
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
return pendingModules[moduleId]
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const loadCommand = (command) => getOrLoadModule(ModuleMap.getModuleId(command))
|
|
35
|
-
|
|
36
|
-
export const register = (commandId, listener) => {
|
|
37
|
-
commands[commandId] = listener
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export const invoke = async (command, ...args) => {
|
|
41
|
-
if (!(command in commands)) {
|
|
42
|
-
await loadCommand(command)
|
|
43
|
-
if (!(command in commands)) {
|
|
44
|
-
console.warn(
|
|
45
|
-
`[extension host helper process] Unknown command "${command}"`
|
|
46
|
-
)
|
|
47
|
-
throw new Error(`Command ${command} not found`)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (typeof commands[command] !== 'function') {
|
|
51
|
-
throw new TypeError(`Command ${command} is not a function`)
|
|
52
|
-
}
|
|
53
|
-
return commands[command](...args)
|
|
54
|
-
}
|
|
1
|
+
import { CommandNotFoundError } from '../CommandNotFoundError/CommandNotFoundError.js'
|
|
2
|
+
import * as CommandState from '../CommandState/CommandState.js'
|
|
55
3
|
|
|
56
4
|
export const execute = (command, ...args) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
loadCommand(command)
|
|
62
|
-
// TODO can skip then block in prod (only to prevent endless loop in dev)
|
|
63
|
-
.then(() => {
|
|
64
|
-
if (!(command in commands)) {
|
|
65
|
-
console.warn(`Unknown command "${command}"`)
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
try {
|
|
69
|
-
execute(command, ...args)
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.error(
|
|
72
|
-
'[extension host helper process] command failed to execute'
|
|
73
|
-
)
|
|
74
|
-
console.error(error)
|
|
75
|
-
}
|
|
76
|
-
})
|
|
77
|
-
.catch((error) => {
|
|
78
|
-
console.error(error)
|
|
79
|
-
})
|
|
80
|
-
)
|
|
5
|
+
const fn = CommandState.getCommand(command)
|
|
6
|
+
if (!fn) {
|
|
7
|
+
throw new CommandNotFoundError(command)
|
|
81
8
|
}
|
|
9
|
+
return fn(...args)
|
|
82
10
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as Ajax from '../Ajax/Ajax.js'
|
|
2
|
+
import * as Exec from '../Exec/Exec.js'
|
|
3
|
+
import * as HandleWebSocket from '../HandleWebSocket/HandleWebSocket.js'
|
|
4
|
+
import * as LoadFile from '../LoadFile/LoadFile.js'
|
|
5
|
+
|
|
6
|
+
export const commandMap = {
|
|
7
|
+
'Exec.exec': Exec.exec,
|
|
8
|
+
'Ajax.getJson': Ajax.getJson,
|
|
9
|
+
'HandleWebSocket.handleWebSocket': HandleWebSocket.handleWebSocket,
|
|
10
|
+
'LoadFile.loadFile': LoadFile.loadFile,
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const state = {
|
|
2
|
+
commands: Object.create(null),
|
|
3
|
+
/**
|
|
4
|
+
* @type {any}
|
|
5
|
+
*/
|
|
6
|
+
execute: undefined,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const registerCommand = (key, fn) => {
|
|
10
|
+
state.commands[key] = fn
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const registerCommands = (commandMap) => {
|
|
14
|
+
for (const [key, value] of Object.entries(commandMap)) {
|
|
15
|
+
registerCommand(key, value)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const getCommand = (key) => {
|
|
20
|
+
const { commands, execute } = state
|
|
21
|
+
if (key in commands) {
|
|
22
|
+
return commands[key]
|
|
23
|
+
}
|
|
24
|
+
if (execute) {
|
|
25
|
+
return (...args) => {
|
|
26
|
+
return execute(key, ...args)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const setExecute = (fn) => {
|
|
33
|
+
state.execute = fn
|
|
34
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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 = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON'
|
|
7
|
+
export const EACCES = 'EACCES'
|
|
8
|
+
export const ECONNRESET = 'ECONNRESET'
|
|
9
|
+
export const EEXIST = 'EEXIST'
|
|
10
|
+
export const EISDIR = 'EISDIR'
|
|
11
|
+
export const ELOOP = 'ELOOP'
|
|
12
|
+
export const ENOENT = 'ENOENT'
|
|
13
|
+
export const ENOTDIR = 'ENOTDIR'
|
|
14
|
+
export const EPERM = 'EPERM'
|
|
15
|
+
export const EPIPE = 'EPIPE'
|
|
16
|
+
export const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED'
|
|
17
|
+
export const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND'
|
|
18
|
+
export const EXDEV = 'EXDEV'
|
package/src/parts/Exec/Exec.js
CHANGED
|
@@ -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
|
+
}
|
|
@@ -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,12 @@
|
|
|
1
|
+
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as Command from '../Command/Command.js'
|
|
3
|
+
import * as Callback from '../Callback/Callback.js'
|
|
4
|
+
import * as HandleJsonRpcMessage from '../HandleJsonRpcMessage/HandleJsonRpcMessage.js'
|
|
5
|
+
|
|
6
|
+
export const handleIpc = (ipc) => {
|
|
7
|
+
Assert.object(ipc)
|
|
8
|
+
const handleMessage = async (message) => {
|
|
9
|
+
return HandleJsonRpcMessage.handleJsonRpcMessage(ipc, message, Command.execute, Callback.resolve)
|
|
10
|
+
}
|
|
11
|
+
ipc.on('message', handleMessage)
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as GetResponse from '../GetResponse/GetResponse.js'
|
|
2
|
+
|
|
3
|
+
export const handleJsonRpcMessage = async (ipc, message, execute, resolve) => {
|
|
4
|
+
if ('result' in message || 'error' in message) {
|
|
5
|
+
resolve(message.id, message)
|
|
6
|
+
return
|
|
7
|
+
}
|
|
8
|
+
const response = await GetResponse.getResponse(message, execute)
|
|
9
|
+
ipc.send(response)
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
import * as WebSocketServer from '../WebSocketServer/WebSocketServer.js'
|
|
6
|
+
|
|
7
|
+
export const handleWebSocket = async (request, handle) => {
|
|
8
|
+
Assert.object(request)
|
|
9
|
+
Assert.object(handle)
|
|
10
|
+
const webSocket = await WebSocketServer.handleUpgrade(request, handle)
|
|
11
|
+
webSocket.pause()
|
|
12
|
+
const ipc = await IpcChild.listen({
|
|
13
|
+
method: IpcChildType.WebSocket,
|
|
14
|
+
webSocket,
|
|
15
|
+
})
|
|
16
|
+
HandleIpc.handleIpc(ipc)
|
|
17
|
+
webSocket.resume()
|
|
18
|
+
}
|
|
@@ -8,6 +8,8 @@ export const getModule = (method) => {
|
|
|
8
8
|
return import('../IpcChildWithWebSocket/IpcChildWithWebSocket.js')
|
|
9
9
|
case IpcChildType.Parent:
|
|
10
10
|
return import('../IpcChildWithParent/IpcChildWithParent.js')
|
|
11
|
+
case IpcChildType.NodeForkedProcess:
|
|
12
|
+
return import('../IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js')
|
|
11
13
|
case IpcChildType.ElectronMessagePort:
|
|
12
14
|
return import('../IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js')
|
|
13
15
|
case IpcChildType.ElectronUtilityProcess:
|
|
@@ -6,6 +6,7 @@ export const Parent = 3
|
|
|
6
6
|
export const ElectronMessagePort = 4
|
|
7
7
|
export const ElectronUtilityProcess = 5
|
|
8
8
|
export const ElectronUtilityProcessMessagePort = 6
|
|
9
|
+
export const NodeForkedProcess = 7
|
|
9
10
|
|
|
10
11
|
const getRawIpcType = () => {
|
|
11
12
|
const { argv } = process
|
|
@@ -29,6 +30,8 @@ export const Auto = () => {
|
|
|
29
30
|
return ElectronUtilityProcess
|
|
30
31
|
case 'electron-utility-process-message-port':
|
|
31
32
|
return ElectronUtilityProcessMessagePort
|
|
33
|
+
case 'node-forked-process':
|
|
34
|
+
return NodeForkedProcess
|
|
32
35
|
default:
|
|
33
36
|
throw new Error(`[extension-host-helper-process] unknown ipc type ${ipcType}`)
|
|
34
37
|
}
|
|
@@ -1,15 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IpcError } from '../IpcError/IpcError.js'
|
|
2
|
+
import * as IsMessagePortMain from '../IsMessagePortMain/IsMessagePortMain.js'
|
|
2
3
|
|
|
3
|
-
export const listen =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// return {
|
|
9
|
-
// }
|
|
4
|
+
export const listen = ({ messagePort }) => {
|
|
5
|
+
if (!IsMessagePortMain.isMessagePortMain(messagePort)) {
|
|
6
|
+
throw new IpcError('port must be of type MessagePortMain')
|
|
7
|
+
}
|
|
8
|
+
return messagePort
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 {
|
|
26
|
+
throw new Error('unsupported event type')
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
off(event, listener) {
|
|
30
|
+
this.messagePort.off(event, listener)
|
|
31
|
+
},
|
|
32
|
+
send(message) {
|
|
33
|
+
this.messagePort.postMessage(message)
|
|
34
|
+
},
|
|
35
|
+
dispose() {
|
|
36
|
+
this.messagePort.close()
|
|
37
|
+
},
|
|
38
|
+
}
|
|
15
39
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { IpcError } from '../IpcError/IpcError.js'
|
|
2
|
+
|
|
1
3
|
export const listen = () => {
|
|
2
4
|
// @ts-ignore
|
|
3
5
|
const parentPort = process.parentPort
|
|
4
6
|
if (!parentPort) {
|
|
5
|
-
throw new
|
|
7
|
+
throw new IpcError('parent port must be defined')
|
|
6
8
|
}
|
|
7
9
|
parentPort.postMessage('ready')
|
|
8
10
|
return parentPort
|
|
@@ -3,6 +3,7 @@ import * as getFirstUtilityProcessEvent from '../GetFirstUtilityProcessEvent/Get
|
|
|
3
3
|
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
4
4
|
import * as IpcChildWithElectronUtilityProcess from '../IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js'
|
|
5
5
|
|
|
6
|
+
// TODO remove this and use HandleElectronMessagePort function instead
|
|
6
7
|
export const listen = async () => {
|
|
7
8
|
const parentPort = IpcChildWithElectronUtilityProcess.listen()
|
|
8
9
|
const { type, event } = await getFirstUtilityProcessEvent.getFirstUtilityProcessEvent(parentPort)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { IpcError } from '../IpcError/IpcError.js'
|
|
2
|
+
|
|
3
|
+
export const listen = async () => {
|
|
4
|
+
if (!process.send) {
|
|
5
|
+
throw new IpcError('process ipc is not available')
|
|
6
|
+
}
|
|
7
|
+
process.send('ready')
|
|
8
|
+
return process
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const wrap = (process) => {
|
|
12
|
+
return {
|
|
13
|
+
process,
|
|
14
|
+
send(message) {
|
|
15
|
+
this.process.send(message)
|
|
16
|
+
},
|
|
17
|
+
on(event, listener) {
|
|
18
|
+
switch (event) {
|
|
19
|
+
case 'message':
|
|
20
|
+
this.process.on('message', listener)
|
|
21
|
+
break
|
|
22
|
+
default:
|
|
23
|
+
throw new Error('unknown event listener type')
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
off(event, listener) {
|
|
27
|
+
switch (event) {
|
|
28
|
+
case 'message':
|
|
29
|
+
this.process.off('message', listener)
|
|
30
|
+
break
|
|
31
|
+
default:
|
|
32
|
+
throw new Error('unknown event listener type')
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import * as
|
|
1
|
+
import * as GetFirstWebSocketEvent from '../GetFirstWebSocketEvent/GetFirstWebSocketEvent.js'
|
|
2
|
+
import { IpcError } from '../IpcError/IpcError.js'
|
|
3
|
+
import * as IsWebSocket from '../IsWebSocket/IsWebSocket.js'
|
|
4
|
+
import * as IsWebSocketOpen from '../IsWebSocketOpen/IsWebSocketOpen.js'
|
|
5
|
+
import * as WebSocketSerialization from '../WebSocketSerialization/WebSocketSerialization.js'
|
|
4
6
|
|
|
5
|
-
export const listen = async () => {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
export const listen = async ({ webSocket }) => {
|
|
8
|
+
if (!webSocket) {
|
|
9
|
+
throw new IpcError('webSocket must be defined')
|
|
10
|
+
}
|
|
11
|
+
if (!IsWebSocket.isWebSocket(webSocket)) {
|
|
12
|
+
throw new IpcError(`webSocket must be of type WebSocket`)
|
|
13
|
+
}
|
|
14
|
+
if (!IsWebSocketOpen.isWebSocketOpen(webSocket)) {
|
|
15
|
+
const { type, event } = await GetFirstWebSocketEvent.getFirstWebSocketEvent(webSocket)
|
|
16
|
+
console.log({ type, event })
|
|
17
|
+
}
|
|
8
18
|
return webSocket
|
|
9
19
|
}
|
|
10
20
|
|
|
@@ -15,31 +25,28 @@ export const wrap = (webSocket) => {
|
|
|
15
25
|
* @type {any}
|
|
16
26
|
*/
|
|
17
27
|
wrappedListener: undefined,
|
|
18
|
-
send(message) {
|
|
19
|
-
const stringifiedMessage = Json.stringify(message)
|
|
20
|
-
this.webSocket.send(stringifiedMessage)
|
|
21
|
-
},
|
|
22
28
|
on(event, listener) {
|
|
23
29
|
switch (event) {
|
|
24
30
|
case 'message':
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
listener(
|
|
31
|
+
const wrappedListener = (message) => {
|
|
32
|
+
const data = WebSocketSerialization.deserialize(message)
|
|
33
|
+
listener(data)
|
|
28
34
|
}
|
|
29
|
-
|
|
35
|
+
webSocket.on('message', wrappedListener)
|
|
30
36
|
break
|
|
31
37
|
default:
|
|
32
38
|
throw new Error('unknown event listener type')
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
off(event, listener) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
this.webSocket.off(event, listener)
|
|
43
|
+
},
|
|
44
|
+
send(message) {
|
|
45
|
+
const stringifiedMessage = WebSocketSerialization.serialize(message)
|
|
46
|
+
this.webSocket.send(stringifiedMessage)
|
|
47
|
+
},
|
|
48
|
+
dispose() {
|
|
49
|
+
this.webSocket.close()
|
|
43
50
|
},
|
|
44
51
|
}
|
|
45
52
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { VError } from '../VError/VError.js'
|
|
2
|
+
import * as CommandState from '../CommandState/CommandState.js'
|
|
3
|
+
import * as ImportScript from '../ImportScript/ImportScript.js'
|
|
4
|
+
import * as Assert from '../Assert/Assert.js'
|
|
5
|
+
|
|
6
|
+
export const loadFile = async (path) => {
|
|
7
|
+
try {
|
|
8
|
+
Assert.string(path)
|
|
9
|
+
const module = await ImportScript.importScript(path)
|
|
10
|
+
if (module && module.commandMap) {
|
|
11
|
+
const commandMap = module.commandMap
|
|
12
|
+
CommandState.registerCommands(commandMap)
|
|
13
|
+
} else if (module && module.execute) {
|
|
14
|
+
CommandState.setExecute(module.execute)
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error(`missing export const execute function`)
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new VError(error, `Failed to load ${path}`)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as CommandMap from '../CommandMap/CommandMap.js'
|
|
2
|
+
import * as CommandState from '../CommandState/CommandState.js'
|
|
3
|
+
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
4
|
+
import * as IpcChild from '../IpcChild/IpcChild.js'
|
|
5
|
+
import * as IpcChildType from '../IpcChildType/IpcChildType.js'
|
|
6
|
+
|
|
7
|
+
export const main = async () => {
|
|
8
|
+
CommandState.registerCommands(CommandMap.commandMap)
|
|
9
|
+
const ipc = await IpcChild.listen({ method: IpcChildType.Auto() })
|
|
10
|
+
HandleIpc.handleIpc(ipc)
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer'
|
|
2
|
+
import * as _ws from 'ws'
|
|
3
|
+
|
|
4
|
+
// workaround for jest or node bug
|
|
5
|
+
const WebSocketServer = _ws.WebSocketServer
|
|
6
|
+
? _ws.WebSocketServer
|
|
7
|
+
: // @ts-ignore
|
|
8
|
+
_ws.default.WebSocketServer
|
|
9
|
+
|
|
10
|
+
const webSocketServer = new WebSocketServer({
|
|
11
|
+
noServer: true,
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export const handleUpgrade = (request, socket) => {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
const upgradeCallback = (ws) => {
|
|
17
|
+
resolve(ws)
|
|
18
|
+
}
|
|
19
|
+
webSocketServer.handleUpgrade(request, socket, Buffer.alloc(0), upgradeCallback)
|
|
20
|
+
})
|
|
21
|
+
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export const listen = () => {
|
|
2
|
-
return process
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const wrap = (process) => {
|
|
6
|
-
return {
|
|
7
|
-
process,
|
|
8
|
-
send(message) {
|
|
9
|
-
this.process.send(message)
|
|
10
|
-
},
|
|
11
|
-
on(event, listener) {
|
|
12
|
-
switch (event) {
|
|
13
|
-
case 'message':
|
|
14
|
-
this.process.on('message', listener)
|
|
15
|
-
break
|
|
16
|
-
default:
|
|
17
|
-
throw new Error('unknown event listener type')
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
}
|
package/src/parts/Rpc/Rpc.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import * as GetResponse from '../GetResponse/GetResponse.js'
|
|
2
|
-
|
|
3
|
-
export const listen = (ipc, execute) => {
|
|
4
|
-
const handleMessage = async (message) => {
|
|
5
|
-
if ('method' in message) {
|
|
6
|
-
const response = await GetResponse.getResponse(message, execute)
|
|
7
|
-
ipc.send(response)
|
|
8
|
-
} else {
|
|
9
|
-
console.log({ message })
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
ipc.on('message', handleMessage)
|
|
13
|
-
}
|