@lvce-editor/shared-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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.14.15",
3
+ "version": "0.15.1",
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.14.15",
21
- "@lvce-editor/extension-host-helper-process": "0.14.15",
22
- "@lvce-editor/pty-host": "0.14.15",
20
+ "@lvce-editor/extension-host": "0.15.1",
21
+ "@lvce-editor/extension-host-helper-process": "0.15.1",
22
+ "@lvce-editor/pty-host": "0.15.1",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^7.1.1",
25
25
  "exit-hook": "^3.2.0",
@@ -28,7 +28,7 @@
28
28
  "lines-and-columns": "^2.0.3",
29
29
  "open": "^9.1.0",
30
30
  "p-queue": "^7.3.4",
31
- "parse-json": "^6.0.2",
31
+ "parse-json": "^7.0.0",
32
32
  "symlink-dir": "^5.1.1",
33
33
  "tail": "^2.2.6",
34
34
  "tar-fs": "^2.1.1",
@@ -1,45 +1,9 @@
1
- import * as SplitLines from '../SplitLines/SplitLines.js'
2
-
3
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/
4
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/
5
-
6
- const RE_MASSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/
7
- const RE_MASSAGE_CODE_BLOCK_END = /^\s* at/
8
-
9
- const isUnhelpfulNativeModuleError = (stderr) => {
10
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr)
11
- }
12
-
13
- const isMessageCodeBlockStartIndex = (line) => {
14
- return RE_MASSAGE_CODE_BLOCK_START.test(line)
15
- }
16
-
17
- const isMessageCodeBlockEndIndex = (line) => {
18
- return RE_MASSAGE_CODE_BLOCK_END.test(line)
19
- }
20
-
21
- const getMessageCodeBlock = (stderr) => {
22
- const lines = SplitLines.splitLines(stderr)
23
- const startIndex = lines.findIndex(isMessageCodeBlockStartIndex)
24
- const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex)
25
- const relevantLines = lines.slice(startIndex, endIndex)
26
- const relevantMessage = relevantLines.join(' ').slice('Error: '.length)
27
- return relevantMessage
28
- }
29
-
30
- const getNativeModuleErrorMessage = (stderr) => {
31
- const message = getMessageCodeBlock(stderr)
32
- return `incompatible native node module: ${message}`
33
- }
1
+ import * as GetHelpfulChildProcessError from '../GetHelpfulChildProcessError/GetHelpfulChildProcessError.js'
34
2
 
35
3
  export class ChildProcessError extends Error {
36
4
  constructor(stderr) {
37
- if (isUnhelpfulNativeModuleError(stderr)) {
38
- const message = getNativeModuleErrorMessage(stderr)
39
- super(message)
40
- } else {
41
- super('child process error')
42
- }
5
+ const message = GetHelpfulChildProcessError.getHelpfulChildProcessError('', stderr)
6
+ super(message)
43
7
  this.name = 'ChildProcessError'
44
8
  }
45
9
  }
@@ -14,9 +14,7 @@ export const downloadAndExtractTarGz = async ({ url, outDir, strip }) => {
14
14
  })
15
15
  )
16
16
  } catch (error) {
17
- // console.log({ error })
18
17
  if (error && error instanceof RequestError) {
19
- console.log('is req error')
20
18
  throw new VError(`Failed to download ${url}: ${error.message}`)
21
19
  }
22
20
  throw error
@@ -1,4 +1,4 @@
1
- import * as ExtensionHostIpcWithChildProcess from './ExtensionHostIpcWithChildProcess.js'
1
+ import * as ExtensionHostIpcWithChildProcess from '../ExtensionHostIpcWithChildProcess/ExtensionHostIpcWithChildProcess.js'
2
2
 
3
3
  export const create = () => {
4
4
  return ExtensionHostIpcWithChildProcess.create()
@@ -0,0 +1,55 @@
1
+ import { CommandNotFoundError } from '../CommandNotFoundError/CommandNotFoundError.js'
2
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
+ import * as JsonRpcErrorCode from '../JsonRpcErrorCode/JsonRpcErrorCode.js'
4
+ import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
5
+ import * as PrettyError from '../PrettyError/PrettyError.js'
6
+ import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
7
+
8
+ const shouldLogError = (error) => {
9
+ if (error && error.code === ErrorCodes.ENOENT) {
10
+ return false
11
+ }
12
+ return true
13
+ }
14
+
15
+ export const getErrorResponse = (message, error) => {
16
+ if (error && error instanceof CommandNotFoundError) {
17
+ return {
18
+ jsonrpc: JsonRpcVersion.Two,
19
+ id: message.id,
20
+ error: {
21
+ code: JsonRpcErrorCode.MethodNotFound,
22
+ message: error.message,
23
+ data: error.stack,
24
+ },
25
+ }
26
+ }
27
+ if (!shouldLogError(error)) {
28
+ return {
29
+ jsonrpc: JsonRpcVersion.Two,
30
+ id: message.id,
31
+ error: {
32
+ code: JsonRpcErrorCode.Custom,
33
+ message: `${error}`,
34
+ data: {
35
+ code: error.code,
36
+ },
37
+ },
38
+ }
39
+ }
40
+ const prettyError = PrettyError.prepare(error)
41
+ PrintPrettyError.printPrettyError(prettyError, `[shared-process] `)
42
+ return {
43
+ jsonrpc: JsonRpcVersion.Two,
44
+ id: message.id,
45
+ error: {
46
+ code: JsonRpcErrorCode.Custom,
47
+ message: prettyError.message,
48
+ data: {
49
+ stack: prettyError.stack,
50
+ codeFrame: prettyError.codeFrame,
51
+ type: prettyError.type,
52
+ },
53
+ },
54
+ }
55
+ }
@@ -4,12 +4,13 @@ export const getFirstNodeChildProcessEvent = async (childProcess) => {
4
4
  const { type, event, stdout, stderr } = await new Promise((resolve, reject) => {
5
5
  let stderr = ''
6
6
  let stdout = ''
7
- const cleanup = () => {
7
+ const cleanup = (value) => {
8
8
  childProcess.stderr.off('data', handleStdErrData)
9
9
  childProcess.stdout.off('data', handleStdoutData)
10
10
  childProcess.off('message', handleMessage)
11
11
  childProcess.off('exit', handleExit)
12
12
  childProcess.off('error', handleError)
13
+ resolve(value)
13
14
  }
14
15
  const handleStdErrData = (data) => {
15
16
  stderr += data
@@ -18,16 +19,13 @@ export const getFirstNodeChildProcessEvent = async (childProcess) => {
18
19
  stdout += data
19
20
  }
20
21
  const handleMessage = (event) => {
21
- cleanup()
22
- resolve({ type: FirstNodeWorkerEventType.Message, event, stdout, stderr })
22
+ cleanup({ type: FirstNodeWorkerEventType.Message, event, stdout, stderr })
23
23
  }
24
24
  const handleExit = (event) => {
25
- cleanup()
26
- resolve({ type: FirstNodeWorkerEventType.Exit, event, stdout, stderr })
25
+ cleanup({ type: FirstNodeWorkerEventType.Exit, event, stdout, stderr })
27
26
  }
28
27
  const handleError = (event) => {
29
- cleanup()
30
- resolve({ type: FirstNodeWorkerEventType.Error, event, stdout, stderr })
28
+ cleanup({ type: FirstNodeWorkerEventType.Error, event, stdout, stderr })
31
29
  }
32
30
  childProcess.stderr.on('data', handleStdErrData)
33
31
  childProcess.stdout.on('data', handleStdoutData)
@@ -2,17 +2,16 @@ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNode
2
2
 
3
3
  export const getFirstNodeWorkerEvent = async (worker) => {
4
4
  const { type, event } = await new Promise((resolve, reject) => {
5
- const cleanup = () => {
5
+ const cleanup = (value) => {
6
6
  worker.off('exit', handleExit)
7
7
  worker.off('error', handleError)
8
+ resolve(value)
8
9
  }
9
10
  const handleExit = (event) => {
10
- cleanup()
11
- resolve({ type: FirstNodeWorkerEventType.Exit, event })
11
+ cleanup({ type: FirstNodeWorkerEventType.Exit, event })
12
12
  }
13
13
  const handleError = (event) => {
14
- cleanup()
15
- resolve({ type: FirstNodeWorkerEventType.Error, event })
14
+ cleanup({ type: FirstNodeWorkerEventType.Error, event })
16
15
  }
17
16
  worker.on('exit', handleExit)
18
17
  worker.on('error', handleError)
@@ -0,0 +1,54 @@
1
+ import * as SplitLines from '../SplitLines/SplitLines.js'
2
+
3
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/
4
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/
5
+
6
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/
7
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/
8
+
9
+ const isUnhelpfulNativeModuleError = (stderr) => {
10
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr)
11
+ }
12
+
13
+ const isMessageCodeBlockStartIndex = (line) => {
14
+ return RE_MESSAGE_CODE_BLOCK_START.test(line)
15
+ }
16
+
17
+ const isMessageCodeBlockEndIndex = (line) => {
18
+ return RE_MESSAGE_CODE_BLOCK_END.test(line)
19
+ }
20
+
21
+ const getMessageCodeBlock = (stderr) => {
22
+ const lines = SplitLines.splitLines(stderr)
23
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex)
24
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex)
25
+ const relevantLines = lines.slice(startIndex, endIndex)
26
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length)
27
+ return relevantMessage
28
+ }
29
+
30
+ const getNativeModuleErrorMessage = (stderr) => {
31
+ const message = getMessageCodeBlock(stderr)
32
+ return `incompatible native node module: ${message}`
33
+ }
34
+
35
+ const isModulesSyntaxError = (stderr) => {
36
+ if (!stderr) {
37
+ return false
38
+ }
39
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module')
40
+ }
41
+
42
+ const getModuleSyntaxError = (stderr) => {
43
+ return `ES Modules are not supported in electron`
44
+ }
45
+
46
+ export const getHelpfulChildProcessError = (stdout, stderr) => {
47
+ if (isUnhelpfulNativeModuleError(stderr)) {
48
+ return getNativeModuleErrorMessage(stderr)
49
+ }
50
+ if (isModulesSyntaxError(stderr)) {
51
+ return getModuleSyntaxError(stderr)
52
+ }
53
+ return 'child process error'
54
+ }
@@ -1,68 +1,15 @@
1
1
  import * as Command from '../Command/Command.js'
2
- import { CommandNotFoundError } from '../CommandNotFoundError/CommandNotFoundError.js'
3
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
4
- import * as JsonRpcErrorCode from '../JsonRpcErrorCode/JsonRpcErrorCode.js'
5
- import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
6
- import * as PrettyError from '../PrettyError/PrettyError.js'
7
- import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
2
+ import * as GetErrorResponse from '../GetErrorResponse/GetErrorResponse.js'
3
+ import * as GetSuccessResponse from '../GetSuccessResponse/GetSuccessResponse.js'
8
4
  import * as RequiresSocket from '../RequiresSocket/RequiresSocket.js'
9
5
 
10
- const shouldLogError = (error) => {
11
- if (error && error.code === ErrorCodes.ENOENT) {
12
- return false
13
- }
14
- return true
15
- }
16
-
17
6
  export const getResponse = async (message, handle) => {
18
7
  try {
19
8
  const result = RequiresSocket.requiresSocket(message.method)
20
9
  ? await Command.execute(message.method, handle, ...message.params)
21
10
  : await Command.execute(message.method, ...message.params)
22
- return {
23
- jsonrpc: JsonRpcVersion.Two,
24
- id: message.id,
25
- result: result ?? null,
26
- }
11
+ return GetSuccessResponse.getSuccessResponse(message, result)
27
12
  } catch (error) {
28
- if (error && error instanceof CommandNotFoundError) {
29
- return {
30
- jsonrpc: JsonRpcVersion.Two,
31
- id: message.id,
32
- error: {
33
- code: JsonRpcErrorCode.MethodNotFound,
34
- message: error.message,
35
- data: error.stack,
36
- },
37
- }
38
- }
39
- if (!shouldLogError(error)) {
40
- return {
41
- jsonrpc: JsonRpcVersion.Two,
42
- id: message.id,
43
- error: {
44
- code: JsonRpcErrorCode.Custom,
45
- message: `${error}`,
46
- data: {
47
- code: error.code,
48
- },
49
- },
50
- }
51
- }
52
- const prettyError = PrettyError.prepare(error)
53
- PrintPrettyError.printPrettyError(prettyError, `[shared-process] `)
54
- return {
55
- jsonrpc: JsonRpcVersion.Two,
56
- id: message.id,
57
- error: {
58
- code: JsonRpcErrorCode.Custom,
59
- message: prettyError.message,
60
- data: {
61
- stack: prettyError.stack,
62
- codeFrame: prettyError.codeFrame,
63
- type: prettyError.type,
64
- },
65
- },
66
- }
13
+ return GetErrorResponse.getErrorResponse(message, error)
67
14
  }
68
15
  }
@@ -0,0 +1,9 @@
1
+ import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
2
+
3
+ export const getSuccessResponse = (message, result) => {
4
+ return {
5
+ jsonrpc: JsonRpcVersion.Two,
6
+ id: message.id,
7
+ result: result ?? null,
8
+ }
9
+ }
@@ -7,6 +7,7 @@ import * as ExtensionHostHelperProcessIpc from '../ExtensionHostHelperProcessIpc
7
7
  import * as ExtensionHostIpc from '../ExtensionHostIpc/ExtensionHostIpc.js'
8
8
  import * as ExtensionHostRpc from '../ExtensionHostRpc/ExtensionHostRpc.js'
9
9
  import * as GetResponse from '../GetResponse/GetResponse.js'
10
+ import * as Logger from '../Logger/Logger.js'
10
11
  import * as ProtocolType from '../ProtocolType/ProtocolType.js'
11
12
  import { VError } from '../VError/VError.js'
12
13
  // TODO add tests for this
@@ -63,6 +64,15 @@ const handleWebSocketExtensionHostHelperProcess = async (message, handle) => {
63
64
  ipc._process.send(message, handle)
64
65
  }
65
66
 
67
+ const handleWebSocketUnknown = (message, handle, protocol) => {
68
+ Logger.warn(`[shared-process] unsupported sec-websocket-procotol ${protocol}`)
69
+ try {
70
+ handle.destroy()
71
+ } catch {
72
+ // ignore
73
+ }
74
+ }
75
+
66
76
  const handleWebSocket = (message, handle) => {
67
77
  const headers = message.headers
68
78
  if (!headers) {
@@ -80,7 +90,7 @@ const handleWebSocket = (message, handle) => {
80
90
  case ProtocolType.ExtensionHostHelperProcess:
81
91
  return handleWebSocketExtensionHostHelperProcess(message, handle)
82
92
  default:
83
- console.warn(`unsupported sec-websocket-procotol ${protocol}`)
93
+ return handleWebSocketUnknown(message, handle, protocol)
84
94
  }
85
95
  }
86
96