@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.
- package/config/defaultKeyBindings.json +1 -784
- package/config/defaultSettings.json +8 -1
- package/extensions/builtin.language-basics-css/extension.json +2 -1
- package/extensions/builtin.language-basics-css/languageConfiguration.json +21 -0
- package/extensions/builtin.language-basics-css/src/tokenizeCss.js +10 -1
- package/extensions/builtin.language-basics-dotenv/extension.json +5 -1
- package/extensions/builtin.language-basics-go/src/tokenizeGo.js +79 -10
- package/extensions/builtin.language-basics-html/languageConfiguration.json +66 -0
- package/extensions/builtin.language-basics-html/src/tokenizeHtml.js +89 -27
- package/extensions/builtin.language-basics-java/src/tokenizeJava.js +6 -5
- package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +29 -1
- package/extensions/builtin.language-basics-json/extension.json +4 -2
- package/extensions/builtin.language-basics-json/src/tokenizeJson.js +3 -0
- package/extensions/builtin.language-basics-jsx/src/tokenizeJsx.js +18 -5
- package/extensions/builtin.language-basics-typescript/src/tokenizeTypeScript.js +26 -0
- package/extensions/builtin.language-basics-vue/src/tokenizeVue.js +1 -1
- package/extensions/builtin.language-basics-xml/extension.json +3 -1
- package/extensions/builtin.theme-atom-one-dark/color-theme.json +2 -2
- package/extensions/builtin.theme-ayu/color-theme.json +6 -2
- package/extensions/builtin.theme-cobalt2/color-theme.json +5 -2
- package/extensions/builtin.theme-slime/color-theme.json +2 -2
- package/package.json +10 -11
- package/src/parts/Assert/Assert.js +1 -6
- package/src/parts/AssertionError/AssertionError.js +6 -0
- package/src/parts/BulkReplacement/BulkReplacement.ipc.js +7 -0
- package/src/parts/BulkReplacement/BulkReplacement.js +20 -0
- package/src/parts/BulkReplacementContent/BulkReplacementContent.js +30 -0
- package/src/parts/ChildProcessError/ChildProcessError.js +45 -0
- package/src/parts/ChromeExtension/ChromeExtension.js +2 -5
- package/src/parts/CleanStack/CleanStack.js +90 -2
- package/src/parts/CliList/CliList.js +3 -0
- package/src/parts/ClipBoard/ClipBoard.js +2 -2
- package/src/parts/ClipBoard/ClipBoardGnome.js +1 -2
- package/src/parts/ClipBoard/ClipBoardNoop.js +2 -2
- package/src/parts/ClipBoard/ClipBoardWindows.js +1 -3
- package/src/parts/Command/Command.js +5 -10
- package/src/parts/Credentials/Credentials.ipc.js +5 -5
- package/src/parts/Credentials/Credentials.js +2 -10
- package/src/parts/Desktop/Desktop.js +22 -0
- package/src/parts/Download/Download.js +2 -2
- package/src/parts/Error/Error.js +1 -1
- package/src/parts/ErrorCodes/ErrorCodes.js +2 -1
- package/src/parts/ErrorHandling/ErrorHandling.js +8 -14
- package/src/parts/ExportStatic/ExportStatic.js +8 -3
- package/src/parts/ExtensionHost/ExtensionHost.js +1 -2
- package/src/parts/ExtensionHost/ExtensionHostKeyBindings.js +0 -12
- package/src/parts/ExtensionHostRpc/ExtensionHostRpc.js +1 -1
- package/src/parts/ExtensionInstallFromFile/ExtensionInstallFromFile.js +1 -1
- package/src/parts/ExtensionInstallFromGitHub/ExtensionInstallFromGitHub.js +1 -1
- package/src/parts/ExtensionInstallFromUrl/ExtensionInstallFromUrl.js +1 -1
- package/src/parts/ExtensionLink/ExtensionLink.js +0 -19
- package/src/parts/ExtensionList/ExtensionList.js +11 -2
- package/src/parts/ExtensionManagement/ExtensionManagement.js +6 -58
- package/src/parts/ExtensionManagement/ExtensionManagementColorTheme.js +3 -1
- package/src/parts/ExtensionManagement/ExtensionManagementIconTheme.js +1 -1
- package/src/parts/ExtensionManagement/ExtensionManagementLanguages.js +7 -3
- package/src/parts/ExtensionManifestInputType/ExtensionManifestInputType.js +2 -0
- package/src/parts/ExtensionManifests/ExtensionManifests.js +3 -0
- package/src/parts/ExtensionManifests/ExtensionManifestsFromFolder.js +5 -15
- package/src/parts/ExtensionManifests/ExtensionManifestsFromLinkedExtensionsFolder.js +56 -0
- package/src/parts/ExtensionUninstall/ExtensionUninstall.js +18 -0
- package/src/parts/ExtensionUnlink/ExtensionUnlink.js +1 -1
- package/src/parts/Extract/Extract.js +2 -6
- package/src/parts/ExtractZip/ExtractZip.js +1 -1
- package/src/parts/{Error → FileNotFoundError}/FileNotFoundError.js +9 -2
- package/src/parts/FileSystem/FileSystem.js +6 -32
- package/src/parts/FirstNodeWorkerEventType/FirstNodeWorkerEventType.js +5 -0
- package/src/parts/GetDirentType/GetDirentType.js +27 -0
- package/src/parts/GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js +39 -0
- package/src/parts/GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js +21 -0
- package/src/parts/GetNewLineIndex/GetNewLineIndex.js +9 -0
- package/src/parts/GetResponse/GetResponse.js +16 -6
- package/src/parts/GetTextSearchRipGrepArgs/GetTextSearchRipGrepArgs.js +14 -0
- package/src/parts/InstallExtension/InstallExtension.ipc.js +6 -0
- package/src/parts/InstallExtension/InstallExtension.js +33 -0
- package/src/parts/IpcParent/IpcParent.js +9 -0
- package/src/parts/IpcParentModule/IpcParentModule.js +12 -0
- package/src/parts/IpcParentType/IpcParentType.js +2 -0
- package/src/parts/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js +49 -0
- package/src/parts/IpcParentWithNodeWorker/IpcParentWithNodeWorker.js +36 -0
- package/src/parts/IsEnoentErrorWindows/IsEnoentErrorWindows.js +3 -0
- package/src/parts/IsIgnoredError/IsIgnoredError.js +14 -0
- package/src/parts/Json/Json.js +3 -5
- package/src/parts/JsonError/JsonError.js +8 -14
- package/src/parts/JsonParsingError/JsonParsingError.js +17 -0
- package/src/parts/Jsonc/Jsonc.js +304 -0
- package/src/parts/JsoncCharCode/JsoncCharCode.js +23 -0
- package/src/parts/JsoncFile/JsoncFile.js +8 -0
- package/src/parts/JsoncTokenType/JsoncTokenType.js +11 -0
- package/src/parts/LimitString/LimitString.js +3 -1
- package/src/parts/MergeStacks/MergeStacks.js +3 -2
- package/src/parts/Module/Module.js +4 -0
- package/src/parts/ModuleId/ModuleId.js +2 -0
- package/src/parts/ModuleMap/ModuleMap.js +4 -0
- package/src/parts/Native/Native.js +1 -1
- package/src/parts/ParentIpc/ParentIpc.js +2 -1
- package/src/parts/Platform/Platform.js +0 -21
- package/src/parts/Preferences/Preferences.js +6 -8
- package/src/parts/PrettyError/PrettyError.js +16 -7
- package/src/parts/PrintPrettyError/PrintPrettyError.js +3 -1
- package/src/parts/RecentlyOpened/RecentlyOpened.js +3 -7
- package/src/parts/RequiresSocket/RequiresSocket.js +1 -0
- package/src/parts/RipGrep/RipGrep.js +1 -1
- package/src/parts/SearchFile/SearchFile.js +4 -9
- package/src/parts/Socket/Socket.js +2 -7
- package/src/parts/Terminal/Terminal.ipc.js +4 -41
- package/src/parts/Terminal/Terminal.js +29 -25
- package/src/parts/TextSearch/TextSearch.js +102 -108
- package/src/parts/ToAbsolutePaths/ToAbsolutePaths.js +9 -0
- package/src/parts/ToTextSearchResult/ToTextSearchResult.js +42 -0
- package/src/parts/Trash/Trash.js +1 -2
- /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
|
|
5
|
-
import
|
|
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
|
|
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:
|
|
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 =
|
|
241
|
+
const type = GetDirentType.getDirentType(stats)
|
|
268
242
|
return type
|
|
269
243
|
}
|
|
270
244
|
|
|
@@ -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
|
+
}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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,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,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,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
|
+
}
|
package/src/parts/Json/Json.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
}
|