@lvce-editor/shared-process 0.11.4 → 0.11.5

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.5",
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.5",
21
+ "@lvce-editor/extension-host-helper-process": "0.11.5",
22
+ "@lvce-editor/pty-host": "0.11.5",
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
  }
@@ -1,6 +1,7 @@
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'
4
5
 
5
6
  export const measureLatencyBetweenExtensionHostAndSharedProcess = async (
6
7
  socket,
@@ -63,7 +64,7 @@ export const getNodeStartupTiming = () => {
63
64
 
64
65
  export const sharedProcessMemoryUsage = () => {
65
66
  // TODO also print out number of watched files
66
- return process.memoryUsage()
67
+ return Process.memoryUsage()
67
68
  }
68
69
 
69
70
  // TODO not sure if this is actually useful
@@ -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,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
  }
@@ -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)
@@ -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
@@ -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
 
@@ -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