@lvce-editor/shared-process 0.0.25 → 0.0.28

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 (56) hide show
  1. package/config/builtinCommands.json +101 -85
  2. package/config/defaultKeyBindings.json +6 -1
  3. package/index.js +2 -2
  4. package/package.json +12 -8
  5. package/src/parts/Assert/Assert.js +12 -5
  6. package/src/parts/ChildProcess/ChildProcessWithFork.js +19 -0
  7. package/src/parts/Command/Command.js +14 -16
  8. package/src/parts/Developer/Developer.ipc.js +2 -8
  9. package/src/parts/ExtensionHost/ExtensionHost.ipc.js +10 -68
  10. package/src/parts/ExtensionHost/ExtensionHost.js +59 -138
  11. package/src/parts/ExtensionHostIpc/ExtensionHostIpc.js +5 -0
  12. package/src/parts/ExtensionHostIpc/ExtensionHostIpcWithChildProcess.js +57 -0
  13. package/src/parts/ExtensionHostIpc/ExtensionHostIpcWithWorker.js +38 -0
  14. package/src/parts/ExtensionHostRpc/ExtensionHostRpc.js +82 -0
  15. package/src/parts/ExtensionManagement/ExtensionManagement.ipc.js +11 -0
  16. package/src/parts/ExtensionManagement/ExtensionManagement.js +5 -2
  17. package/src/parts/{ExtensionHost/ExtensionHostColorTheme.js → ExtensionManagement/ExtensionManagementColorTheme.js} +1 -1
  18. package/src/parts/{ExtensionHost/ExtensionHostIconTheme.js → ExtensionManagement/ExtensionManagementIconTheme.js} +1 -1
  19. package/src/parts/{ExtensionHost/ExtensionHostLanguages.js → ExtensionManagement/ExtensionManagementLanguages.js} +1 -1
  20. package/src/parts/FileSystem/FileSystem.js +13 -1
  21. package/src/parts/JsonRpc/JsonRpc.js +2 -2
  22. package/src/parts/OutputChannel/OutputChannel.ipc.js +1 -1
  23. package/src/parts/ParentIpc/ParentIpc.js +93 -47
  24. package/src/parts/Platform/Platform.js +1 -1
  25. package/src/parts/Preferences/Preferences.js +0 -2
  26. package/src/parts/PrettyError/PrettyError.js +5 -2
  27. package/src/parts/RequiresSocket/RequiresSocket.js +6 -5
  28. package/src/parts/Stats/Stats.js +8 -7
  29. package/src/parts/Terminal/Terminal.ipc.js +2 -2
  30. package/src/parts/Terminal/Terminal.js +1 -1
  31. package/src/parts/Timeout/Timeout.js +7 -0
  32. package/src/sharedProcessMain.js +13 -4
  33. package/src/parts/Extension/Extension.js +0 -7
  34. package/src/parts/ExtensionHost/ExtensionHostBraceCompletion.js +0 -14
  35. package/src/parts/ExtensionHost/ExtensionHostClosingTag.js +0 -14
  36. package/src/parts/ExtensionHost/ExtensionHostCommand.js +0 -19
  37. package/src/parts/ExtensionHost/ExtensionHostCompletion.js +0 -12
  38. package/src/parts/ExtensionHost/ExtensionHostDefinition.js +0 -12
  39. package/src/parts/ExtensionHost/ExtensionHostDiagnostic.js +0 -7
  40. package/src/parts/ExtensionHost/ExtensionHostFileSystem.js +0 -23
  41. package/src/parts/ExtensionHost/ExtensionHostFormatting.js +0 -4
  42. package/src/parts/ExtensionHost/ExtensionHostHover.js +0 -12
  43. package/src/parts/ExtensionHost/ExtensionHostImplementation.js +0 -12
  44. package/src/parts/ExtensionHost/ExtensionHostManagement.js +0 -26
  45. package/src/parts/ExtensionHost/ExtensionHostOutput.js +0 -3
  46. package/src/parts/ExtensionHost/ExtensionHostQuickPick.js +0 -6
  47. package/src/parts/ExtensionHost/ExtensionHostReference.js +0 -12
  48. package/src/parts/ExtensionHost/ExtensionHostRename.js +0 -27
  49. package/src/parts/ExtensionHost/ExtensionHostSemanticTokens.js +0 -10
  50. package/src/parts/ExtensionHost/ExtensionHostSourceControl.js +0 -15
  51. package/src/parts/ExtensionHost/ExtensionHostStats.js +0 -3
  52. package/src/parts/ExtensionHost/ExtensionHostStatusBar.js +0 -7
  53. package/src/parts/ExtensionHost/ExtensionHostTabCompletion.js +0 -12
  54. package/src/parts/ExtensionHost/ExtensionHostTextDocument.js +0 -35
  55. package/src/parts/ExtensionHost/ExtensionHostTypeDefinition.js +0 -12
  56. package/src/parts/ExtensionHost/ExtensionHostWorkspace.js +0 -3
@@ -100,23 +100,15 @@ const getModuleId = (commandId) => {
100
100
  case 'Developer.createHeapSnapshot':
101
101
  case 'Developer.createProfile':
102
102
  case 'Developer.getNodeStartupTiming':
103
+ case 'Developer.getNodeStartupTime':
103
104
  return MODULE_DEVELOPER
104
- case 'ExtensionHost.getColorThemeJson':
105
- case 'ExtensionHost.getIconThemeJson':
106
105
  case 'ExtensionHost.executeTabCompletionProvider':
107
106
  case 'ExtensionHostLanguages.getLanguages':
108
- case 'ExtensionHost.getIconTheme':
109
107
  case 'ExtensionHostKeyBindings.getKeyBindings':
110
108
  case 'ExtensionHost.executeCommand':
111
- case 'ExtensionHost.getColorThemeJson':
112
- case 'ExtensionHost.getColorThemeNames':
113
109
  case 'ExtensionHost.getMemoryUsage':
114
110
  case 'ExtensionHost.getSourceControlBadgeCount':
115
111
  case 'ExtensionHost.format':
116
- case 'ExtensionHost.executeCommand':
117
- case 'ExtensionHost.getSourceControlBadgeCount':
118
- case 'ExtensionHost.getLanguageConfiguration':
119
- case 'ExtensionHost.getColorThemes':
120
112
  case 'ExtensionHostTextDocument.syncInitial':
121
113
  case 'ExtensionHostHover.execute':
122
114
  case 'ExtensionHostDiagnostic.execute':
@@ -131,6 +123,7 @@ const getModuleId = (commandId) => {
131
123
  case 'ExtensionHostFileSystem.rename':
132
124
  case 'ExtensionHostSourceControl.acceptInput':
133
125
  case 'ExtensionHost.start':
126
+ case 'ExtensionHost.dispose':
134
127
  case 'ExtensionHostManagement.activateAll':
135
128
  case 'ExtensionHostManagement.enableExtensions':
136
129
  case 'ExtensionHostFileSystem.getPathSeparator':
@@ -148,20 +141,25 @@ const getModuleId = (commandId) => {
148
141
  case 'ExtensionHostTextDocument.syncFull':
149
142
  case 'ExtensionHost.setWorkspacePath':
150
143
  case 'ExtensionHost.enableExtension':
151
- case 'ExtensionHost.getIconThemeJson':
152
- case 'ExtensionHost.getLanguages':
153
144
  case 'ExtensionHostCompletion.execute':
154
145
  case 'ExtensionHostTextDocument.syncIncremental':
155
146
  case 'ExtensionHostClosingTag.executeClosingTagProvider':
156
147
  case 'ExtensionHost.sourceControlGetChangedFiles':
157
148
  case 'ExtensionHostSemanticTokens.executeSemanticTokenProvider':
158
149
  return MODULE_EXTENSION_HOST
159
- case 'ExtensionManagement.install':
160
- case 'ExtensionManagement.uninstall':
161
- case 'ExtensionManagement.enable':
150
+ case 'ExtensionHost.getColorThemeJson':
151
+ case 'ExtensionHost.getColorThemeNames':
152
+ case 'ExtensionHost.getColorThemes':
153
+ case 'ExtensionHost.getIconTheme':
154
+ case 'ExtensionHost.getIconThemeJson':
155
+ case 'ExtensionHost.getLanguageConfiguration':
156
+ case 'ExtensionHost.getLanguages':
162
157
  case 'ExtensionManagement.disable':
158
+ case 'ExtensionManagement.enable':
163
159
  case 'ExtensionManagement.getAllExtensions':
164
160
  case 'ExtensionManagement.getExtensions':
161
+ case 'ExtensionManagement.install':
162
+ case 'ExtensionManagement.uninstall':
165
163
  return MODULE_EXTENSION_MANAGEMENT
166
164
  case 'Search.search':
167
165
  return MODULE_SEARCH
@@ -212,7 +210,7 @@ const getModuleId = (commandId) => {
212
210
  case 'Electron.openProcessExplorer':
213
211
  return MODULE_ELECTRON
214
212
  default:
215
- throw new Error(`command ${commandId} not found`)
213
+ throw new Error(`[shared-process] command ${commandId} not found`)
216
214
  }
217
215
  }
218
216
 
@@ -235,7 +233,7 @@ export const invoke = async (command, ...args) => {
235
233
  }
236
234
  }
237
235
  if (typeof commands[command] !== 'function') {
238
- throw new Error(`Command ${command} is not a function`)
236
+ throw new TypeError(`Command ${command} is not a function`)
239
237
  }
240
238
  return commands[command](...args)
241
239
  }
@@ -1,15 +1,8 @@
1
1
  import * as Command from '../Command/Command.js'
2
2
  import * as Developer from './Developer.js'
3
3
 
4
+ // prettier-ignore
4
5
  export const __initialize__ = () => {
5
- // Command.register(
6
- // 281,
7
- // Developer.measureLatencyBetweenExtensionHostAndSharedProcess
8
- // )
9
- // Command.register(
10
- // 282,
11
- // Developer.measureLatencyBetweenSharedProcessAndRendererProcess
12
- // )
13
6
  Command.register('Developer.sharedProcessStartupPerformance', Developer.sharedProcessStartupPerformance)
14
7
  Command.register('Developer.sharedProcessMemoryUsage', Developer.sharedProcessMemoryUsage)
15
8
  Command.register('Developer.allocateMemory', Developer.allocateMemory)
@@ -17,4 +10,5 @@ export const __initialize__ = () => {
17
10
  Command.register('Developer.createHeapSnapshot', Developer.createHeapSnapshot)
18
11
  Command.register('Developer.createProfile', Developer.createProfile)
19
12
  Command.register('Developer.getNodeStartupTiming', Developer.getNodeStartupTiming)
13
+ Command.register('Developer.getNodeStartupTime', Developer.getNodeStartupTiming)
20
14
  }
@@ -1,79 +1,21 @@
1
1
  import * as Command from '../Command/Command.js'
2
2
  import * as ExtensionHost from './ExtensionHost.js'
3
3
  import * as ExtensionHostCommand from './ExtensionHostCommand.js'
4
- import * as ExtensionHostCompletion from './ExtensionHostCompletion.js'
5
- import * as ExtensionHostSourceControl from './ExtensionHostSourceControl.js'
6
- import * as ExtensionHostTabCompletion from './ExtensionHostTabCompletion.js'
7
- import * as ExtensionHostStats from './ExtensionHostStats.js'
8
- import * as ExtensionHostFormatting from './ExtensionHostFormatting.js'
9
- import * as ExtensionHostTextDocument from './ExtensionHostTextDocument.js'
10
- import * as ExtensionHostHover from './ExtensionHostHover.js'
11
- import * as ExtensionHostDiagnostic from './ExtensionHostDiagnostic.js'
12
- import * as ExtensionHostRename from './ExtensionHostRename.js'
13
- import * as ExtensionHostDefinition from './ExtensionHostDefinition.js'
14
- import * as ExtensionHostFileSystem from './ExtensionHostFileSystem.js'
15
- import * as ExtensionHostManagement from './ExtensionHostManagement.js'
16
- import * as ExtensionHostWorkspace from './ExtensionHostWorkspace.js'
17
- import * as ExtensionHostOutput from './ExtensionHostOutput.js'
18
- import * as ExtensionHostLanguages from './ExtensionHostLanguages.js'
19
- import * as ExtensionHostColorTheme from './ExtensionHostColorTheme.js'
20
4
  import * as ExtensionHostKeyBindings from './ExtensionHostKeyBindings.js'
21
- import * as ExtensionHostIconTheme from './ExtensionHostIconTheme.js'
22
- import * as ExtensionHostStatusBar from './ExtensionHostStatusBar.js'
23
- import * as ExtensionHostQuickPick from './ExtensionHostQuickPick.js'
24
- import * as ExtensionHostBraceCompletion from './ExtensionHostBraceCompletion.js'
25
- import * as ExtensionHostReferences from './ExtensionHostReference.js'
26
- import * as ExtensionHostImplementation from './ExtensionHostImplementation.js'
27
- import * as ExtensionHostTypeDefinition from './ExtensionHostTypeDefinition.js'
28
- import * as ExtensionHostClosingTag from './ExtensionHostClosingTag.js'
29
- import * as ExtensionHostSemanticTokens from './ExtensionHostSemanticTokens.js'
30
5
 
31
6
  // prettier-ignore
32
7
  export const __initialize__ = () => {
33
8
  Command.register('ExtensionHost.getCommands', ExtensionHostCommand.getCommandsIpc)
34
- Command.register('ExtensionHostCompletion.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCompletion.executeCompletionProvider))
35
- Command.register('ExtensionHost.executeTabCompletionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTabCompletion.executeTabCompletionProvider))
36
- Command.register('ExtensionHost.getLanguages', ExtensionHostLanguages.getLanguages)
37
- Command.register('ExtensionHost.getIconThemeJson', ExtensionHostIconTheme.getIconTheme)
38
9
  Command.register('ExtensionHostKeyBindings.getKeyBindings', ExtensionHostKeyBindings.getKeyBindings)
39
- Command.register('ExtensionHost.executeCommand', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCommand.executeCommand))
40
- Command.register('ExtensionHost.getColorThemeJson', ExtensionHostColorTheme.getColorThemeJson)
41
- Command.register('ExtensionHost.getColorThemeNames', ExtensionHostColorTheme.getColorThemeNames)
42
- Command.register('ExtensionHost.getMemoryUsage', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStats.getMemoryUsage))
43
- Command.register('ExtensionHost.getSourceControlBadgeCount', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.getSourceControlBadgeCount))
44
- Command.register('ExtensionHost.format', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFormatting.format))
45
- Command.register('ExtensionHost.executeCommand', ExtensionHost.wrapExtensionHostCommand(ExtensionHostCommand.executeCommand))
46
- Command.register('ExtensionHost.sourceControlGetChangedFiles', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.getSourceControlChangedFiles))
47
- Command.register('ExtensionHost.getLanguageConfiguration', ExtensionHostLanguages.getLanguageConfiguration)
48
- Command.register('ExtensionHost.getColorThemes', ExtensionHostColorTheme.getColorThemes)
49
- Command.register('ExtensionHostTextDocument.syncFull', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.textDocumentSyncInitial))
50
- Command.register('ExtensionHostHover.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostHover.executeHoverProvider))
51
- Command.register('ExtensionHostDiagnostic.execute', ExtensionHost.wrapExtensionHostCommand(ExtensionHostDiagnostic.executeDiagnosticProvider))
52
- Command.register('ExtensionHostTextDocument.syncIncremental', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.textDocumentSyncIncremental))
53
- Command.register('ExtensionHostRename.executePrepareRename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostRename.executePrepareRename))
54
- Command.register('ExtensionHostRename.executeRename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostRename.executeRename))
55
- Command.register('ExtensionHostDefinition.executeDefinitionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostDefinition.executeDefinitionProvider))
56
- Command.register('ExtensionHostFileSystem.readFile', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.readFile))
57
- Command.register('ExtensionHostFileSystem.writeFile', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.writeFile))
58
- Command.register('ExtensionHostFileSystem.readDirWithFileTypes', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.readDirWithFileTypes))
59
- Command.register('ExtensionHostFileSystem.remove', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.remove))
60
- Command.register('ExtensionHostFileSystem.rename', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.rename))
61
- Command.register('ExtensionHostSourceControl.acceptInput', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSourceControl.sourceControlAcceptInput))
62
10
  Command.register('ExtensionHost.start', ExtensionHost.start)
63
- Command.register('ExtensionHost.activateAll', ExtensionHost.wrapExtensionHostCommand(ExtensionHostManagement.activateAll))
64
- Command.register('ExtensionHost.enableExtension', ExtensionHost.wrapExtensionHostCommand(ExtensionHostManagement.enableExtension))
65
- Command.register('ExtensionHostFileSystem.getPathSeparator', ExtensionHost.wrapExtensionHostCommand(ExtensionHostFileSystem.getPathSeparator))
66
- Command.register('ExtensionHost.setWorkspacePath', ExtensionHost.wrapExtensionHostCommand(ExtensionHostWorkspace.setWorkspacePath))
67
- Command.register('ExtensionHost.setWorkspaceRoot', ExtensionHost.wrapExtensionHostCommand(ExtensionHostWorkspace.setWorkspacePath))
68
- Command.register('ExtensionHostOutput.getOutputChannels', ExtensionHost.wrapExtensionHostCommand(ExtensionHostOutput.getOutputChannels))
69
- Command.register('ExtensionHost.getStatusBarItems', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStatusBar.getStatusBarItems))
70
- Command.register('ExtensionHostStatusBar.registerChangeListener', ExtensionHost.wrapExtensionHostCommand(ExtensionHostStatusBar.registerChangeListener))
71
- Command.register('ExtensionHostTextDocument.setLanguageId', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTextDocument.setLanguageId))
72
- Command.register('ExtensionHostQuickPick.handleQuickPickResult', ExtensionHost.wrapExtensionHostCommand(ExtensionHostQuickPick.handleQuickPickResult))
73
- Command.register('ExtensionHostBraceCompletion.executeBraceCompletionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostBraceCompletion.executeBraceCompletionProvider))
74
- Command.register('ExtensionHostReferences.executeReferenceProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostReferences.executeReferenceProvider))
75
- Command.register('ExtensionHostImplementation.executeImplementationProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostImplementation.executeImplementationProvider))
76
- Command.register('ExtensionHostClosingTag.executeTypeDefinitionProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostTypeDefinition.executeTypeDefinitionProvider))
77
- Command.register('ExtensionHostClosingTag.executeClosingTagProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostClosingTag.executeClosingTagProvider))
78
- Command.register('ExtensionHostSemanticTokens.executeSemanticTokenProvider', ExtensionHost.wrapExtensionHostCommand(ExtensionHostSemanticTokens.executeSemanticTokenProvider))
11
+ Command.register('ExtensionHost.dispose', ExtensionHost.dispose)
12
+ Command.register('ExtensionHost.send', ExtensionHost.send)
13
+
14
+ Command.register('ExtensionHostExtension.activate', ExtensionHost.forward)
15
+ Command.register('ExtensionHostExtension.disable', ExtensionHost.forward)
16
+ Command.register('ExtensionHostSemanticTokens.executeSemanticTokenProvider', ExtensionHost.forward)
17
+ Command.register('ExtensionHostTextDocument.setLanguageId', ExtensionHost.forward)
18
+ Command.register('ExtensionHostTextDocument.syncIncremental', ExtensionHost.forward)
19
+ Command.register('ExtensionHostTextDocument.syncFull', ExtensionHost.forward)
20
+ Command.register('ExtensionHostCompletion.execute', ExtensionHost.forward)
79
21
  }
@@ -1,163 +1,84 @@
1
1
  import VError from 'verror'
2
+ import * as Assert from '../Assert/Assert.js'
2
3
  import * as Callback from '../Callback/Callback.js'
3
- import * as ChildProcess from '../ChildProcess/ChildProcess.js'
4
- import * as Error from '../Error/Error.js'
4
+ import * as ExtensionHostIpc from '../ExtensionHostIpc/ExtensionHostIpc.js'
5
+ import * as ExtensionHostRpc from '../ExtensionHostRpc/ExtensionHostRpc.js'
5
6
  import * as JsonRpc from '../JsonRpc/JsonRpc.js'
6
- import * as Platform from '../Platform/Platform.js'
7
- import * as Socket from '../Socket/Socket.js'
8
- import * as Assert from '../Assert/Assert.js'
9
- // TODO maybe rename to extension host management for clarity
10
7
 
11
- // TODO needed? probably not
12
- const NULL_EXTENSION_HOST = {
13
- dispose() {
14
- throw new VError('not implemented')
15
- },
16
- send(message) {
17
- throw new VError(
18
- 'extension host must be started before commands can be invoked'
19
- )
20
- },
21
- async invoke(commandId, ...args) {
22
- throw new VError(
23
- 'extension host must be started before commands can be invoked'
24
- )
25
- },
26
- }
8
+ // TODO maybe rename to extension host management for clarity
27
9
 
28
10
  /**
29
- * @type{{
30
- * extensionHost: {dispose:()=>void, invoke:(commandId, ...args)=>Promise<any>},
31
- * }}
11
+ * @type{{extensionHosts:any }}
32
12
  */
33
13
  export const state = {
34
- extensionHost: NULL_EXTENSION_HOST,
14
+ extensionHosts: Object.create(null),
35
15
  }
36
16
 
37
- const onMessage = (message) => {
38
- if (message.id) {
39
- if ('result' in message) {
40
- Callback.resolve(message.id, message.result)
41
- } else if ('error' in message) {
42
- Callback.reject(
43
- message.id,
44
- new Error.OperationalError({
45
- code: 'E_CALLBACK_REJECTED',
46
- message: message.error.message,
47
- stack: message.error.data.stack,
48
- codeFrame: message.error.data.codeFrame,
49
- // @ts-ignore
50
- stderr: message.error.data.stderr,
51
- })
52
- )
53
- } else {
54
- Socket.send(message)
55
- }
56
- } else {
57
- Socket.send(message)
58
- }
17
+ // TODO this function is very ugly and has probably memory leaks
18
+ const createExtensionHost = async (socket) => {
19
+ Assert.object(socket)
20
+ const ipc = ExtensionHostIpc.create()
21
+ const rpc = ExtensionHostRpc.create(ipc, socket)
22
+ return rpc
59
23
  }
60
24
 
61
- // TODO this function is very ugly and has probably memory leaks
62
25
  export const start = async (socket) => {
63
26
  try {
64
- Assert.object(socket)
65
- const extensionHostPath = Platform.getExtensionHostPath()
66
- const childProcess = ChildProcess.fork(extensionHostPath, {
67
- execArgv: [
68
- '--experimental-json-modules',
69
- '--max-old-space-size=60',
70
- '--enable-source-maps',
71
- ],
72
- env: {
73
- ...process.env,
74
- LOGS_DIR: Platform.getLogsDir(),
75
- CONFIG_DIR: Platform.getConfigDir(),
76
- },
77
- })
78
-
79
- const handleChildProcessError = (error) => {
80
- console.error(`[Extension Host] ${error}`)
81
- }
82
-
83
- const handleChildProcessExit = (exitCode) => {
84
- console.info(
85
- `[SharedProcess] Extension Host exited with code ${exitCode}`
86
- )
87
- state.extensionHost = NULL_EXTENSION_HOST
88
- }
89
-
90
- const handleSocketClose = () => {
91
- console.info('[shared process] disposing extension host')
92
- childProcess.kill()
93
- }
94
-
95
- socket.on('close', handleSocketClose)
96
-
97
- childProcess.on('error', handleChildProcessError)
98
-
99
- childProcess.on('exit', handleChildProcessExit)
100
-
101
- state.extensionHost = {
102
- invoke(...args) {
103
- return JsonRpc.invoke(childProcess, ...args)
104
- },
105
- dispose() {
106
- childProcess.kill()
107
- },
108
- }
109
-
110
- await new Promise((resolve, reject) => {
111
- const handleFirstError = (error) => {
112
- cleanup()
113
- reject(error)
114
- }
115
- const handleFirstExit = (exitCode) => {
116
- cleanup()
117
- reject(
118
- new globalThis.Error(`Extension Host exited with code ${exitCode}`)
119
- )
27
+ const id = 1
28
+ console.log('start extension host', id)
29
+ const handleMessage = (message) => {
30
+ if ('result' in message) {
31
+ Callback.resolve(message.id, message.result)
32
+ } else if ('error' in message) {
33
+ Callback.reject(message.id, message.error)
34
+ } else {
35
+ console.error('unsupported message type')
120
36
  }
121
- const handleFirstMessage = () => {
122
- cleanup()
123
- childProcess.on('message', onMessage)
124
- resolve(undefined)
125
- }
126
- const handleSocketClose = () => {
127
- cleanup()
128
- childProcess.off('error', handleChildProcessError)
129
- childProcess.off('exit', handleChildProcessExit)
130
- resolve(undefined)
131
- }
132
- const cleanup = () => {
133
- childProcess.off('error', handleFirstError)
134
- childProcess.off('exit', handleFirstExit)
135
- childProcess.off('message', handleFirstMessage)
136
- }
137
- childProcess.on('error', handleFirstError)
138
- childProcess.on('exit', handleFirstExit)
139
- childProcess.on('message', handleFirstMessage)
140
- socket.on('close', handleSocketClose)
141
- })
37
+ }
38
+ const extensionHost = await createExtensionHost(socket)
39
+ extensionHost.on('message', handleMessage)
40
+ state.extensionHosts[id] = extensionHost
41
+ return id
142
42
  } catch (error) {
143
43
  // @ts-ignore
144
44
  throw new VError(error, 'Failed to start extension host')
145
45
  }
146
46
  }
147
47
 
148
- export const stop = () => {
149
- state.extensionHost.dispose()
150
- state.extensionHost = NULL_EXTENSION_HOST
151
- }
152
-
153
- export const restart = () => {
154
- stop()
155
- start()
48
+ export const send = async (socket, id, message) => {
49
+ Assert.number(id)
50
+ Assert.object(message)
51
+ console.log(Object.keys(state))
52
+ const extensionHost = state.extensionHosts[id]
53
+ if (!extensionHost) {
54
+ throw new VError(`no extension host with id ${id} found`)
55
+ }
56
+ try {
57
+ const result = await JsonRpc.invoke(
58
+ extensionHost,
59
+ message.method,
60
+ ...message.params
61
+ )
62
+ socket.send({
63
+ jsonrpc: '2.0',
64
+ id: message.id,
65
+ result,
66
+ })
67
+ } catch (error) {
68
+ // console.log({ error })
69
+ socket.send({
70
+ jsonrpc: '2.0',
71
+ id: message.id,
72
+ error,
73
+ })
74
+ }
156
75
  }
157
76
 
158
- export const wrapExtensionHostCommand = (fn) => {
159
- const wrappedExtensionHostCommand = (...args) => {
160
- return fn(state.extensionHost, ...args)
77
+ export const dispose = (id) => {
78
+ const extensionHost = state.extensionHosts[id]
79
+ if (!extensionHost) {
80
+ throw new VError(`no extension host with id ${id} found`)
161
81
  }
162
- return wrappedExtensionHostCommand
82
+ extensionHost.dispose()
83
+ delete state.extensionHosts[id]
163
84
  }
@@ -0,0 +1,5 @@
1
+ import * as ExtensionHostIpcWithChildProcess from './ExtensionHostIpcWithChildProcess.js'
2
+
3
+ export const create = () => {
4
+ return ExtensionHostIpcWithChildProcess.create()
5
+ }
@@ -0,0 +1,57 @@
1
+ import * as ChildProcess from '../ChildProcess/ChildProcess.js'
2
+ import * as Platform from '../Platform/Platform.js'
3
+
4
+ export const create = () => {
5
+ const extensionHostPath = Platform.getExtensionHostPath()
6
+ const childProcess = ChildProcess.fork(extensionHostPath, {
7
+ execArgv: [
8
+ '--experimental-json-modules',
9
+ '--max-old-space-size=60',
10
+ '--enable-source-maps',
11
+ ],
12
+ env: {
13
+ ...process.env,
14
+ LOGS_DIR: Platform.getLogsDir(),
15
+ CONFIG_DIR: Platform.getConfigDir(),
16
+ },
17
+ })
18
+ return {
19
+ on(event, listener) {
20
+ switch (event) {
21
+ case 'message':
22
+ childProcess.on('message', listener)
23
+ break
24
+ case 'error':
25
+ childProcess.on('error', listener)
26
+ break
27
+ case 'exit':
28
+ childProcess.on('exit', listener)
29
+ break
30
+ default:
31
+ throw new Error(`unsupported event type ${event}`)
32
+ }
33
+ },
34
+ off(event, listener) {
35
+ switch (event) {
36
+ case 'message':
37
+ childProcess.off('message', listener)
38
+ break
39
+ case 'error':
40
+ childProcess.off('error', listener)
41
+ break
42
+ case 'exit':
43
+ childProcess.off('exit', listener)
44
+ break
45
+ default:
46
+ throw new Error(`unsupported event type ${event}`)
47
+ }
48
+ },
49
+ send(message) {
50
+ childProcess.send(message)
51
+ },
52
+ dispose() {
53
+ childProcess.kill()
54
+ },
55
+ _process: childProcess,
56
+ }
57
+ }
@@ -0,0 +1,38 @@
1
+ import { Worker } from 'node:worker_threads'
2
+ import * as Platform from '../Platform/Platform.js'
3
+
4
+ export const create = () => {
5
+ const extensionHostPath = Platform.getExtensionHostPath()
6
+ const child = new Worker(extensionHostPath, {
7
+ execArgv: [
8
+ '--experimental-json-modules',
9
+ '--max-old-space-size=60',
10
+ '--enable-source-maps',
11
+ ],
12
+ env: {
13
+ ...process.env,
14
+ LOGS_DIR: Platform.getLogsDir(),
15
+ CONFIG_DIR: Platform.getConfigDir(),
16
+ },
17
+ })
18
+ return {
19
+ on(event, listener) {
20
+ switch (event) {
21
+ case 'message':
22
+ child.on('message', listener)
23
+ break
24
+ case 'error':
25
+ child.on('error', listener)
26
+ break
27
+ default:
28
+ break
29
+ }
30
+ },
31
+ send(message) {
32
+ child.postMessage(message)
33
+ },
34
+ dispose() {
35
+ child.terminate()
36
+ },
37
+ }
38
+ }
@@ -0,0 +1,82 @@
1
+ import VError from 'verror'
2
+ import * as Assert from '../Assert/Assert.js'
3
+ import * as Timeout from '../Timeout/Timeout.js'
4
+
5
+ // TODO maybe rename to extension host management for clarity
6
+
7
+ const CONNECTION_TIMEOUT = 1000
8
+
9
+ export const create = async (ipc, socket) => {
10
+ Assert.object(socket)
11
+
12
+ const handleChildProcessError = (error) => {
13
+ console.error(`[Extension Host] ${error}`)
14
+ }
15
+
16
+ const handleChildProcessExit = (exitCode) => {
17
+ console.info(`[SharedProcess] Extension Host exited with code ${exitCode}`)
18
+ }
19
+
20
+ const handleSocketClose = () => {
21
+ console.info('[shared process] disposing extension host')
22
+ ipc.dispose()
23
+ }
24
+
25
+ socket.on('close', handleSocketClose)
26
+
27
+ ipc.on('error', handleChildProcessError)
28
+
29
+ ipc.on('exit', handleChildProcessExit)
30
+
31
+ await new Promise((resolve, reject) => {
32
+ const handleFirstError = (error) => {
33
+ cleanup()
34
+ reject(error)
35
+ }
36
+ const handleFirstExit = (exitCode) => {
37
+ cleanup()
38
+ reject(new VError(`Extension Host exited with code ${exitCode}`))
39
+ }
40
+ const handleFirstMessage = (message) => {
41
+ cleanup()
42
+ if (message === 'ready') {
43
+ resolve(undefined)
44
+ } else {
45
+ reject(new VError('Unexpected first message from extension host'))
46
+ }
47
+ }
48
+ const handleSocketClose = () => {
49
+ cleanup()
50
+ ipc.off('error', handleChildProcessError)
51
+ ipc.off('exit', handleChildProcessExit)
52
+ resolve(undefined)
53
+ }
54
+ const cleanup = () => {
55
+ ipc.off('error', handleFirstError)
56
+ ipc.off('exit', handleFirstExit)
57
+ ipc.off('message', handleFirstMessage)
58
+ clearTimeout(timeout)
59
+ }
60
+ const handleTimeout = () => {
61
+ cleanup()
62
+ reject(new VError('Extension host did not connect'))
63
+ }
64
+ const timeout = Timeout.setTimeout(handleTimeout, CONNECTION_TIMEOUT)
65
+ ipc.on('error', handleFirstError)
66
+ ipc.on('exit', handleFirstExit)
67
+ ipc.on('message', handleFirstMessage)
68
+ socket.on('close', handleSocketClose)
69
+ })
70
+
71
+ return {
72
+ on(event, listener) {
73
+ ipc.on(event, listener)
74
+ },
75
+ send(message) {
76
+ ipc.send(message)
77
+ },
78
+ dispose() {
79
+ ipc.dispose()
80
+ },
81
+ }
82
+ }
@@ -1,6 +1,10 @@
1
1
  import * as Command from '../Command/Command.js'
2
+ import * as ExtensionHostIconTheme from '../ExtensionManagement/ExtensionManagementIconTheme.js'
3
+ import * as ExtensionHostColorTheme from './ExtensionManagementColorTheme.js'
4
+ import * as ExtensionHostLanguages from './ExtensionManagementLanguages.js'
2
5
  import * as ExtensionManagement from './ExtensionManagement.js'
3
6
 
7
+ // prettier-ignore
4
8
  export const __initialize__ = () => {
5
9
  Command.register('ExtensionManagement.install', ExtensionManagement.install)
6
10
  Command.register('ExtensionManagement.uninstall', ExtensionManagement.uninstall)
@@ -8,4 +12,11 @@ export const __initialize__ = () => {
8
12
  Command.register('ExtensionManagement.disable', ExtensionManagement.disable)
9
13
  Command.register('ExtensionManagement.getAllExtensions', ExtensionManagement.getAllExtensions)
10
14
  Command.register('ExtensionManagement.getExtensions', ExtensionManagement.getExtensions)
15
+
16
+ Command.register('ExtensionHost.getColorThemeJson', ExtensionHostColorTheme.getColorThemeJson)
17
+ Command.register('ExtensionHost.getColorThemeNames', ExtensionHostColorTheme.getColorThemeNames)
18
+
19
+ Command.register('ExtensionHost.getLanguages', ExtensionHostLanguages.getLanguages)
20
+ Command.register('ExtensionHost.getLanguageConfiguration', ExtensionHostLanguages.getLanguageConfiguration)
21
+ Command.register('ExtensionHost.getIconThemeJson', ExtensionHostIconTheme.getIconTheme)
11
22
  }
@@ -1,5 +1,6 @@
1
1
  import { mkdir, readdir, rename, rm } from 'node:fs/promises'
2
2
  import { performance } from 'node:perf_hooks'
3
+ import path from 'node:path'
3
4
  import isObject from 'is-object'
4
5
  import VError from 'verror'
5
6
  import * as Debug from '../Debug/Debug.js'
@@ -8,10 +9,12 @@ import * as ReadJson from '../JsonFile/JsonFile.js'
8
9
  import * as Path from '../Path/Path.js'
9
10
  import * as Platform from '../Platform/Platform.js'
10
11
  import * as Queue from '../Queue/Queue.js'
11
- import path from 'node:path'
12
12
 
13
13
  const isLanguageBasics = (extension) => {
14
- return extension.id.includes('language-basics')
14
+ if (extension && extension.id) {
15
+ return extension.id.includes('language-basics')
16
+ }
17
+ return false
15
18
  }
16
19
 
17
20
  export const state = {
@@ -1,6 +1,6 @@
1
1
  import * as Error from '../Error/Error.js'
2
- import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
3
2
  import * as ReadJson from '../JsonFile/JsonFile.js'
3
+ import * as ExtensionManagement from './ExtensionManagement.js'
4
4
 
5
5
  // TODO test this function
6
6
  // TODO very similar with getIconTheme