@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.
Files changed (54) hide show
  1. package/config/builtinCommands.json +4 -0
  2. package/package.json +4 -4
  3. package/src/parts/AttachDebugger/AttachDebugger.ipc.js +7 -0
  4. package/src/parts/AttachDebugger/AttachDebugger.js +6 -0
  5. package/src/parts/Callback/Callback.js +17 -26
  6. package/src/parts/CleanStack/CleanStack.js +4 -0
  7. package/src/parts/CommandNotFoundError/CommandNotFoundError.js +2 -1
  8. package/src/parts/CreateCpuProfile/CreateCpuProfile.js +59 -0
  9. package/src/parts/DestroySocket/DestroySocket.js +5 -0
  10. package/src/parts/DevtoolsProtocolRpc/DevtoolsProtocolRpc.js +32 -0
  11. package/src/parts/ElectronInitialize/ElectronInitialize.js +9 -38
  12. package/src/parts/ErrorHandling/ErrorHandling.js +12 -14
  13. package/src/parts/GetActualPath/GetActualPath.js +8 -0
  14. package/src/parts/GetErrorResponse/GetErrorResponse.js +5 -3
  15. package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +41 -0
  16. package/src/parts/GetResponse/GetResponse.js +3 -3
  17. package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.ipc.js +7 -0
  18. package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.js +14 -0
  19. package/src/parts/HandleIpc/HandleIpc.js +4 -4
  20. package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.ipc.js +7 -0
  21. package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.js +12 -0
  22. package/src/parts/HandleWebSocket/HandleWebSocket.js +15 -14
  23. package/src/parts/HandleWebSocketForSharedProcess/HandleWebSocketForSharedProcess.js +10 -3
  24. package/src/parts/Id/Id.js +7 -0
  25. package/src/parts/IpcChild/IpcChild.js +3 -2
  26. package/src/parts/IpcChildModule/IpcChildModule.js +6 -0
  27. package/src/parts/IpcChildType/IpcChildType.js +3 -0
  28. package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +41 -0
  29. package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +25 -1
  30. package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +21 -1
  31. package/src/parts/IpcChildWithNodeMessagePort/IpcChildWithNodeMessagePort.js +41 -0
  32. package/src/parts/IpcChildWithNodeWorker/IpcChildWithNodeWorker.js +17 -1
  33. package/src/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +51 -0
  34. package/src/parts/IpcError/IpcError.js +6 -0
  35. package/src/parts/IsMessagePort/IsMessagePort.js +3 -0
  36. package/src/parts/IsMessagePortMain/IsMessagePortMain.js +3 -0
  37. package/src/parts/IsSocket/IsSocket.js +5 -0
  38. package/src/parts/IsWebSocketOpen/IsWebSocketOpen.js +5 -0
  39. package/src/parts/JsonRpc/JsonRpc.js +18 -22
  40. package/src/parts/Module/Module.js +8 -0
  41. package/src/parts/ModuleId/ModuleId.js +4 -0
  42. package/src/parts/ModuleMap/ModuleMap.js +12 -0
  43. package/src/parts/PrettyError/PrettyError.js +3 -19
  44. package/src/parts/Process/Process.ipc.js +1 -0
  45. package/src/parts/Process/Process.js +8 -0
  46. package/src/parts/ProcessDisplayName/ProcessDisplayName.js +1 -0
  47. package/src/parts/RequiresSocket/RequiresSocket.js +0 -1
  48. package/src/parts/Signal/Signal.js +2 -0
  49. package/src/parts/Terminal/Terminal.js +29 -16
  50. package/src/parts/TerminalState/TerminalState.js +15 -0
  51. package/src/parts/WebSocketServer/WebSocketServer.js +7 -2
  52. package/src/sharedProcessMain.cjs +1 -0
  53. package/src/sharedProcessMain.js +2 -1
  54. package/src/parts/Socket/Socket.js +0 -77
@@ -1,3 +1,5 @@
1
+ import * as IsElectron from '../IsElectron/IsElectron.js'
2
+
1
3
  export const listen = () => {
2
4
  // @ts-ignore
3
5
  const parentPort = process.parentPort
@@ -8,11 +10,33 @@ export const listen = () => {
8
10
  return parentPort
9
11
  }
10
12
 
13
+ const getActualData = (event) => {
14
+ const { data, ports } = event
15
+ if (ports.length === 0) {
16
+ return data
17
+ }
18
+ return {
19
+ ...data,
20
+ params: [...data.params, ...ports],
21
+ }
22
+ }
23
+
11
24
  export const wrap = (parentPort) => {
12
25
  return {
26
+ shouldLogError: !IsElectron.isElectron(),
13
27
  parentPort,
14
28
  on(event, listener) {
15
- this.parentPort.on(event, listener)
29
+ if (event === 'message') {
30
+ const wrappedListener = (event) => {
31
+ const actualData = getActualData(event)
32
+ listener(actualData)
33
+ }
34
+ this.parentPort.on(event, wrappedListener)
35
+ } else if (event === 'close') {
36
+ this.parentPort.on('close', listener)
37
+ } else {
38
+ throw new Error('unsupported event type')
39
+ }
16
40
  },
17
41
  off(event, listener) {
18
42
  this.parentPort.off(event, listener)
@@ -6,11 +6,31 @@ export const listen = async () => {
6
6
  return process
7
7
  }
8
8
 
9
+ const getActualData = (message, handle) => {
10
+ if (handle) {
11
+ return {
12
+ ...message,
13
+ params: [...message.params, handle],
14
+ }
15
+ }
16
+ return message
17
+ }
18
+
9
19
  export const wrap = (process) => {
10
20
  return {
11
21
  process,
12
22
  on(event, listener) {
13
- this.process.on(event, listener)
23
+ if (event === 'message') {
24
+ const wrappedListener = (event, handle) => {
25
+ const actualData = getActualData(event, handle)
26
+ listener(actualData)
27
+ }
28
+ this.process.on(event, wrappedListener)
29
+ } else if (event === 'close') {
30
+ this.process.on('close', listener)
31
+ } else {
32
+ throw new Error('unsupported event type')
33
+ }
14
34
  },
15
35
  off(event, listener) {
16
36
  this.process.off(event, listener)
@@ -0,0 +1,41 @@
1
+ import { IpcError } from '../IpcError/IpcError.js'
2
+ import * as IsMessagePort from '../IsMessagePort/IsMessagePort.js'
3
+
4
+ export const listen = ({ messagePort }) => {
5
+ if (!IsMessagePort.isMessagePort(messagePort)) {
6
+ throw new IpcError('port must be of type MessagePort')
7
+ }
8
+ return messagePort
9
+ }
10
+
11
+ const getActualData = (message) => {
12
+ return message
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 ${event}`)
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
+ }
@@ -1,4 +1,5 @@
1
1
  import { parentPort } from 'node:worker_threads'
2
+ import * as IsElectron from '../IsElectron/IsElectron.js'
2
3
 
3
4
  export const listen = async () => {
4
5
  if (!parentPort) {
@@ -8,11 +9,26 @@ export const listen = async () => {
8
9
  return parentPort
9
10
  }
10
11
 
12
+ const getActualData = (message) => {
13
+ return message
14
+ }
15
+
11
16
  export const wrap = (parentPort) => {
12
17
  return {
18
+ shouldLogError: !IsElectron.isElectron(),
13
19
  parentPort,
14
20
  on(event, listener) {
15
- this.parentPort.on(event, listener)
21
+ if (event === 'message') {
22
+ const wrappedListener = (event) => {
23
+ const actualData = getActualData(event)
24
+ listener(actualData)
25
+ }
26
+ this.parentPort.on(event, wrappedListener)
27
+ } else if (event === 'close') {
28
+ this.parentPort.on('close', listener)
29
+ } else {
30
+ throw new Error('unsupported event type')
31
+ }
16
32
  },
17
33
  off(event, listener) {
18
34
  this.parentPort.off(event, listener)
@@ -0,0 +1,51 @@
1
+ import * as GetFirstWebSocketEvent from '../GetFirstWebSocketEvent/GetFirstWebSocketEvent.js'
2
+ import * as IsWebSocketOpen from '../IsWebSocketOpen/IsWebSocketOpen.js'
3
+
4
+ export const listen = async ({ webSocket }) => {
5
+ if (!IsWebSocketOpen.isWebSocketOpen(webSocket)) {
6
+ const { type, event } = await GetFirstWebSocketEvent.getFirstWebSocketEvent(webSocket)
7
+ console.log({ type, event })
8
+ }
9
+ return webSocket
10
+ }
11
+
12
+ const getActualData = (message) => {
13
+ const data = JSON.parse(message.toString())
14
+ return data
15
+ }
16
+
17
+ export const wrap = (webSocket) => {
18
+ return {
19
+ webSocket,
20
+ /**
21
+ * @type {any}
22
+ */
23
+ wrappedListener: undefined,
24
+ on(event, listener) {
25
+ switch (event) {
26
+ case 'message':
27
+ const wrappedListener = (message) => {
28
+ const data = getActualData(message)
29
+ listener(data)
30
+ }
31
+ webSocket.on('message', wrappedListener)
32
+ break
33
+ case 'close':
34
+ webSocket.on('close', listener)
35
+ break
36
+ default:
37
+ throw new Error('unknown event listener type')
38
+ }
39
+ },
40
+ off(event, listener) {
41
+ this.webSocket.off(event, listener)
42
+ },
43
+ send(message) {
44
+ const stringifiedMessage = JSON.stringify(message)
45
+ this.webSocket.send(stringifiedMessage)
46
+ },
47
+ dispose() {
48
+ this.webSocket.close()
49
+ },
50
+ }
51
+ }
@@ -0,0 +1,6 @@
1
+ export class IpcError extends Error {
2
+ constructor(message) {
3
+ super(message)
4
+ this.name = 'IpcError'
5
+ }
6
+ }
@@ -0,0 +1,3 @@
1
+ export const isMessagePort = (value) => {
2
+ return value && value instanceof MessagePort
3
+ }
@@ -0,0 +1,3 @@
1
+ export const isMessagePortMain = (value) => {
2
+ return value && value.constructor && value.constructor.name === 'MessagePortMain'
3
+ }
@@ -0,0 +1,5 @@
1
+ import { Socket } from 'node:net'
2
+
3
+ export const isSocket = (value) => {
4
+ return value instanceof Socket
5
+ }
@@ -0,0 +1,5 @@
1
+ import { WebSocket } from 'ws'
2
+
3
+ export const isWebSocketOpen = (webSocket) => {
4
+ return webSocket.readyState === WebSocket.OPEN
5
+ }
@@ -10,30 +10,26 @@ export const send = (transport, method, ...params) => {
10
10
  }
11
11
 
12
12
  export const invoke = (ipc, method, ...params) => {
13
- return new Promise((resolve, reject) => {
14
- // TODO use one map instead of two
15
- const callbackId = Callback.register(resolve, reject)
16
- ipc.send({
17
- jsonrpc: JsonRpcVersion.Two,
18
- method,
19
- params,
20
- id: callbackId,
21
- })
13
+ const { id, promise } = Callback.registerPromise()
14
+ ipc.send({
15
+ jsonrpc: JsonRpcVersion.Two,
16
+ method,
17
+ params,
18
+ id,
22
19
  })
20
+ return promise
23
21
  }
24
22
 
25
23
  export const invokeAndTransfer = (ipc, handle, method, ...params) => {
26
- return new Promise((resolve, reject) => {
27
- // TODO use one map instead of two
28
- const callbackId = Callback.register(resolve, reject)
29
- ipc.sendAndTransfer(
30
- {
31
- jsonrpc: JsonRpcVersion.Two,
32
- method,
33
- params,
34
- id: callbackId,
35
- },
36
- handle
37
- )
38
- })
24
+ const { id, promise } = Callback.registerPromise()
25
+ ipc.sendAndTransfer(
26
+ {
27
+ jsonrpc: JsonRpcVersion.Two,
28
+ method,
29
+ params,
30
+ id,
31
+ },
32
+ handle
33
+ )
34
+ return promise
39
35
  }
@@ -2,6 +2,8 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
2
2
 
3
3
  export const load = (moduleId) => {
4
4
  switch (moduleId) {
5
+ case ModuleId.AttachDebugger:
6
+ return import('../AttachDebugger/AttachDebugger.ipc.js')
5
7
  case ModuleId.AutoUpdater:
6
8
  return import('../AutoUpdater/AutoUpdater.ipc.js')
7
9
  case ModuleId.AutoUpdaterAppImage:
@@ -40,6 +42,8 @@ export const load = (moduleId) => {
40
42
  return import('../Platform/Platform.ipc.js')
41
43
  case ModuleId.Preferences:
42
44
  return import('../Preferences/Preferences.ipc.js')
45
+ case ModuleId.Process:
46
+ return import('../Process/Process.ipc.js')
43
47
  case ModuleId.RecentlyOpened:
44
48
  return import('../RecentlyOpened/RecentlyOpened.ipc.js')
45
49
  case ModuleId.SearchFile:
@@ -58,6 +62,10 @@ export const load = (moduleId) => {
58
62
  return import('../RebuildNodePty/RebuildNodePty.ipc.js')
59
63
  case ModuleId.HandleWebSocket:
60
64
  return import('../HandleWebSocket/HandleWebSocket.ipc.js')
65
+ case ModuleId.HandleElectronMessagePort:
66
+ return import('../HandleElectronMessagePort/HandleElectronMessagePort.ipc.js')
67
+ case ModuleId.HandleNodeMessagePort:
68
+ return import('../HandleNodeMessagePort/HandleNodeMessagePort.ipc.js')
61
69
  default:
62
70
  throw new Error(`module ${moduleId} not found`)
63
71
  }
@@ -26,3 +26,7 @@ export const AutoUpdaterWindowsNsis = 25
26
26
  export const RebuildNodePty = 26
27
27
  export const ElectronInitialize = 27
28
28
  export const HandleWebSocket = 28
29
+ export const Process = 29
30
+ export const AttachDebugger = 30
31
+ export const HandleElectronMessagePort = 31
32
+ export const HandleNodeMessagePort = 32
@@ -3,6 +3,8 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
3
3
 
4
4
  export const getModuleId = (commandId) => {
5
5
  switch (commandId) {
6
+ case 'AttachDebugger.attachDebugger':
7
+ return ModuleId.AttachDebugger
6
8
  case 'AutoUpdater.getAutoUpdateType':
7
9
  case 'AutoUpdater.getLatestVersion':
8
10
  return ModuleId.AutoUpdater
@@ -112,6 +114,10 @@ export const getModuleId = (commandId) => {
112
114
  return ModuleId.GitLsFiles
113
115
  case 'HandleWebSocket.handleWebSocket':
114
116
  return ModuleId.HandleWebSocket
117
+ case 'HandleElectronMessagePort.handleElectronMessagePort':
118
+ return ModuleId.HandleElectronMessagePort
119
+ case 'HandleNodeMessagePort.handleNodeMessagePort':
120
+ return ModuleId.HandleNodeMessagePort
115
121
  case 'InstallExtension.installExtension':
116
122
  return ModuleId.InstallExtension
117
123
  case 'IsAutoUpdateSupported.isAutoUpdateSupported':
@@ -161,6 +167,12 @@ export const getModuleId = (commandId) => {
161
167
  return ModuleId.Workspace
162
168
  case 'RebuildNodePty.rebuildNodePty':
163
169
  return ModuleId.RebuildNodePty
170
+ case 'Process.getPid':
171
+ return ModuleId.Process
172
+ case 'HandleNodeMessagePort.handleNodeMessagePort':
173
+ return ModuleId.HandleNodeMessagePort
174
+ case 'HandleElectronMessagePort.handleElectronMessagePort':
175
+ return ModuleId.HandleElectronMessagePort
164
176
  default:
165
177
  throw new CommandNotFoundError(commandId)
166
178
  }
@@ -1,22 +1,14 @@
1
1
  import { codeFrameColumns } from '@babel/code-frame'
2
2
  import { LinesAndColumns } from 'lines-and-columns'
3
3
  import { readFileSync } from 'node:fs'
4
- import { fileURLToPath } from 'node:url'
5
- import { AssertionError } from '../AssertionError/AssertionError.js'
6
4
  import * as CleanStack from '../CleanStack/CleanStack.js'
7
5
  import * as EncodingType from '../EncodingType/EncodingType.js'
8
6
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
7
+ import * as GetActualPath from '../GetActualPath/GetActualPath.js'
9
8
  import * as JoinLines from '../JoinLines/JoinLines.js'
10
9
  import * as Json from '../Json/Json.js'
11
10
  import * as SplitLines from '../SplitLines/SplitLines.js'
12
11
 
13
- const getActualPath = (fileUri) => {
14
- if (fileUri.startsWith('file://')) {
15
- return fileURLToPath(fileUri)
16
- }
17
- return fileUri
18
- }
19
-
20
12
  const RE_MODULE_NOT_FOUND_STACK = /Cannot find package '([^']+)' imported from (.+)$/
21
13
 
22
14
  const prepareModuleNotFoundError = (error) => {
@@ -61,13 +53,6 @@ const prepareModuleNotFoundError = (error) => {
61
53
  }
62
54
  }
63
55
 
64
- const getStackLinesToCut = (error) => {
65
- if (error instanceof AssertionError) {
66
- return 1
67
- }
68
- return 0
69
- }
70
-
71
56
  export const prepare = (error) => {
72
57
  if (error && error.code === ErrorCodes.ERR_MODULE_NOT_FOUND) {
73
58
  return prepareModuleNotFoundError(error)
@@ -79,8 +64,7 @@ export const prepare = (error) => {
79
64
  error = cause
80
65
  }
81
66
  }
82
- const linesToCut = getStackLinesToCut(error)
83
- const lines = CleanStack.cleanStack(error.stack).slice(linesToCut)
67
+ const lines = CleanStack.cleanStack(error.stack)
84
68
  const file = lines[0]
85
69
  let codeFrame = ''
86
70
  if (error.codeFrame) {
@@ -92,7 +76,7 @@ export const prepare = (error) => {
92
76
  }
93
77
  if (match) {
94
78
  const [_, path, line, column] = match
95
- const actualPath = getActualPath(path)
79
+ const actualPath = GetActualPath.getActualPath(path)
96
80
  const rawLines = readFileSync(actualPath, EncodingType.Utf8)
97
81
  const location = {
98
82
  start: {
@@ -5,4 +5,5 @@ export const name = 'Process'
5
5
  export const Commands = {
6
6
  crash: Process.crash,
7
7
  crashAsync: Process.crashAsync,
8
+ getPid: Process.getPid,
8
9
  }
@@ -28,4 +28,12 @@ export const isConnected = () => {
28
28
  return process.connected
29
29
  }
30
30
 
31
+ export const kill = (pid, signal) => {
32
+ process.kill(pid, signal)
33
+ }
34
+
35
+ export const getPid = () => {
36
+ return process.pid
37
+ }
38
+
31
39
  export const { platform } = process
@@ -0,0 +1 @@
1
+ export const processDisplayName = 'shared process'
@@ -7,7 +7,6 @@ const METHODS_THAT_REQUIRE_SOCKET = new Set([
7
7
  'ExtensionHost.send',
8
8
  'ExtensionHost.watchColorTheme',
9
9
  'Terminal.create',
10
- 'HandleWebSocket.handleWebSocket',
11
10
  ])
12
11
 
13
12
  export const requiresSocket = (method) => {
@@ -0,0 +1,2 @@
1
+ export const SIGUSR1 = 'SIGUSR1'
2
+ export const SIGTERM = 'SIGTERM'
@@ -1,10 +1,31 @@
1
1
  import * as Assert from '../Assert/Assert.js'
2
2
  import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
3
3
  import * as PtyHost from '../PtyHost/PtyHost.js'
4
+ import * as TerminalState from '../TerminalState/TerminalState.js'
4
5
  import { VError } from '../VError/VError.js'
5
6
 
6
- export const state = {
7
- socketMap: Object.create(null),
7
+ const createTerminal = (ptyHost, socket) => {
8
+ const handleMessage = (message) => {
9
+ socket.send(message)
10
+ }
11
+ const handleClose = () => {
12
+ // socket.off('close', handleClose)
13
+ ptyHost.off('message', handleMessage)
14
+ ptyHost.dispose()
15
+ }
16
+ const dispose = () => {
17
+ ptyHost.off('message', handleMessage)
18
+ socket.off('close', handleClose)
19
+ }
20
+ ptyHost.on('message', handleMessage)
21
+ socket.on('close', handleClose)
22
+ return {
23
+ ptyHost,
24
+ socket,
25
+ handleMessage,
26
+ handleClose,
27
+ dispose,
28
+ }
8
29
  }
9
30
 
10
31
  export const create = async (socket, id, cwd) => {
@@ -12,21 +33,10 @@ export const create = async (socket, id, cwd) => {
12
33
  Assert.object(socket)
13
34
  Assert.number(id)
14
35
  Assert.string(cwd)
15
- // TODO dispose entry
16
- state.socketMap[id] = socket
36
+ // TODO race condition because of await
17
37
  const ptyHost = await PtyHost.getOrCreate()
18
-
19
- const handleMessage = (message) => {
20
- socket.send(message)
21
- }
22
- const handleClose = () => {
23
- // socket.off('close', handleClose)
24
- ptyHost.off('message', handleMessage)
25
- ptyHost.dispose()
26
- }
27
- ptyHost.on('message', handleMessage)
28
- socket.on('close', handleClose)
29
-
38
+ const terminal = createTerminal(ptyHost, socket)
39
+ TerminalState.add(id, terminal)
30
40
  // TODO use invoke
31
41
  ptyHost.send({
32
42
  jsonrpc: JsonRpcVersion.Two,
@@ -59,6 +69,9 @@ export const resize = (state, columns, rows) => {
59
69
  }
60
70
 
61
71
  export const dispose = async (id) => {
72
+ const terminal = TerminalState.get(id)
73
+ terminal.dispose()
74
+ TerminalState.remove(id)
62
75
  const ptyHost = await PtyHost.getOrCreate()
63
76
  // TODO use invoke
64
77
  ptyHost.send({
@@ -0,0 +1,15 @@
1
+ export const state = {
2
+ terminals: Object.create(null),
3
+ }
4
+
5
+ export const add = (id, terminal) => {
6
+ state.terminals[id] = terminal
7
+ }
8
+
9
+ export const get = (id) => {
10
+ return state.terminals[id]
11
+ }
12
+
13
+ export const remove = (id) => {
14
+ delete state.terminals[id]
15
+ }
@@ -1,5 +1,6 @@
1
1
  import { Buffer } from 'node:buffer'
2
2
  import * as _ws from 'ws'
3
+ import * as IsSocket from '../IsSocket/IsSocket.js'
3
4
 
4
5
  // workaround for jest or node bug
5
6
  const WebSocketServer = _ws.WebSocketServer
@@ -14,11 +15,15 @@ const webSocketServer = new WebSocketServer({
14
15
  // perMessageDeflate: true
15
16
  })
16
17
 
17
- export const handleUpgrade = (request, socket) => {
18
- return new Promise((resolve, reject) => {
18
+ export const handleUpgrade = async (request, socket) => {
19
+ if (!IsSocket.isSocket(socket)) {
20
+ throw new TypeError(`socket must be of type Socket`)
21
+ }
22
+ const webSocket = await new Promise((resolve, reject) => {
19
23
  const upgradeCallback = (ws) => {
20
24
  resolve(ws)
21
25
  }
22
26
  webSocketServer.handleUpgrade(request, socket, Buffer.alloc(0), upgradeCallback)
23
27
  })
28
+ return webSocket
24
29
  }
@@ -0,0 +1 @@
1
+ import('./sharedProcessMain.js')
@@ -3,6 +3,7 @@ import * as ErrorHandling from './parts/ErrorHandling/ErrorHandling.js'
3
3
  import * as Module from './parts/Module/Module.js'
4
4
  import * as ParentIpc from './parts/ParentIpc/ParentIpc.js'
5
5
  import * as Process from './parts/Process/Process.js'
6
+ import * as Signal from './parts/Signal/Signal.js'
6
7
  // TODO handle structure: one shared process multiple extension hosts
7
8
 
8
9
  // TODO use named functions here
@@ -34,7 +35,7 @@ const main = async () => {
34
35
  console.log('[shared process] started')
35
36
  // process.on('beforeExit', handleBeforeExit)
36
37
  process.on('disconnect', handleDisconnect)
37
- process.on('SIGTERM', handleSigTerm)
38
+ process.on(Signal.SIGTERM, handleSigTerm)
38
39
 
39
40
  process.on('uncaughtExceptionMonitor', ErrorHandling.handleUncaughtExceptionMonitor)
40
41
  await ParentIpc.listen()
@@ -1,77 +0,0 @@
1
- import * as Command from '../Command/Command.js'
2
- import * as GetResponse from '../GetResponse/GetResponse.js'
3
- import { VError } from '../VError/VError.js'
4
-
5
- export const state = {
6
- /**
7
- * @type {any}
8
- */
9
- socket: undefined,
10
- }
11
-
12
- export const send = (message) => {
13
- if (!state.socket) {
14
- console.warn('socket not yet available')
15
- return
16
- }
17
- state.socket.send(message)
18
- }
19
-
20
- const handleMessage = async (event) => {
21
- const object = JSON.parse(event.data)
22
- if (object.id) {
23
- if (!object.params) {
24
- console.warn('[shared-process] invalid message 1', typeof object, object.params, object)
25
- return
26
- }
27
- const response = await GetResponse.getResponse(object, state.socket)
28
- send(response)
29
- } else {
30
- if (!object.params) {
31
- console.warn('invalid message', typeof object, object.params, object)
32
- return
33
- }
34
- Command.execute(object.method, state.socket, ...object.params)
35
- }
36
- }
37
-
38
- const handleError = (error) => {
39
- // console.error(error)
40
- throw new VError(error, 'Shared Process Socket Error')
41
-
42
- // console.error('[Shared Process: Socket Error]', event)
43
- }
44
-
45
- // TODO
46
- const createAbstractSocket = (socket) => {
47
- return {
48
- _socket: socket,
49
- send(message) {
50
- socket.send(JSON.stringify(message))
51
- },
52
- on(event, listener) {
53
- switch (event) {
54
- case 'message':
55
- socket.on('message', listener)
56
- break
57
- case 'close':
58
- socket.on('close', listener)
59
- break
60
- default:
61
- console.warn('socket event not implemented', event, listener)
62
- break
63
- }
64
- },
65
- }
66
- }
67
-
68
- export const set = (socket) => {
69
- socket.on('close', () => {
70
- console.log('[shared-process] socket closed')
71
- })
72
- socket.onmessage = handleMessage
73
- // socket.onerror = handleError
74
- socket.on('error', handleError)
75
- const abstractSocket = createAbstractSocket(socket)
76
- state.socket = abstractSocket
77
- }