@lvce-editor/shared-process 0.11.4 → 0.11.6

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.
@@ -742,5 +742,9 @@
742
742
  "key": "Enter",
743
743
  "command": "SimpleBrowser.go",
744
744
  "when": "focus.SimpleBrowserInput"
745
+ },
746
+ {
747
+ "key": "ctrl+r",
748
+ "command": "Window.reload"
745
749
  }
746
750
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.11.4",
3
+ "version": "0.11.6",
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.18.6",
20
- "@lvce-editor/extension-host": "0.11.4",
21
- "@lvce-editor/extension-host-helper-process": "0.11.4",
22
- "@lvce-editor/pty-host": "0.11.4",
20
+ "@lvce-editor/extension-host": "0.11.6",
21
+ "@lvce-editor/extension-host-helper-process": "0.11.6",
22
+ "@lvce-editor/pty-host": "0.11.6",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^6.1.0",
25
25
  "exit-hook": "^3.1.2",
@@ -1,3 +1,6 @@
1
+ import * as Logger from '../Logger/Logger.js'
2
+ import * as Process from '../Process/Process.js'
3
+
1
4
  const getModule = (argv0) => {
2
5
  switch (argv0) {
3
6
  case 'install':
@@ -20,7 +23,7 @@ export const handleCliArgs = async (argv, console, process) => {
20
23
  try {
21
24
  await module.handleCliArgs(argv, console, process)
22
25
  } catch (error) {
23
- console.error(error)
24
- process.exitCode = 1
26
+ Logger.error(error)
27
+ Process.setExitCode(1)
25
28
  }
26
29
  }
@@ -1,9 +1,10 @@
1
1
  import * as ExtensionInstall from '../ExtensionInstall/ExtensionInstall.js'
2
+ import * as Logger from '../Logger/Logger.js'
2
3
 
3
4
  export const handleCliArgs = async (argv, console) => {
4
5
  const extension = argv[1]
5
6
  if (!extension) {
6
- console.error('extension argument is required')
7
+ Logger.error('extension argument is required')
7
8
  return
8
9
  }
9
10
  await ExtensionInstall.install(extension)
@@ -1,5 +1,7 @@
1
1
  import * as ExtensionLink from '../ExtensionLink/ExtensionLink.js'
2
2
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
+ import * as Logger from '../Logger/Logger.js'
4
+ import * as Process from '../Process/Process.js'
3
5
 
4
6
  export const handleCliArgs = async (argv) => {
5
7
  try {
@@ -7,8 +9,8 @@ export const handleCliArgs = async (argv) => {
7
9
  await ExtensionLink.link(path)
8
10
  } catch (error) {
9
11
  if (error && error.code === ErrorCodes.E_MANIFEST_NOT_FOUND) {
10
- console.error(error.message)
11
- process.exitCode = 128
12
+ Logger.error(error.message)
13
+ Process.setExitCode(128)
12
14
  return
13
15
  }
14
16
  throw error
@@ -1,6 +1,7 @@
1
1
  import * as ExtensionUnlink from '../ExtensionUnlink/ExtensionUnlink.js'
2
+ import * as Process from '../Process/Process.js'
2
3
 
3
4
  export const handleCliArgs = async (argv, console, process) => {
4
- const path = argv.length > 1 ? argv[1] : process.cwd()
5
+ const path = argv.length > 1 ? argv[1] : Process.cwd()
5
6
  await ExtensionUnlink.unlink(path)
6
7
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import VError from 'verror'
6
6
  import * as Exec from '../Exec/Exec.js'
7
+ import * as SplitLines from '../SplitLines/SplitLines.js'
7
8
 
8
9
  const removePrefix = (file) => {
9
10
  if (file.startsWith('file://')) {
@@ -35,7 +36,7 @@ export const readFiles = async () => {
35
36
  }
36
37
  throw error
37
38
  }
38
- const [type, ...files] = result.stdout.split('\n')
39
+ const [type, ...files] = SplitLines.splitLines(result.stdout)
39
40
  const actualFiles = files.map(removePrefix)
40
41
  return {
41
42
  source: 'gnomeCopiedFiles',
@@ -1,6 +1,8 @@
1
1
  import { createWriteStream, writeFileSync } from 'node:fs'
2
2
  import { performance } from 'node:perf_hooks'
3
3
  import * as ExtensionHost from '../ExtensionHost/ExtensionHost.js'
4
+ import * as Process from '../Process/Process.js'
5
+ import * as Timeout from '../Timeout/Timeout.js'
4
6
 
5
7
  export const measureLatencyBetweenExtensionHostAndSharedProcess = async (
6
8
  socket,
@@ -63,7 +65,7 @@ export const getNodeStartupTiming = () => {
63
65
 
64
66
  export const sharedProcessMemoryUsage = () => {
65
67
  // TODO also print out number of watched files
66
- return process.memoryUsage()
68
+ return Process.memoryUsage()
67
69
  }
68
70
 
69
71
  // TODO not sure if this is actually useful
@@ -76,7 +78,7 @@ export const allocateMemory = () => {
76
78
 
77
79
  /* istanbul ignore next */
78
80
  export const crashSharedProcess = () => {
79
- setTimeout(() => {
81
+ Timeout.setTimeout(() => {
80
82
  throw new Error('oops')
81
83
  }, 0)
82
84
  }
@@ -112,7 +114,7 @@ export const createProfile = async () => {
112
114
  session.post('Profiler.start', () => {
113
115
  // Invoke business logic under measurement here...
114
116
 
115
- setTimeout(() => {
117
+ Timeout.setTimeout(() => {
116
118
  session.post('Profiler.stop', (error, { profile }) => {
117
119
  // Write profile to disk, upload, etc.
118
120
  if (!error) {
@@ -7,3 +7,15 @@ export const EEXIST = 'EEXIST'
7
7
  export const ENOTDIR = 'ENOTDIR'
8
8
 
9
9
  export const E_MANIFEST_NOT_FOUND = 'E_MANIFEST_NOT_FOUND'
10
+
11
+ export const EPIPE = 'EPIPE'
12
+
13
+ export const ERR_IPC_CHANNEL_CLOSED = 'ERR_IPC_CHANNEL_CLOSED'
14
+
15
+ export const E_COLOR_THEME_NOT_FOUND = 'E_COLOR_THEME_NOT_FOUND'
16
+
17
+ export const E_ICON_THEME_NOT_FOUND = 'E_ICON_THEME_NOT_FOUND'
18
+
19
+ export const ECONNRESET = 'ECONNRESET'
20
+
21
+ export const EPERM = 'EPERM'
@@ -1,4 +1,7 @@
1
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
+ import * as PrettyError from '../PrettyError/PrettyError.js'
1
3
  import * as Socket from '../Socket/Socket.js'
4
+ import * as Process from '../Process/Process.js'
2
5
 
3
6
  export const state = {
4
7
  seenErrors: [],
@@ -38,3 +41,39 @@ export const handleError = (error) => {
38
41
  })
39
42
  printPrettyError(prettyError)
40
43
  }
44
+
45
+ // TODO handle structure: one shared process multiple extension hosts
46
+
47
+ // TODO use named functions here
48
+
49
+ const firstErrorLine = (error) => {
50
+ if (error.stack) {
51
+ return error.stack.slice(0, error.stack.indexOf('\n'))
52
+ }
53
+ if (error.message) {
54
+ return error.message
55
+ }
56
+ return `${error}`
57
+ }
58
+
59
+ export const handleUncaughtExceptionMonitor = (error, origin) => {
60
+ console.info(`[shared process] uncaught exception: ${firstErrorLine(error)}`)
61
+ if (error && error.code === ErrorCodes.EPIPE && !process.connected) {
62
+ // parent process is disposed, ignore
63
+ return
64
+ }
65
+ if (
66
+ error &&
67
+ error.code === ErrorCodes.ERR_IPC_CHANNEL_CLOSED &&
68
+ !Process.isConnected()
69
+ ) {
70
+ // parent process is disposed, ignore
71
+ return
72
+ }
73
+ // console.log(error)
74
+ const prettyError = PrettyError.prepare(error)
75
+ // console.error(prettyError.message)
76
+ console.error(prettyError.codeFrame)
77
+ console.error(prettyError.stack)
78
+ Process.exit(1)
79
+ }
@@ -1,7 +1,7 @@
1
1
  import VError from 'verror'
2
- import * as Assert from '../Assert/Assert.js'
3
2
  import * as Extract from '../Extract/Extract.js'
4
3
  import * as FileSystem from '../FileSystem/FileSystem.js'
4
+ import * as JsonFile from '../JsonFile/JsonFile.js'
5
5
  import * as Path from '../Path/Path.js'
6
6
  import * as Platform from '../Platform/Platform.js'
7
7
 
@@ -24,8 +24,7 @@ export const install = async ({ path }) => {
24
24
  await Extract.extractTarBr(path, cachedExtensionPath)
25
25
  const extensionsPath = Platform.getExtensionsPath()
26
26
  const manifestPath = Path.join(cachedExtensionPath, 'extension.json')
27
- const manifestContent = await FileSystem.readFile(manifestPath)
28
- const manifestJson = JSON.parse(manifestContent)
27
+ const manifestJson = await JsonFile.readJson(manifestPath)
29
28
  const id = manifestJson.id
30
29
  if (!id) {
31
30
  throw new Error('missing id in extension manifest')
@@ -1,6 +1,7 @@
1
1
  import VError from 'verror'
2
2
  import * as DownloadAndExtract from '../DownloadAndExtract/DownloadAndExtract.js'
3
3
  import * as FileSystem from '../FileSystem/FileSystem.js'
4
+ import * as JsonFile from '../JsonFile/JsonFile.js'
4
5
  import * as Path from '../Path/Path.js'
5
6
  import * as Platform from '../Platform/Platform.js'
6
7
 
@@ -19,8 +20,7 @@ export const install = async ({ user, repo, branch }) => {
19
20
  })
20
21
  const extensionsPath = Platform.getExtensionsPath()
21
22
  const manifestPath = Path.join(cachedExtensionPath, 'extension.json')
22
- const manifestContent = await FileSystem.readFile(manifestPath)
23
- const manifestJson = JSON.parse(manifestContent)
23
+ const manifestJson = await JsonFile.readJson(manifestPath)
24
24
  const id = manifestJson.id
25
25
  if (!id) {
26
26
  throw new Error('missing id in extension manifest')
@@ -1,11 +1,11 @@
1
- import { readFile, rename, rm } from 'fs/promises'
1
+ import { rename, rm } from 'fs/promises'
2
2
  import { join } from 'path'
3
3
  import VError from 'verror'
4
4
  import * as Download from '../Download/Download.js'
5
5
  import * as Extract from '../Extract/Extract.js'
6
+ import * as JsonFile from '../JsonFile/JsonFile.js'
6
7
  import * as Platform from '../Platform/Platform.js'
7
8
  import * as TmpFile from '../TmpFile/TmpFile.js'
8
- import * as EncodingType from '../EncodingType/EncodingType.js'
9
9
 
10
10
  export const install = async ({ url }) => {
11
11
  try {
@@ -18,8 +18,7 @@ export const install = async ({ url }) => {
18
18
  const tmpDir = await TmpFile.getTmpDir()
19
19
  await Extract.extractTarBr(tmpFile, tmpDir)
20
20
  const manifestPath = join(tmpDir, 'extension.json')
21
- const manifestContent = await readFile(manifestPath, EncodingType.Utf8)
22
- const manifestJson = JSON.parse(manifestContent)
21
+ const manifestJson = await JsonFile.readJson(manifestPath)
23
22
  const id = manifestJson.id
24
23
  if (!id) {
25
24
  throw new Error('missing id in extension manifest')
@@ -1,9 +1,10 @@
1
1
  import VError from 'verror'
2
2
  import * as Error from '../Error/Error.js'
3
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
4
+ import * as FileSystemWatch from '../FileSystemWatch/FileSystemWatch.js'
3
5
  import * as ReadJson from '../JsonFile/JsonFile.js'
4
6
  import * as Path from '../Path/Path.js'
5
7
  import * as ExtensionManagement from './ExtensionManagement.js'
6
- import * as FileSystemWatch from '../FileSystemWatch/FileSystemWatch.js'
7
8
 
8
9
  // TODO test this function
9
10
  // TODO very similar with getIconTheme
@@ -29,7 +30,7 @@ export const getColorThemeJson = async (colorThemeId) => {
29
30
  const colorThemePath = await getColorThemePath(extensions, colorThemeId)
30
31
  if (!colorThemePath) {
31
32
  throw new Error.OperationalError({
32
- code: 'E_COLOR_THEME_NOT_FOUND',
33
+ code: ErrorCodes.E_COLOR_THEME_NOT_FOUND,
33
34
  message: `Color theme "${colorThemeId}" not found in extensions folder`,
34
35
  })
35
36
  }
@@ -1,5 +1,6 @@
1
1
  import VError from 'verror'
2
2
  import * as Error from '../Error/Error.js'
3
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
4
  import * as ReadJson from '../JsonFile/JsonFile.js'
4
5
  import * as Path from '../Path/Path.js'
5
6
  import * as ExtensionManagement from './ExtensionManagement.js'
@@ -27,7 +28,7 @@ export const getIconTheme = async (iconThemeId) => {
27
28
  }
28
29
  }
29
30
  throw new Error.OperationalError({
30
- code: 'E_ICON_THEME_NOT_FOUND',
31
+ code: ErrorCodes.E_ICON_THEME_NOT_FOUND,
31
32
  message: `Icon theme "${iconThemeId}" not found in extensions folder`,
32
33
  })
33
34
  }
@@ -32,6 +32,7 @@ export const getResponse = async (message, handle) => {
32
32
  },
33
33
  }
34
34
  }
35
+ // @ts-ignore
35
36
  if (error && error instanceof Error && error.code === ErrorCodes.ENOENT) {
36
37
  return {
37
38
  jsonrpc: JsonRpc.Version,
@@ -43,7 +44,7 @@ export const getResponse = async (message, handle) => {
43
44
  }
44
45
  }
45
46
  const prettyError = PrettyError.prepare(error)
46
- PrettyError.print(prettyError)
47
+ PrettyError.print(prettyError, `[shared-process] `)
47
48
  return {
48
49
  jsonrpc: JsonRpc.Version,
49
50
  id: message.id,
@@ -0,0 +1,50 @@
1
+ import { Console } from 'node:console'
2
+ import { createWriteStream } from 'node:fs'
3
+ import { tmpdir } from 'node:os'
4
+
5
+ // TODO mock this module when used in unit tests
6
+
7
+ const state = {
8
+ /**
9
+ * @type {Console|undefined}
10
+ */
11
+ console: undefined,
12
+ }
13
+
14
+ const createConsole = () => {
15
+ const logFile = `${tmpdir()}/log-shared-process.txt`
16
+ const writeStream = createWriteStream(logFile)
17
+ const logger = new Console(writeStream)
18
+ return logger
19
+ }
20
+
21
+ const getOrCreateLogger = () => {
22
+ if (!state.console) {
23
+ state.console = createConsole()
24
+ }
25
+ return state.console
26
+ }
27
+
28
+ export const log = (...args) => {
29
+ const logger = getOrCreateLogger()
30
+ logger.log(...args)
31
+ console.log(...args)
32
+ }
33
+
34
+ export const info = (...args) => {
35
+ const logger = getOrCreateLogger()
36
+ logger.info(...args)
37
+ console.info(...args)
38
+ }
39
+
40
+ export const warn = (...args) => {
41
+ const logger = getOrCreateLogger()
42
+ logger.warn(...args)
43
+ console.warn(...args)
44
+ }
45
+
46
+ export const error = (...args) => {
47
+ const logger = getOrCreateLogger()
48
+ logger.error(...args)
49
+ console.error(...args)
50
+ }
@@ -3,6 +3,7 @@ import VError from 'verror'
3
3
  import * as Callback from '../Callback/Callback.js'
4
4
  import * as Command from '../Command/Command.js'
5
5
  import * as Debug from '../Debug/Debug.js'
6
+ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
6
7
  import * as ExtensionHostHelperProcessIpc from '../ExtensionHostHelperProcessIpc/ExtensionHostHelperProcessIpc.js'
7
8
  import * as ExtensionHostIpc from '../ExtensionHostIpc/ExtensionHostIpc.js'
8
9
  import * as ExtensionHostRpc from '../ExtensionHostRpc/ExtensionHostRpc.js'
@@ -36,7 +37,7 @@ export const electronSend = (message) => {
36
37
  const handleWebSocketSharedProcess = (message, handle) => {
37
38
  // TODO when it is an extension host websocket, spawn extension host
38
39
  handle.on('error', (error) => {
39
- if (error && error.code === 'ECONNRESET') {
40
+ if (error && error.code === ErrorCodes.ECONNRESET) {
40
41
  return
41
42
  }
42
43
  console.info('[info shared process: handle error]', error)
@@ -1,8 +1,9 @@
1
- import { readFileSync } from 'node:fs'
2
- import { fileURLToPath } from 'node:url'
3
1
  import { codeFrameColumns } from '@babel/code-frame'
4
2
  import cleanStack from 'clean-stack'
5
3
  import { LinesAndColumns } from 'lines-and-columns'
4
+ import { readFileSync } from 'node:fs'
5
+ import { fileURLToPath } from 'node:url'
6
+ import * as SplitLines from '../SplitLines/SplitLines.js'
6
7
 
7
8
  const getActualPath = (fileUri) => {
8
9
  if (fileUri.startsWith('file://')) {
@@ -20,7 +21,7 @@ export const prepare = (error) => {
20
21
  }
21
22
  }
22
23
  const cleanedStack = cleanStack(error.stack)
23
- const lines = cleanedStack.split('\n')
24
+ const lines = SplitLines.splitLines(cleanedStack)
24
25
  const file = lines[1]
25
26
  let codeFrame = ''
26
27
  if (error.codeFrame) {
@@ -82,8 +83,8 @@ export const prepareJsonError = (json, property, message) => {
82
83
  return jsonError
83
84
  }
84
85
 
85
- export const print = (prettyError) => {
86
+ export const print = (prettyError, prefix = '') => {
86
87
  console.error(
87
- `Error: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}`
88
+ `${prefix}Error: ${prettyError.message}\n\n${prettyError.codeFrame}\n\n${prettyError.stack}`
88
89
  )
89
90
  }
@@ -5,3 +5,27 @@ export const crash = (message) => {
5
5
  export const crashAsync = async (message) => {
6
6
  throw new Error(message)
7
7
  }
8
+
9
+ export const exit = (code) => {
10
+ process.exit(code)
11
+ }
12
+
13
+ export const setExitCode = (exitCode) => {
14
+ process.exitCode = exitCode
15
+ }
16
+
17
+ export const argv = process.argv
18
+
19
+ export const cwd = () => {
20
+ return process.cwd()
21
+ }
22
+
23
+ export const memoryUsage = () => {
24
+ return process.memoryUsage()
25
+ }
26
+
27
+ export const isConnected = () => {
28
+ return process.connected
29
+ }
30
+
31
+ export const platform = process.platform
@@ -4,6 +4,7 @@ import * as Assert from '../Assert/Assert.js'
4
4
  import { FileNotFoundError } from '../Error/FileNotFoundError.js'
5
5
  import * as FileSystem from '../FileSystem/FileSystem.js'
6
6
  import * as Json from '../Json/Json.js'
7
+ import * as JsonFile from '../JsonFile/JsonFile.js'
7
8
  import * as Platform from '../Platform/Platform.js'
8
9
 
9
10
  const isValid = (recentlyOpened) => {
@@ -24,8 +25,7 @@ const addToArrayUnique = (recentlyOpened, path) => {
24
25
 
25
26
  const getRecentlyOpened = async (recentlyOpenedPath) => {
26
27
  try {
27
- const content = await FileSystem.readFile(recentlyOpenedPath)
28
- const parsed = await Json.parse(content, recentlyOpenedPath)
28
+ const parsed = await JsonFile.readJson(recentlyOpenedPath)
29
29
  return parsed
30
30
  } catch (error) {
31
31
  // TODO should check for error.code
@@ -0,0 +1,4 @@
1
+ export const Begin = 'begin'
2
+ export const Match = 'match'
3
+ export const Summary = 'summary'
4
+ export const Context = 'context'
@@ -1,6 +1,8 @@
1
1
  import { spawn } from 'node:child_process'
2
- import * as RgPath from '../RgPath/RgPath.js'
3
2
  import * as Platform from '../Platform/Platform.js'
3
+ import * as RgPath from '../RgPath/RgPath.js'
4
+ import * as RipGrepParsedLineType from '../RipGrepParsedLineType/RipGrepParsedLineType.js'
5
+ import * as SplitLines from '../SplitLines/SplitLines.js'
4
6
 
5
7
  const MAX_SEARCH_RESULTS = 300
6
8
 
@@ -25,64 +27,51 @@ const useNice = !Platform.isWindows
25
27
  // TODO update client
26
28
  // TODO not always run nice, maybe configure nice via flag/options
27
29
 
28
- const ParsedLineType = {
29
- Begin: 'begin',
30
- Match: 'match',
31
- Summary: 'summary',
32
- }
33
-
34
30
  export const search = async (searchDir, searchString) => {
35
31
  // TODO reject promise when ripgrep search fails
36
32
  return new Promise((resolve, reject) => {
33
+ const ripGrepArgs = [
34
+ '--smart-case',
35
+ '--stats',
36
+ '--json',
37
+ '--fixed-strings',
38
+ searchString,
39
+ '.',
40
+ ]
37
41
  const childProcess = useNice
38
- ? spawn(
39
- 'nice',
40
- [
41
- '-20',
42
- RgPath.rgPath,
43
- '--smart-case',
44
- '--stats',
45
- '--json',
46
- searchString,
47
- '.',
48
- ],
49
- {
50
- cwd: searchDir,
51
- }
52
- )
53
- : spawn(
54
- RgPath.rgPath,
55
- ['--smart-case', '--stats', '--json', searchString, '.'],
56
- {
57
- cwd: searchDir,
58
- }
59
- )
42
+ ? spawn('nice', ['-20', RgPath.rgPath, ...ripGrepArgs], {
43
+ cwd: searchDir,
44
+ })
45
+ : spawn(RgPath.rgPath, ripGrepArgs, {
46
+ cwd: searchDir,
47
+ })
60
48
  const allSearchResults = Object.create(null)
61
49
  let buffer = ''
62
50
  let stats = {}
51
+ let limitHit = false
63
52
  let numberOfResults = 0
64
53
  // TODO use pipeline / transform stream maybe
65
54
 
66
55
  const handleData = (chunk) => {
67
56
  buffer += chunk
68
- const lines = buffer.split('\n')
57
+ const lines = SplitLines.splitLines(buffer)
69
58
  // @ts-ignore
70
59
  buffer = lines.pop()
71
60
  for (const line of lines) {
72
61
  const parsedLine = JSON.parse(line)
62
+ console.log(parsedLine)
73
63
  switch (parsedLine.type) {
74
- case ParsedLineType.Begin: {
64
+ case RipGrepParsedLineType.Begin: {
75
65
  allSearchResults[parsedLine.data.path.text] = []
76
66
  break
77
67
  }
78
- case ParsedLineType.Match: {
68
+ case RipGrepParsedLineType.Match:
79
69
  numberOfResults++
80
70
  allSearchResults[parsedLine.data.path.text].push(
81
71
  toSearchResult(parsedLine)
82
72
  )
83
73
  break
84
- }
85
- case ParsedLineType.Summary:
74
+ case RipGrepParsedLineType.Summary:
86
75
  stats = parsedLine.data
87
76
  break
88
77
  default:
@@ -90,6 +79,7 @@ export const search = async (searchDir, searchString) => {
90
79
  }
91
80
  }
92
81
  if (numberOfResults > MAX_SEARCH_RESULTS) {
82
+ limitHit = true
93
83
  childProcess.kill()
94
84
  }
95
85
  }
@@ -98,6 +88,7 @@ export const search = async (searchDir, searchString) => {
98
88
  resolve({
99
89
  results: Object.entries(allSearchResults),
100
90
  stats,
91
+ limitHit,
101
92
  })
102
93
  }
103
94
  const handleError = (error) => {
@@ -106,6 +97,7 @@ export const search = async (searchDir, searchString) => {
106
97
  resolve({
107
98
  results: [],
108
99
  stats,
100
+ limitHit,
109
101
  })
110
102
  }
111
103
  childProcess.stdout.on('data', handleData)
@@ -41,7 +41,6 @@ const handleMessage = async (event) => {
41
41
  }
42
42
 
43
43
  const handleError = (error) => {
44
- console.log('EEERRR')
45
44
  // console.error(error)
46
45
  throw new VError(error, 'Shared Process Socket Error')
47
46
 
@@ -0,0 +1,3 @@
1
+ export const splitLines = (lines) => {
2
+ return lines.split('\n')
3
+ }
@@ -1,9 +1,9 @@
1
1
  // parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
2
2
 
3
3
  import * as Exec from '../Exec/Exec.js'
4
+ import * as SplitLines from '../SplitLines/SplitLines.js'
4
5
 
5
- const PID_CMD =
6
- /^\s*(\d+)\s+(\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(.+)$/
6
+ const PID_CMD = /^\s*(\d+)\s+(\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(.+)$/
7
7
 
8
8
  const parsePsOutputLine = (line) => {
9
9
  const matches = PID_CMD.exec(line.trim())
@@ -18,7 +18,7 @@ const parsePsOutputLine = (line) => {
18
18
  }
19
19
  }
20
20
  const parsePsOutput = (stdout, rootPid) => {
21
- const lines = stdout.split('\n')
21
+ const lines = SplitLines.splitLines(stdout)
22
22
  return lines.map(parsePsOutputLine)
23
23
  }
24
24
 
@@ -1,40 +1,12 @@
1
1
  import * as Command from './parts/Command/Command.js'
2
+ import * as ErrorHandling from './parts/ErrorHandling/ErrorHandling.js'
2
3
  import * as Module from './parts/Module/Module.js'
3
4
  import * as ParentIpc from './parts/ParentIpc/ParentIpc.js'
4
- import * as PrettyError from './parts/PrettyError/PrettyError.js'
5
-
5
+ import * as Process from './parts/Process/Process.js'
6
6
  // TODO handle structure: one shared process multiple extension hosts
7
7
 
8
8
  // TODO use named functions here
9
9
 
10
- const firstErrorLine = (error) => {
11
- if (error.stack) {
12
- return error.stack.slice(0, error.stack.indexOf('\n'))
13
- }
14
- if (error.message) {
15
- return error.message
16
- }
17
- return `${error}`
18
- }
19
-
20
- const handleUncaughtExceptionMonitor = (error, origin) => {
21
- console.info(`[shared process] uncaught exception: ${firstErrorLine(error)}`)
22
- if (error && error.code === 'EPIPE' && !process.connected) {
23
- // parent process is disposed, ignore
24
- return
25
- }
26
- if (error && error.code === 'ERR_IPC_CHANNEL_CLOSED' && !process.connected) {
27
- // parent process is disposed, ignore
28
- return
29
- }
30
- // console.log(error)
31
- const prettyError = PrettyError.prepare(error)
32
- // console.error(prettyError.message)
33
- console.error(prettyError.codeFrame)
34
- console.error(prettyError.stack)
35
- process.exit(1)
36
- }
37
-
38
10
  const handleDisconnect = () => {
39
11
  console.info('[shared process] disconnected')
40
12
  }
@@ -51,7 +23,7 @@ const knownCliArgs = ['install', 'list', 'link', 'unlink']
51
23
 
52
24
  const main = async () => {
53
25
  Command.setLoad(Module.load)
54
- const argv = process.argv.slice(2)
26
+ const argv = Process.argv.slice(2)
55
27
  const argv0 = argv[0]
56
28
  if (knownCliArgs.includes(argv0)) {
57
29
  const module = await import('./parts/Cli/Cli.js')
@@ -64,7 +36,10 @@ const main = async () => {
64
36
  process.on('disconnect', handleDisconnect)
65
37
  process.on('SIGTERM', handleSigTerm)
66
38
 
67
- process.on('uncaughtExceptionMonitor', handleUncaughtExceptionMonitor)
39
+ process.on(
40
+ 'uncaughtExceptionMonitor',
41
+ ErrorHandling.handleUncaughtExceptionMonitor
42
+ )
68
43
  ParentIpc.listen()
69
44
 
70
45
  // ExtensionHost.start() // TODO start on demand, e.g. not when extensions should be disabled