@lvce-editor/shared-process 0.13.0 → 0.14.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.
Files changed (112) hide show
  1. package/config/defaultKeyBindings.json +1 -784
  2. package/config/defaultSettings.json +8 -1
  3. package/extensions/builtin.language-basics-css/extension.json +2 -1
  4. package/extensions/builtin.language-basics-css/languageConfiguration.json +21 -0
  5. package/extensions/builtin.language-basics-css/src/tokenizeCss.js +10 -1
  6. package/extensions/builtin.language-basics-dotenv/extension.json +5 -1
  7. package/extensions/builtin.language-basics-go/src/tokenizeGo.js +79 -10
  8. package/extensions/builtin.language-basics-html/languageConfiguration.json +66 -0
  9. package/extensions/builtin.language-basics-html/src/tokenizeHtml.js +89 -27
  10. package/extensions/builtin.language-basics-java/src/tokenizeJava.js +6 -5
  11. package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +29 -1
  12. package/extensions/builtin.language-basics-json/extension.json +4 -2
  13. package/extensions/builtin.language-basics-json/src/tokenizeJson.js +3 -0
  14. package/extensions/builtin.language-basics-jsx/src/tokenizeJsx.js +18 -5
  15. package/extensions/builtin.language-basics-typescript/src/tokenizeTypeScript.js +26 -0
  16. package/extensions/builtin.language-basics-vue/src/tokenizeVue.js +1 -1
  17. package/extensions/builtin.language-basics-xml/extension.json +3 -1
  18. package/extensions/builtin.theme-atom-one-dark/color-theme.json +2 -2
  19. package/extensions/builtin.theme-ayu/color-theme.json +6 -2
  20. package/extensions/builtin.theme-cobalt2/color-theme.json +5 -2
  21. package/extensions/builtin.theme-slime/color-theme.json +2 -2
  22. package/package.json +10 -11
  23. package/src/parts/Assert/Assert.js +1 -6
  24. package/src/parts/AssertionError/AssertionError.js +6 -0
  25. package/src/parts/BulkReplacement/BulkReplacement.ipc.js +7 -0
  26. package/src/parts/BulkReplacement/BulkReplacement.js +20 -0
  27. package/src/parts/BulkReplacementContent/BulkReplacementContent.js +30 -0
  28. package/src/parts/ChildProcessError/ChildProcessError.js +45 -0
  29. package/src/parts/ChromeExtension/ChromeExtension.js +2 -5
  30. package/src/parts/CleanStack/CleanStack.js +90 -2
  31. package/src/parts/CliList/CliList.js +3 -0
  32. package/src/parts/ClipBoard/ClipBoard.js +2 -2
  33. package/src/parts/ClipBoard/ClipBoardGnome.js +1 -2
  34. package/src/parts/ClipBoard/ClipBoardNoop.js +2 -2
  35. package/src/parts/ClipBoard/ClipBoardWindows.js +1 -3
  36. package/src/parts/Command/Command.js +5 -10
  37. package/src/parts/Credentials/Credentials.ipc.js +5 -5
  38. package/src/parts/Credentials/Credentials.js +2 -10
  39. package/src/parts/Desktop/Desktop.js +22 -0
  40. package/src/parts/Download/Download.js +2 -2
  41. package/src/parts/Error/Error.js +1 -1
  42. package/src/parts/ErrorCodes/ErrorCodes.js +2 -1
  43. package/src/parts/ErrorHandling/ErrorHandling.js +8 -14
  44. package/src/parts/ExportStatic/ExportStatic.js +8 -3
  45. package/src/parts/ExtensionHost/ExtensionHost.js +1 -2
  46. package/src/parts/ExtensionHost/ExtensionHostKeyBindings.js +0 -12
  47. package/src/parts/ExtensionHostRpc/ExtensionHostRpc.js +1 -1
  48. package/src/parts/ExtensionInstallFromFile/ExtensionInstallFromFile.js +1 -1
  49. package/src/parts/ExtensionInstallFromGitHub/ExtensionInstallFromGitHub.js +1 -1
  50. package/src/parts/ExtensionInstallFromUrl/ExtensionInstallFromUrl.js +1 -1
  51. package/src/parts/ExtensionLink/ExtensionLink.js +0 -19
  52. package/src/parts/ExtensionList/ExtensionList.js +11 -2
  53. package/src/parts/ExtensionManagement/ExtensionManagement.js +6 -58
  54. package/src/parts/ExtensionManagement/ExtensionManagementColorTheme.js +3 -1
  55. package/src/parts/ExtensionManagement/ExtensionManagementIconTheme.js +1 -1
  56. package/src/parts/ExtensionManagement/ExtensionManagementLanguages.js +7 -3
  57. package/src/parts/ExtensionManifestInputType/ExtensionManifestInputType.js +2 -0
  58. package/src/parts/ExtensionManifests/ExtensionManifests.js +3 -0
  59. package/src/parts/ExtensionManifests/ExtensionManifestsFromFolder.js +5 -15
  60. package/src/parts/ExtensionManifests/ExtensionManifestsFromLinkedExtensionsFolder.js +56 -0
  61. package/src/parts/ExtensionUninstall/ExtensionUninstall.js +18 -0
  62. package/src/parts/ExtensionUnlink/ExtensionUnlink.js +1 -1
  63. package/src/parts/Extract/Extract.js +2 -6
  64. package/src/parts/ExtractZip/ExtractZip.js +1 -1
  65. package/src/parts/{Error → FileNotFoundError}/FileNotFoundError.js +9 -2
  66. package/src/parts/FileSystem/FileSystem.js +6 -32
  67. package/src/parts/FirstNodeWorkerEventType/FirstNodeWorkerEventType.js +5 -0
  68. package/src/parts/GetDirentType/GetDirentType.js +27 -0
  69. package/src/parts/GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js +39 -0
  70. package/src/parts/GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js +21 -0
  71. package/src/parts/GetNewLineIndex/GetNewLineIndex.js +9 -0
  72. package/src/parts/GetResponse/GetResponse.js +16 -6
  73. package/src/parts/GetTextSearchRipGrepArgs/GetTextSearchRipGrepArgs.js +14 -0
  74. package/src/parts/InstallExtension/InstallExtension.ipc.js +6 -0
  75. package/src/parts/InstallExtension/InstallExtension.js +33 -0
  76. package/src/parts/IpcParent/IpcParent.js +9 -0
  77. package/src/parts/IpcParentModule/IpcParentModule.js +12 -0
  78. package/src/parts/IpcParentType/IpcParentType.js +2 -0
  79. package/src/parts/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js +49 -0
  80. package/src/parts/IpcParentWithNodeWorker/IpcParentWithNodeWorker.js +36 -0
  81. package/src/parts/IsEnoentErrorWindows/IsEnoentErrorWindows.js +3 -0
  82. package/src/parts/IsIgnoredError/IsIgnoredError.js +14 -0
  83. package/src/parts/Json/Json.js +3 -5
  84. package/src/parts/JsonError/JsonError.js +8 -14
  85. package/src/parts/JsonParsingError/JsonParsingError.js +17 -0
  86. package/src/parts/Jsonc/Jsonc.js +304 -0
  87. package/src/parts/JsoncCharCode/JsoncCharCode.js +23 -0
  88. package/src/parts/JsoncFile/JsoncFile.js +8 -0
  89. package/src/parts/JsoncTokenType/JsoncTokenType.js +11 -0
  90. package/src/parts/LimitString/LimitString.js +3 -1
  91. package/src/parts/MergeStacks/MergeStacks.js +3 -2
  92. package/src/parts/Module/Module.js +4 -0
  93. package/src/parts/ModuleId/ModuleId.js +2 -0
  94. package/src/parts/ModuleMap/ModuleMap.js +4 -0
  95. package/src/parts/Native/Native.js +1 -1
  96. package/src/parts/ParentIpc/ParentIpc.js +2 -1
  97. package/src/parts/Platform/Platform.js +0 -21
  98. package/src/parts/Preferences/Preferences.js +6 -8
  99. package/src/parts/PrettyError/PrettyError.js +16 -7
  100. package/src/parts/PrintPrettyError/PrintPrettyError.js +3 -1
  101. package/src/parts/RecentlyOpened/RecentlyOpened.js +3 -7
  102. package/src/parts/RequiresSocket/RequiresSocket.js +1 -0
  103. package/src/parts/RipGrep/RipGrep.js +1 -1
  104. package/src/parts/SearchFile/SearchFile.js +4 -9
  105. package/src/parts/Socket/Socket.js +2 -7
  106. package/src/parts/Terminal/Terminal.ipc.js +4 -41
  107. package/src/parts/Terminal/Terminal.js +29 -25
  108. package/src/parts/TextSearch/TextSearch.js +102 -108
  109. package/src/parts/ToAbsolutePaths/ToAbsolutePaths.js +9 -0
  110. package/src/parts/ToTextSearchResult/ToTextSearchResult.js +42 -0
  111. package/src/parts/Trash/Trash.js +1 -2
  112. /package/src/parts/{RgPath/RgPath.js → RipGrepPath/RipGrepPath.js} +0 -0
@@ -1,9 +1,16 @@
1
- import VError from 'verror'
2
1
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
+ import { VError } from '../VError/VError.js'
3
+
4
+ const getDisplayPath = (path) => {
5
+ if (path === '') {
6
+ return '<empty string>'
7
+ }
8
+ return path
9
+ }
3
10
 
4
11
  export class FileNotFoundError extends VError {
5
12
  constructor(path) {
6
- super(`File not found '${path}'`)
13
+ super(`File not found: '${getDisplayPath(path)}'`)
7
14
  this.name = 'FileNotFoundError'
8
15
  this.code = ErrorCodes.ENOENT
9
16
  }
@@ -1,14 +1,14 @@
1
1
  // TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
2
2
  import * as fs from 'node:fs/promises'
3
3
  import * as os from 'node:os'
4
- import VError from 'verror'
5
- import * as DirentType from '../DirentType/DirentType.js'
6
- import { FileNotFoundError } from '../Error/FileNotFoundError.js'
4
+ import * as EncodingType from '../EncodingType/EncodingType.js'
5
+ import { FileNotFoundError } from '../FileNotFoundError/FileNotFoundError.js'
7
6
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
7
+ import * as GetDirentType from '../GetDirentType/GetDirentType.js'
8
8
  import * as Path from '../Path/Path.js'
9
9
  import * as Platform from '../Platform/Platform.js'
10
10
  import * as Trash from '../Trash/Trash.js'
11
- import * as EncodingType from '../EncodingType/EncodingType.js'
11
+ import { VError } from '../VError/VError.js'
12
12
 
13
13
  export const state = {
14
14
  watcherMap: Object.create(null),
@@ -132,39 +132,13 @@ export const exists = async (path) => {
132
132
  }
133
133
  }
134
134
 
135
- /**
136
- * @param {import('fs').Dirent|import('fs').StatsBase} dirent
137
- */
138
- const getType = (dirent) => {
139
- if (dirent.isFile()) {
140
- return DirentType.File
141
- }
142
- if (dirent.isDirectory()) {
143
- return DirentType.Directory
144
- }
145
- if (dirent.isSymbolicLink()) {
146
- return DirentType.Symlink
147
- }
148
- if (dirent.isSocket()) {
149
- return DirentType.Socket
150
- }
151
- if (dirent.isBlockDevice()) {
152
- return DirentType.BlockDevice
153
- }
154
- if (dirent.isCharacterDevice()) {
155
- return DirentType.CharacterDevice
156
- }
157
- console.log({ dirent })
158
- return DirentType.Unknown
159
- }
160
-
161
135
  /**
162
136
  * @param {import('fs').Dirent} dirent
163
137
  */
164
138
  const toPrettyDirent = (dirent) => {
165
139
  return {
166
140
  name: dirent.name,
167
- type: getType(dirent),
141
+ type: GetDirentType.getDirentType(dirent),
168
142
  }
169
143
  }
170
144
 
@@ -264,7 +238,7 @@ export const getRealPath = async (path) => {
264
238
  // TODO handle error
265
239
  export const stat = async (path) => {
266
240
  const stats = await fs.stat(path)
267
- const type = getType(stats)
241
+ const type = GetDirentType.getDirentType(stats)
268
242
  return type
269
243
  }
270
244
 
@@ -0,0 +1,5 @@
1
+ export const Exit = 'exit'
2
+
3
+ export const Error = 'error'
4
+
5
+ export const Message = 'message'
@@ -0,0 +1,27 @@
1
+ import * as DirentType from '../DirentType/DirentType.js'
2
+
3
+ /**
4
+ * @param {import('fs').Dirent|import('fs').StatsBase} dirent
5
+ */
6
+ export const getDirentType = (dirent) => {
7
+ if (dirent.isFile()) {
8
+ return DirentType.File
9
+ }
10
+ if (dirent.isDirectory()) {
11
+ return DirentType.Directory
12
+ }
13
+ if (dirent.isSymbolicLink()) {
14
+ return DirentType.Symlink
15
+ }
16
+ if (dirent.isSocket()) {
17
+ return DirentType.Socket
18
+ }
19
+ if (dirent.isBlockDevice()) {
20
+ return DirentType.BlockDevice
21
+ }
22
+ if (dirent.isCharacterDevice()) {
23
+ return DirentType.CharacterDevice
24
+ }
25
+ console.log({ dirent })
26
+ return DirentType.Unknown
27
+ }
@@ -0,0 +1,39 @@
1
+ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
2
+
3
+ export const getFirstNodeChildProcessEvent = async (childProcess) => {
4
+ const { type, event, stdout, stderr } = await new Promise((resolve, reject) => {
5
+ let stderr = ''
6
+ let stdout = ''
7
+ const cleanup = () => {
8
+ childProcess.stderr.off('data', handleStdErrData)
9
+ childProcess.stdout.off('data', handleStdoutData)
10
+ childProcess.off('message', handleMessage)
11
+ childProcess.off('exit', handleExit)
12
+ childProcess.off('error', handleError)
13
+ }
14
+ const handleStdErrData = (data) => {
15
+ stderr += data
16
+ }
17
+ const handleStdoutData = (data) => {
18
+ stdout += data
19
+ }
20
+ const handleMessage = (event) => {
21
+ cleanup()
22
+ resolve({ type: FirstNodeWorkerEventType.Message, event, stdout, stderr })
23
+ }
24
+ const handleExit = (event) => {
25
+ cleanup()
26
+ resolve({ type: FirstNodeWorkerEventType.Exit, event, stdout, stderr })
27
+ }
28
+ const handleError = (event) => {
29
+ cleanup()
30
+ resolve({ type: FirstNodeWorkerEventType.Error, event, stdout, stderr })
31
+ }
32
+ childProcess.stderr.on('data', handleStdErrData)
33
+ childProcess.stdout.on('data', handleStdoutData)
34
+ childProcess.on('message', handleMessage)
35
+ childProcess.on('exit', handleExit)
36
+ childProcess.on('error', handleError)
37
+ })
38
+ return { type, event, stdout, stderr }
39
+ }
@@ -0,0 +1,21 @@
1
+ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
2
+
3
+ export const getFirstNodeWorkerEvent = async (worker) => {
4
+ const { type, event } = await new Promise((resolve, reject) => {
5
+ const cleanup = () => {
6
+ worker.off('exit', handleExit)
7
+ worker.off('error', handleError)
8
+ }
9
+ const handleExit = (event) => {
10
+ cleanup()
11
+ resolve({ type: FirstNodeWorkerEventType.Exit, event })
12
+ }
13
+ const handleError = (event) => {
14
+ cleanup()
15
+ resolve({ type: FirstNodeWorkerEventType.Error, event })
16
+ }
17
+ worker.on('exit', handleExit)
18
+ worker.on('error', handleError)
19
+ })
20
+ return { type, event }
21
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {string} string
4
+ * @param {number|undefined} startIndex
5
+ * @returns
6
+ */
7
+ export const getNewLineIndex = (string, startIndex = undefined) => {
8
+ return string.indexOf('\n', startIndex)
9
+ }
@@ -1,24 +1,31 @@
1
1
  import * as Command from '../Command/Command.js'
2
+ import { CommandNotFoundError } from '../CommandNotFoundError/CommandNotFoundError.js'
2
3
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
4
  import * as JsonRpcErrorCode from '../JsonRpcErrorCode/JsonRpcErrorCode.js'
4
5
  import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
5
6
  import * as PrettyError from '../PrettyError/PrettyError.js'
6
7
  import * as PrintPrettyError from '../PrintPrettyError/PrintPrettyError.js'
7
- import { requiresSocket } from '../RequiresSocket/RequiresSocket.js'
8
+ import * as RequiresSocket from '../RequiresSocket/RequiresSocket.js'
9
+
10
+ const shouldLogError = (error) => {
11
+ if (error && error.code === ErrorCodes.ENOENT) {
12
+ return false
13
+ }
14
+ return true
15
+ }
8
16
 
9
17
  export const getResponse = async (message, handle) => {
10
18
  try {
11
- const result = requiresSocket(message.method)
19
+ const result = RequiresSocket.requiresSocket(message.method)
12
20
  ? await Command.execute(message.method, handle, ...message.params)
13
21
  : await Command.execute(message.method, ...message.params)
14
-
15
22
  return {
16
23
  jsonrpc: JsonRpcVersion.Two,
17
24
  id: message.id,
18
25
  result: result ?? null,
19
26
  }
20
27
  } catch (error) {
21
- if (error && error instanceof Error && error.message && error.message.startsWith('method not found')) {
28
+ if (error && error instanceof CommandNotFoundError) {
22
29
  return {
23
30
  jsonrpc: JsonRpcVersion.Two,
24
31
  id: message.id,
@@ -29,14 +36,16 @@ export const getResponse = async (message, handle) => {
29
36
  },
30
37
  }
31
38
  }
32
- // @ts-ignore
33
- if (error && error instanceof Error && error.code === ErrorCodes.ENOENT) {
39
+ if (!shouldLogError(error)) {
34
40
  return {
35
41
  jsonrpc: JsonRpcVersion.Two,
36
42
  id: message.id,
37
43
  error: {
38
44
  code: JsonRpcErrorCode.Custom,
39
45
  message: `${error}`,
46
+ data: {
47
+ code: error.code,
48
+ },
40
49
  },
41
50
  }
42
51
  }
@@ -51,6 +60,7 @@ export const getResponse = async (message, handle) => {
51
60
  data: {
52
61
  stack: prettyError.stack,
53
62
  codeFrame: prettyError.codeFrame,
63
+ type: prettyError.type,
54
64
  },
55
65
  },
56
66
  }
@@ -0,0 +1,14 @@
1
+ export const getRipGrepArgs = ({ threads, isCaseSensitive, searchString }) => {
2
+ const ripGrepArgs = ['--smart-case', '--stats', '--json']
3
+ ripGrepArgs.push('--threads', `${threads}`)
4
+ if (isCaseSensitive) {
5
+ ripGrepArgs.push('--case-sensitive')
6
+ } else {
7
+ ripGrepArgs.push('--ignore-case')
8
+ }
9
+ ripGrepArgs.push('--fixed-strings')
10
+ ripGrepArgs.push('--')
11
+ ripGrepArgs.push(searchString)
12
+ ripGrepArgs.push('.')
13
+ return ripGrepArgs
14
+ }
@@ -0,0 +1,6 @@
1
+ import * as InstallExtension from './InstallExtension.js'
2
+
3
+ // prettier-ignore
4
+ export const Commands = {
5
+ 'InstallExtension.installExtension': InstallExtension.installExtension,
6
+ }
@@ -0,0 +1,33 @@
1
+ import * as Debug from '../Debug/Debug.js'
2
+ import * as Download from '../Download/Download.js'
3
+ import * as Extract from '../Extract/Extract.js'
4
+ import * as Path from '../Path/Path.js'
5
+ import * as Platform from '../Platform/Platform.js'
6
+ import * as Queue from '../Queue/Queue.js'
7
+ import { VError } from '../VError/VError.js'
8
+
9
+ export const installExtension = async (id) => {
10
+ // TODO this should be a stateless function, renderer-worker should have info on marketplace url
11
+ // TODO use command.execute
12
+ try {
13
+ const marketplaceUrl = Platform.getMarketplaceUrl()
14
+ Debug.debug(`ExtensionManagement#install ${id}`)
15
+ const cachedExtensionsPath = Platform.getCachedExtensionsPath()
16
+ const extensionsPath = Platform.getExtensionsPath()
17
+ // TODO maybe a queue is over engineering here
18
+ await Queue.add('download', async () => {
19
+ Debug.debug(`ExtensionManagement#download ${id}`)
20
+ // TODO use command.execute
21
+ await Download.download(`${marketplaceUrl}/download/${id}`, Path.join(cachedExtensionsPath, `${id}.tar.br`))
22
+ Debug.debug(`ExtensionManagement#extract ${id}`)
23
+ await Extract.extractTarBr(Path.join(cachedExtensionsPath, `${id}.tar.br`), Path.join(extensionsPath, id))
24
+ })
25
+ // TODO should this be here? (probably not)
26
+ // await ExtensionHost.enableExtension({
27
+ // id,
28
+ // type: 'marketplace',
29
+ // })
30
+ } catch (error) {
31
+ throw new VError(error, `Failed to install extension "${id}"`)
32
+ }
33
+ }
@@ -0,0 +1,9 @@
1
+ import * as IpcParentModule from '../IpcParentModule/IpcParentModule.js'
2
+
3
+ export const create = async ({ method, ...options }) => {
4
+ const module = await IpcParentModule.getModule(method)
5
+ // @ts-ignore
6
+ const rawIpc = await module.create(options)
7
+ const ipc = module.wrap(rawIpc)
8
+ return ipc
9
+ }
@@ -0,0 +1,12 @@
1
+ import * as IpcParentType from '../IpcParentType/IpcParentType.js'
2
+
3
+ export const getModule = (method) => {
4
+ switch (method) {
5
+ case IpcParentType.NodeWorker:
6
+ return import('../IpcParentWithNodeWorker/IpcParentWithNodeWorker.js')
7
+ case IpcParentType.NodeForkedProcess:
8
+ return import('../IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js')
9
+ default:
10
+ throw new Error('unexpected ipc type')
11
+ }
12
+ }
@@ -0,0 +1,2 @@
1
+ export const NodeWorker = 1
2
+ export const NodeForkedProcess = 2
@@ -0,0 +1,49 @@
1
+ import * as Assert from '../Assert/Assert.js'
2
+ import { fork } from 'node:child_process'
3
+ import * as GetFirstNodeChildProcessEvent from '../GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js'
4
+ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
5
+ import { ChildProcessError } from '../ChildProcessError/ChildProcessError.js'
6
+ import { VError } from '../VError/VError.js'
7
+
8
+ export const create = async ({ path, argv = [], env, execArgv = [], stdio = 'inherit', name = 'child process' }) => {
9
+ try {
10
+ Assert.string(path)
11
+ const childProcess = fork(path, argv, {
12
+ env,
13
+ execArgv,
14
+ stdio: 'pipe',
15
+ })
16
+ const { type, event, stdout, stderr } = await GetFirstNodeChildProcessEvent.getFirstNodeChildProcessEvent(childProcess)
17
+ if (type === FirstNodeWorkerEventType.Exit) {
18
+ throw new ChildProcessError(stderr)
19
+ }
20
+ if (type === FirstNodeWorkerEventType.Error) {
21
+ throw new Error(`child process had an error ${event}`)
22
+ }
23
+ if (stdio === 'inherit' && childProcess.stdout && childProcess.stderr) {
24
+ childProcess.stdout.pipe(process.stdout)
25
+ childProcess.stderr.pipe(process.stderr)
26
+ }
27
+ return childProcess
28
+ } catch (error) {
29
+ throw new VError(error, `Failed to launch ${name}`)
30
+ }
31
+ }
32
+
33
+ export const wrap = (childProcess) => {
34
+ return {
35
+ childProcess,
36
+ on(event, listener) {
37
+ this.childProcess.on(event, listener)
38
+ },
39
+ send(message) {
40
+ this.childProcess.send(message)
41
+ },
42
+ sendAndTransfer(message, transfer) {
43
+ throw new Error('transfer is not supported')
44
+ },
45
+ dispose() {
46
+ this.childProcess.kill()
47
+ },
48
+ }
49
+ }
@@ -0,0 +1,36 @@
1
+ import { Worker } from 'node:worker_threads'
2
+ import * as Assert from '../Assert/Assert.js'
3
+ import * as FirstNodeWorkerEventType from '../FirstNodeWorkerEventType/FirstNodeWorkerEventType.js'
4
+ import * as GetFirstNodeWorkerEvent from '../GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js'
5
+
6
+ export const create = async ({ path, argv, env, execArgv }) => {
7
+ Assert.string(path)
8
+ const worker = new Worker(path, {
9
+ argv,
10
+ env,
11
+ execArgv,
12
+ })
13
+ const { type, event } = await GetFirstNodeWorkerEvent.getFirstNodeWorkerEvent(worker)
14
+ if (type === FirstNodeWorkerEventType.Error) {
15
+ throw event
16
+ }
17
+ return worker
18
+ }
19
+
20
+ export const wrap = (worker) => {
21
+ return {
22
+ worker,
23
+ on(event, listener) {
24
+ this.worker.on(event, listener)
25
+ },
26
+ send(message) {
27
+ this.worker.postMessage(message)
28
+ },
29
+ sendAndTransfer(message, transfer) {
30
+ this.worker.postMessage(message, transfer)
31
+ },
32
+ dispose() {
33
+ this.worker.terminate()
34
+ },
35
+ }
36
+ }
@@ -0,0 +1,3 @@
1
+ export const isEnoentErrorWindows = (error) => {
2
+ return error && error.message && error.message.includes('The system cannot find the path specified.')
3
+ }
@@ -0,0 +1,14 @@
1
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
+ import * as Process from '../Process/Process.js'
3
+
4
+ export const isIgnoredError = (error) => {
5
+ if (error && error.code === ErrorCodes.EPIPE && !process.connected) {
6
+ // parent process is disposed, ignore
7
+ return true
8
+ }
9
+ if (error && error.code === ErrorCodes.ERR_IPC_CHANNEL_CLOSED && !Process.isConnected()) {
10
+ // parent process is disposed, ignore
11
+ return true
12
+ }
13
+ return false
14
+ }
@@ -1,16 +1,14 @@
1
1
  // parsing error handling based on https://github.com/sindresorhus/parse-json/blob/main/index.js
2
2
 
3
+ import { JsonParsingError } from '../JsonParsingError/JsonParsingError.js'
4
+
3
5
  export const parse = async (string, filePath) => {
4
6
  try {
5
7
  return JSON.parse(string)
6
8
  } catch (error) {
7
9
  const JsonError = await import('../JsonError/JsonError.js')
8
10
  const errorProps = JsonError.getErrorPropsFromError(error, string, filePath)
9
- const jsonError = new Error(errorProps.message)
10
- jsonError.stack = errorProps.stack
11
- // @ts-ignore
12
- jsonError.codeFrame = errorProps.codeFrame
13
- throw jsonError
11
+ throw new JsonParsingError(errorProps.message, errorProps.codeFrame, errorProps.stack)
14
12
  }
15
13
  }
16
14
 
@@ -16,15 +16,13 @@ export const getErrorPropsFromError = (error, string, filePath) => {
16
16
  const index = Number(indexMatch[1])
17
17
  const location = lines.locationForIndex(index)
18
18
  if (location) {
19
- const codeFrame = codeFrameColumns(
20
- string,
21
- { start: { line: location.line + 1, column: location.column + 1 } },
22
- { highlightCode: false }
23
- )
19
+ const line = location.line + 1
20
+ const column = location.column + 1
21
+ const codeFrame = codeFrameColumns(string, { start: { line, column } }, { highlightCode: false })
24
22
  return {
25
23
  codeFrame,
26
24
  message: 'Json Parsing Error',
27
- stack: `at ${filePath}`,
25
+ stack: ` at ${filePath}:${line}:${column}`,
28
26
  }
29
27
  }
30
28
  }
@@ -32,7 +30,7 @@ export const getErrorPropsFromError = (error, string, filePath) => {
32
30
  return {
33
31
  codeFrame: ``,
34
32
  message: 'Json Parsing Error: Cannot parse empty string',
35
- stack: `at ${filePath}`,
33
+ stack: ` at ${filePath}`,
36
34
  }
37
35
  }
38
36
 
@@ -41,22 +39,18 @@ export const getErrorPropsFromError = (error, string, filePath) => {
41
39
  const index = string.length - 1
42
40
  const location = lines.locationForIndex(index)
43
41
  if (location) {
44
- const codeFrame = codeFrameColumns(
45
- string,
46
- { start: { line: location.line + 1, column: location.column + 1 } },
47
- { highlightCode: false }
48
- )
42
+ const codeFrame = codeFrameColumns(string, { start: { line: location.line + 1, column: location.column + 1 } }, { highlightCode: false })
49
43
  return {
50
44
  codeFrame,
51
45
  message: 'Json Parsing Error',
52
- stack: `at ${filePath}`,
46
+ stack: ` at ${filePath}`,
53
47
  }
54
48
  }
55
49
  }
56
50
  return {
57
51
  codeFrame: ``,
58
52
  message: 'Json Parsing Error',
59
- stack: `at ${filePath}`,
53
+ stack: ` at ${filePath}`,
60
54
  }
61
55
  }
62
56
 
@@ -0,0 +1,17 @@
1
+ import * as JoinLines from '../JoinLines/JoinLines.js'
2
+ import * as SplitLines from '../SplitLines/SplitLines.js'
3
+
4
+ export class JsonParsingError extends Error {
5
+ constructor(message, codeFrame, stack) {
6
+ super(message)
7
+ this.name = 'JsonParsingError'
8
+ if (codeFrame) {
9
+ this.codeFrame = codeFrame
10
+ }
11
+
12
+ if (stack) {
13
+ const parentStack = JoinLines.joinLines(SplitLines.splitLines(this.stack).slice(1))
14
+ this.stack = this.name + ': ' + this.message + '\n' + stack + '\n' + parentStack
15
+ }
16
+ }
17
+ }