@lvce-editor/shared-process 0.15.17 → 0.15.19

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 (67) hide show
  1. package/config/builtinCommands.json +4 -0
  2. package/extensions/builtin.language-basics-dart/src/tokenizeDart.js +2 -1
  3. package/extensions/builtin.language-basics-html/src/tokenizeHtml.js +77 -3
  4. package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +3 -0
  5. package/package.json +9 -9
  6. package/src/parts/AttachDebugger/AttachDebugger.ipc.js +7 -0
  7. package/src/parts/AttachDebugger/AttachDebugger.js +6 -0
  8. package/src/parts/Callback/Callback.js +17 -26
  9. package/src/parts/Character/Character.js +11 -0
  10. package/src/parts/CleanStack/CleanStack.js +4 -0
  11. package/src/parts/CommandNotFoundError/CommandNotFoundError.js +2 -1
  12. package/src/parts/Configuration/Configuration.js +4 -7
  13. package/src/parts/CreateCpuProfile/CreateCpuProfile.js +59 -0
  14. package/src/parts/DestroySocket/DestroySocket.js +5 -0
  15. package/src/parts/DevtoolsProtocolRpc/DevtoolsProtocolRpc.js +32 -0
  16. package/src/parts/ElectronInitialize/ElectronInitialize.js +9 -38
  17. package/src/parts/ErrorHandling/ErrorHandling.js +14 -15
  18. package/src/parts/ExportStatic/ExportStatic.js +4 -14
  19. package/src/parts/GetActualPath/GetActualPath.js +8 -0
  20. package/src/parts/GetErrorResponse/GetErrorResponse.js +5 -3
  21. package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +41 -0
  22. package/src/parts/GetNewLineIndex/GetNewLineIndex.js +3 -1
  23. package/src/parts/GetResponse/GetResponse.js +3 -3
  24. package/src/parts/GetTerminalSpawnOptions/GetTerminalSpawnOptions.ipc.js +7 -0
  25. package/src/parts/GetTerminalSpawnOptions/GetTerminalSpawnOptions.js +14 -0
  26. package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.ipc.js +7 -0
  27. package/src/parts/HandleElectronMessagePort/HandleElectronMessagePort.js +14 -0
  28. package/src/parts/HandleIpc/HandleIpc.js +4 -4
  29. package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.ipc.js +7 -0
  30. package/src/parts/HandleNodeMessagePort/HandleNodeMessagePort.js +12 -0
  31. package/src/parts/HandleWebSocket/HandleWebSocket.js +15 -14
  32. package/src/parts/HandleWebSocketForSharedProcess/HandleWebSocketForSharedProcess.js +10 -3
  33. package/src/parts/Id/Id.js +7 -0
  34. package/src/parts/IpcChild/IpcChild.js +3 -2
  35. package/src/parts/IpcChildModule/IpcChildModule.js +6 -0
  36. package/src/parts/IpcChildType/IpcChildType.js +3 -0
  37. package/src/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +41 -0
  38. package/src/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +25 -1
  39. package/src/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +21 -1
  40. package/src/parts/IpcChildWithNodeMessagePort/IpcChildWithNodeMessagePort.js +41 -0
  41. package/src/parts/IpcChildWithNodeWorker/IpcChildWithNodeWorker.js +17 -1
  42. package/src/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +51 -0
  43. package/src/parts/IpcError/IpcError.js +6 -0
  44. package/src/parts/IsMessagePort/IsMessagePort.js +3 -0
  45. package/src/parts/IsMessagePortMain/IsMessagePortMain.js +3 -0
  46. package/src/parts/IsSocket/IsSocket.js +5 -0
  47. package/src/parts/IsWebSocketOpen/IsWebSocketOpen.js +5 -0
  48. package/src/parts/JoinLines/JoinLines.js +3 -1
  49. package/src/parts/Json/Json.js +2 -1
  50. package/src/parts/JsonError/JsonError.js +3 -1
  51. package/src/parts/JsonRpc/JsonRpc.js +18 -22
  52. package/src/parts/Module/Module.js +10 -0
  53. package/src/parts/ModuleId/ModuleId.js +5 -0
  54. package/src/parts/ModuleMap/ModuleMap.js +14 -0
  55. package/src/parts/PrettyError/PrettyError.js +43 -53
  56. package/src/parts/Process/Process.ipc.js +1 -0
  57. package/src/parts/Process/Process.js +8 -0
  58. package/src/parts/ProcessDisplayName/ProcessDisplayName.js +1 -0
  59. package/src/parts/RequiresSocket/RequiresSocket.js +0 -1
  60. package/src/parts/Signal/Signal.js +2 -0
  61. package/src/parts/SplitLines/SplitLines.js +3 -1
  62. package/src/parts/Terminal/Terminal.js +31 -18
  63. package/src/parts/TerminalState/TerminalState.js +15 -0
  64. package/src/parts/WebSocketServer/WebSocketServer.js +7 -2
  65. package/src/sharedProcessMain.cjs +1 -0
  66. package/src/sharedProcessMain.js +2 -1
  67. package/src/parts/Socket/Socket.js +0 -77
@@ -230,6 +230,10 @@
230
230
  "id": "RebuildNodePty.rebuildNodePty",
231
231
  "label": "Developer: Rebuild Node Pty"
232
232
  },
233
+ {
234
+ "id": "DebugSharedProcess.debugSharedProcess",
235
+ "label": "Developer: Debug Shared Process"
236
+ },
233
237
  {
234
238
  "id": "Window.reload",
235
239
  "label": "Window: Reload",
@@ -43,9 +43,10 @@ export const hasArrayReturn = true
43
43
 
44
44
  const RE_KEYWORD =
45
45
  /^(?:abstract|as|assert|async|await|break|case|catch|class|const|continue|covariant|default|deferred|do|dynamic|else|enum|export|extends|extension|external|factory|false|final|finally|for|Function|get|hide|if|implements|import|in|interface|is|late|library|mixin|new|null|on|operator|part|required|rethrow|return|set|show|static|super|switch|sync|this|throw|true|try|typedef|var|void|while|with|yield)\b/
46
+
46
47
  const RE_WHITESPACE = /^\s+/
47
48
  const RE_VARIABLE_NAME = /^[a-zA-Z]+/
48
- const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)>]/
49
+ const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)>+<]/
49
50
  const RE_QUOTE_SINGLE = /^'/
50
51
  const RE_QUOTE_DOUBLE = /^"/
51
52
  const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
@@ -89,6 +89,7 @@ const RE_SCRIPT_CONTENT_END = /^<\/script/
89
89
  const RE_STYLE_CONTENT = /^..*?(?=(?:<\/(?:style|head))|$)/s
90
90
  const RE_STYLE_CONTENT_END = /^<\/style/
91
91
  const RE_STYLE_CONTENT_END_2 = /^<\/head/
92
+ const RE_TYPE = /^[^\s\>]+/
92
93
 
93
94
  export const initialLineState = {
94
95
  state: State.TopLevelContent,
@@ -98,6 +99,8 @@ export const initialLineState = {
98
99
  embeddedLanguageStart: 0,
99
100
  embeddedLanguageEnd: 0,
100
101
  embeddedState: undefined,
102
+ specialTag: false,
103
+ type: '',
101
104
  }
102
105
 
103
106
  /**
@@ -150,6 +153,54 @@ const getEmbeddedContentState = (tag) => {
150
153
  }
151
154
  }
152
155
 
156
+ /**
157
+ * @param {string} value
158
+ */
159
+ const unquote = (value) => {
160
+ for (const quote of ["'", '"']) {
161
+ if (value.startsWith(quote) && value.endsWith(quote)) {
162
+ return value.slice(1, -1)
163
+ }
164
+ }
165
+ return value
166
+ }
167
+
168
+ /**
169
+ *
170
+ * @param {string} value
171
+ */
172
+ const getType = (value) => {
173
+ const unquotedValue = unquote(value)
174
+ switch (unquotedValue) {
175
+ case 'text/javascript':
176
+ case 'text/x-javascript':
177
+ case 'text/jscript':
178
+ case 'text/livescript':
179
+ case 'text/babel':
180
+ case 'text/ecmascript':
181
+ case 'text/x-ecmascript':
182
+ case 'application/x-javascript':
183
+ case 'application/javascript':
184
+ case 'application/x-ecmascript':
185
+ case 'application/ecmascript':
186
+ case 'module':
187
+ return 'javascript'
188
+ case 'text/x-handlebars':
189
+ case 'text/x-handlebars-template':
190
+ case 'text/handlebars-template':
191
+ case 'text/template':
192
+ case 'text/x-template':
193
+ case 'text/ng-template':
194
+ case 'text/x-ng-template':
195
+ return 'html'
196
+ case 'application/json':
197
+ case 'application/ld+json':
198
+ return 'json'
199
+ default:
200
+ return ''
201
+ }
202
+ }
203
+
153
204
  /**
154
205
  *
155
206
  * @param {string} line
@@ -166,6 +217,9 @@ export const tokenizeLine = (line, lineState) => {
166
217
  let embeddedLanguage = lineState.embeddedLanguage
167
218
  let embeddedLanguageStart = lineState.embeddedLanguageStart
168
219
  let embeddedLanguageEnd = lineState.embeddedLanguageEnd
220
+ let specialTag = lineState.specialTag
221
+ let attributeName = ''
222
+ let type = ''
169
223
  while (index < line.length) {
170
224
  const part = line.slice(index)
171
225
  switch (state) {
@@ -198,6 +252,7 @@ export const tokenizeLine = (line, lineState) => {
198
252
  token = TokenType.TagName
199
253
  state = State.InsideOpeningTag
200
254
  tag = next[0]
255
+ specialTag = tag === 'script' || tag === 'style'
201
256
  } else if ((next = part.match(RE_SLASH))) {
202
257
  token = TokenType.PunctuationTag
203
258
  state = State.AfterClosingTagAngleBrackets
@@ -219,12 +274,15 @@ export const tokenizeLine = (line, lineState) => {
219
274
  if ((next = part.match(RE_ANGLE_BRACKET_CLOSE))) {
220
275
  token = TokenType.PunctuationTag
221
276
  state = State.TopLevelContent
222
- const embeddedLanguageId = getEmbeddedLangageId(tag)
277
+ const embeddedLanguageId = type || getEmbeddedLangageId(tag)
223
278
  if (embeddedLanguageId) {
224
279
  state = getEmbeddedContentState(tag)
225
280
  embeddedLanguage = embeddedLanguageId
226
281
  embeddedLanguageStart = index + next[0].length
227
282
  }
283
+ specialTag = false
284
+ type = ''
285
+ attributeName = ''
228
286
  } else if ((next = part.match(RE_EXCLAMATION_MARK))) {
229
287
  token = TokenType.PunctuationTag
230
288
  state = State.InsideOpeningTag
@@ -281,18 +339,22 @@ export const tokenizeLine = (line, lineState) => {
281
339
  if ((next = part.match(RE_ATTRIBUTE_NAME))) {
282
340
  token = TokenType.AttributeName
283
341
  state = State.AfterAttributeName
342
+ attributeName = next[0]
284
343
  } else if ((next = part.match(RE_SELF_CLOSING))) {
285
344
  token = TokenType.PunctuationTag
286
345
  state = State.TopLevelContent
287
346
  } else if ((next = part.match(RE_ANGLE_BRACKET_CLOSE))) {
288
347
  token = TokenType.PunctuationTag
289
348
  state = State.TopLevelContent
290
- const embeddedLanguageId = getEmbeddedLangageId(tag)
349
+ const embeddedLanguageId = type || getEmbeddedLangageId(tag)
291
350
  if (embeddedLanguageId) {
292
351
  state = getEmbeddedContentState(tag)
293
352
  embeddedLanguage = embeddedLanguageId
294
353
  embeddedLanguageStart = index + next[0].length
295
354
  }
355
+ specialTag = false
356
+ type = ''
357
+ attributeName = ''
296
358
  } else if ((next = part.match(RE_DOUBLE_QUOTE))) {
297
359
  token = TokenType.Punctuation
298
360
  state = State.InsideDoubleQuoteString
@@ -314,12 +376,15 @@ export const tokenizeLine = (line, lineState) => {
314
376
  if ((next = part.match(RE_ANGLE_BRACKET_CLOSE))) {
315
377
  token = TokenType.PunctuationTag
316
378
  state = State.TopLevelContent
317
- const embeddedLanguageId = getEmbeddedLangageId(tag)
379
+ const embeddedLanguageId = type || getEmbeddedLangageId(tag)
318
380
  if (embeddedLanguageId) {
319
381
  state = getEmbeddedContentState(tag)
320
382
  embeddedLanguage = embeddedLanguageId
321
383
  embeddedLanguageStart = index + next[0].length
322
384
  }
385
+ specialTag = false
386
+ type = ''
387
+ attributeName = ''
323
388
  } else if ((next = part.match(RE_EQUAL_SIGN))) {
324
389
  token = TokenType.Punctuation
325
390
  state = State.AfterAttributeEqualSign
@@ -345,6 +410,13 @@ export const tokenizeLine = (line, lineState) => {
345
410
  }
346
411
  break
347
412
  case State.AfterAttributeEqualSign:
413
+ if (specialTag && attributeName === 'type') {
414
+ const valueMatch = part.match(RE_TYPE)
415
+ if (valueMatch) {
416
+ const value = valueMatch[0]
417
+ type = getType(value)
418
+ }
419
+ }
348
420
  if ((next = part.match(RE_DOUBLE_QUOTE))) {
349
421
  token = TokenType.PunctuationString
350
422
  state = State.InsideDoubleQuoteString
@@ -473,5 +545,7 @@ export const tokenizeLine = (line, lineState) => {
473
545
  embeddedLanguage,
474
546
  embeddedLanguageStart,
475
547
  embeddedLanguageEnd,
548
+ specialTag,
549
+ type,
476
550
  }
477
551
  }
@@ -89,6 +89,7 @@ export const TokenMap = {
89
89
 
90
90
  const RE_KEYWORD =
91
91
  /^(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|if|implements|import|in|Infinity|instanceof|interface|let|new|null|of|package|private|protected|public|return|super|switch|static|this|throw|try|true|typeof|undefined|var|void|while|with|yield)\b/
92
+
92
93
  const RE_CURLY_OPEN = /^\{/
93
94
  const RE_CURLY_CLOSE = /^\}/
94
95
  const RE_SQUARE_OPEN = /^\[/
@@ -97,6 +98,7 @@ const RE_COMMA = /^,/
97
98
  const RE_COLON = /^:/
98
99
  const RE_NUMERIC =
99
100
  /^((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)\b/
101
+
100
102
  const RE_NUMERIC_OCTAL = /0(?:o|O)?[0-7][0-7_]*(n)?\b/
101
103
  const RE_LINE_COMMENT_START = /^\/\//
102
104
  const RE_LINE_COMMENT_CONTENT = /^[^\n]+/
@@ -128,6 +130,7 @@ const RE_STRING_ESCAPE = /^\\./
128
130
  const RE_SHEBANG = /^#!.*/
129
131
  const RE_FUNCTION_CALL_NAME =
130
132
  /^[\w]+(?=\s*(\(|\=\s*(?:async\s*)?function|\=\s*(?:async\s*)?\())/
133
+
131
134
  const RE_DECORATOR = /^@\w+/
132
135
  const RE_BACKSLASH = /^\\/
133
136
  const RE_DOLLAR_CURLY_OPEN = /^\$\{/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.15.17",
3
+ "version": "0.15.19",
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.21.4",
20
- "@lvce-editor/extension-host": "0.15.17",
21
- "@lvce-editor/extension-host-helper-process": "0.15.17",
22
- "@lvce-editor/pty-host": "0.15.17",
20
+ "@lvce-editor/extension-host": "0.15.19",
21
+ "@lvce-editor/extension-host-helper-process": "0.15.19",
22
+ "@lvce-editor/pty-host": "0.15.19",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^7.1.1",
25
25
  "exit-hook": "^3.2.0",
@@ -28,11 +28,7 @@
28
28
  "lines-and-columns": "^2.0.3",
29
29
  "p-queue": "^7.3.4",
30
30
  "parse-json": "^7.0.0",
31
- "symlink-dir": "^5.1.1",
32
- "tail": "^2.2.6",
33
31
  "tar-fs": "^2.1.1",
34
- "tmp-promise": "^3.0.3",
35
- "trash": "^8.1.1",
36
32
  "ws": "^8.13.0",
37
33
  "xdg-basedir": "^5.1.0"
38
34
  },
@@ -40,6 +36,10 @@
40
36
  "extract-zip": "^2.0.1",
41
37
  "keytar": "^7.9.0",
42
38
  "vscode-ripgrep-with-github-api-error-fix": "^2.8.0",
43
- "open": "^9.1.0"
39
+ "open": "^9.1.0",
40
+ "symlink-dir": "^5.1.1",
41
+ "tmp-promise": "^3.0.3",
42
+ "trash": "^8.1.1",
43
+ "tail": "^2.2.6"
44
44
  }
45
45
  }
@@ -0,0 +1,7 @@
1
+ import * as AttachDebugger from './AttachDebugger.js'
2
+
3
+ export const name = 'AttachDebugger'
4
+
5
+ export const Commands = {
6
+ attachDebugger: AttachDebugger.attachDebugger,
7
+ }
@@ -0,0 +1,6 @@
1
+ import * as Process from '../Process/Process.js'
2
+ import * as Signal from '../Signal/Signal.js'
3
+
4
+ export const attachDebugger = (pid) => {
5
+ Process.kill(pid, Signal.SIGUSR1)
6
+ }
@@ -1,48 +1,39 @@
1
+ import * as Id from '../Id/Id.js'
2
+
1
3
  export const state = {
2
4
  callbacks: Object.create(null),
3
5
  onceListeners: new Set(),
4
- id: 2,
5
- }
6
-
7
- export const register = (resolve, reject) => {
8
- state.callbacks[++state.id] = {
9
- resolve,
10
- reject,
11
- }
12
- return state.id
13
6
  }
14
7
 
15
- export const unregister = (id) => {
16
- delete state.callbacks[id]
8
+ export const registerPromise = () => {
9
+ const id = Id.create()
10
+ const promise = new Promise((resolve, reject) => {
11
+ state.callbacks[id] = { resolve, reject }
12
+ })
13
+ return { id, promise }
17
14
  }
18
15
 
19
16
  // TODO merge resolve and resolveEmpty
20
17
  export const resolve = (id, args) => {
21
- if (!(id in state.callbacks)) {
18
+ const { callbacks } = state
19
+ if (!(id in callbacks)) {
22
20
  console.warn(`callback ${id} may already be disposed`)
23
21
  return
24
22
  }
25
- state.callbacks[id].resolve(args)
26
- }
27
-
28
- export const resolveEmpty = (id) => {
29
- if (!(id in state.callbacks)) {
30
- console.warn(`callback (resolved) ${id} may already be disposed`)
31
- return
32
- }
33
- state.callbacks[id].resolve()
23
+ callbacks[id].resolve(args)
24
+ delete callbacks[id]
34
25
  }
35
26
 
36
27
  export const reject = (id, error) => {
37
- if (!(id in state.callbacks)) {
28
+ const { callbacks } = state
29
+ if (!(id in callbacks)) {
38
30
  console.warn(`callback (rejected) ${id} may already be disposed`)
39
31
  return
40
32
  }
41
- state.callbacks[id].reject(error)
33
+ callbacks[id].reject(error)
34
+ delete callbacks[id]
42
35
  }
43
36
 
44
37
  export const isAllEmpty = () => {
45
- return (
46
- Object.keys(state.callbacks).length === 0 && state.onceListeners.size === 0
47
- )
38
+ return Object.keys(state.callbacks).length === 0 && state.onceListeners.size === 0
48
39
  }
@@ -0,0 +1,11 @@
1
+ export const Backslash = '\\'
2
+ export const Dash = '-'
3
+ export const Dot = '.'
4
+ export const EmptyString = ''
5
+ export const NewLine = '\n'
6
+ export const OpenAngleBracket = '<'
7
+ export const Slash = '/'
8
+ export const Space = ' '
9
+ export const Tab = '\t'
10
+ export const Underline = '_'
11
+ export const T = 't'
@@ -7,6 +7,7 @@ const RE_GET_RESPONSE = /^\s*at async getResponse/
7
7
  const RE_WEBSOCKET_HANDLE_MESSAGE = /^\s*at async WebSocket.handleMessage/
8
8
  const RE_EXECUTE_COMMAND_ASYNC = /^\s*at executeCommandAsync/
9
9
  const RE_HANDLE_OTHER_MESSAGES_FROM_MESSAGE_PORT = /^\s*at async MessagePort\.handleOtherMessagesFromMessagePort/
10
+ const RE_ASSERT = /^\s*at .*\/Assert\.js/
10
11
 
11
12
  const isInternalLine = (line) => {
12
13
  return line.includes('node:') || RE_AT_PROMISE_INDEX.test(line) || line.includes('node_modules/ws')
@@ -18,6 +19,9 @@ const isRelevantLine = (line) => {
18
19
 
19
20
  const isApplicationUsefulLine = (line, index) => {
20
21
  if (index === 0) {
22
+ if (RE_ASSERT.test(line)) {
23
+ return false
24
+ }
21
25
  return true
22
26
  }
23
27
  if (RE_GET_RESPONSE.test(line)) {
@@ -1,8 +1,9 @@
1
1
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
+ import * as ProcessDisplayName from '../ProcessDisplayName/ProcessDisplayName.js'
2
3
 
3
4
  export class CommandNotFoundError extends Error {
4
5
  constructor(id) {
5
- super(`command ${id} not found`)
6
+ super(`command ${id} not found in ${ProcessDisplayName.processDisplayName}`)
6
7
  this.name = 'CommandNotFoundError'
7
8
  this.code = ErrorCodes.E_COMMAND_NOT_FOUND
8
9
  }
@@ -1,6 +1,6 @@
1
- import { readFile } from 'node:fs/promises'
1
+ import * as Character from '../Character/Character.js'
2
2
  import { writeFile } from '../FileSystem/FileSystem.js'
3
- import * as ReadJson from '../JsonFile/JsonFile.js'
3
+ import * as JsonFile from '../JsonFile/JsonFile.js'
4
4
 
5
5
  let settings
6
6
  let settingsPromise
@@ -9,7 +9,7 @@ const readSettings = async () => {
9
9
  // TODO allow jsonc
10
10
  if (!settings) {
11
11
  if (!settingsPromise) {
12
- settingsPromise = ReadJson.readJson('/tmp/settings.json')
12
+ settingsPromise = JsonFile.readJson('/tmp/settings.json')
13
13
  }
14
14
  await settingsPromise
15
15
  }
@@ -18,10 +18,7 @@ const readSettings = async () => {
18
18
 
19
19
  const writeSettings = async () => {
20
20
  // TODO jsonc
21
- await writeFile(
22
- '/tmp/settings.json',
23
- JSON.stringify(settings, null, 2) + '\n'
24
- )
21
+ await writeFile('/tmp/settings.json', JSON.stringify(settings, null, 2) + Character.NewLine)
25
22
  }
26
23
 
27
24
  export const get = async (key) => {
@@ -0,0 +1,59 @@
1
+ import { writeFile } from 'fs/promises'
2
+ import got from 'got'
3
+ import { tmpdir } from 'os'
4
+ import { join } from 'path'
5
+ import { WebSocket } from 'ws'
6
+ import * as DevtoolsProtocolRpc from '../DevtoolsProtocolRpc/DevtoolsProtocolRpc.js'
7
+
8
+ const createConnection = (webSocketDebuggerUrl) => {
9
+ const webSocket = new WebSocket(webSocketDebuggerUrl)
10
+ // console.log({ webSocket })
11
+ return {
12
+ on(event, listener) {
13
+ if (event === 'message') {
14
+ const wrappedListener = (string) => {
15
+ listener(JSON.parse(string))
16
+ }
17
+ webSocket.on(event, wrappedListener)
18
+ } else {
19
+ webSocket.on(event, listener)
20
+ }
21
+ },
22
+ send(message) {
23
+ webSocket.send(JSON.stringify(message))
24
+ },
25
+ }
26
+ }
27
+
28
+ export const createCpuProfile = async (pid) => {
29
+ // AttachDebugger.attachDebugger(pid)
30
+ const response = await got('http://localhost:9229/json/list').json()
31
+ const first = response[0]
32
+ const webSocketDebuggerUrl = first.webSocketDebuggerUrl
33
+ const ipc = createConnection(webSocketDebuggerUrl)
34
+
35
+ await new Promise((r) => {
36
+ ipc.on('open', r)
37
+ })
38
+ const rpc = DevtoolsProtocolRpc.create(ipc)
39
+ const result = await rpc.invoke('Debugger.enable')
40
+ const debuggerId = result.result.debuggerId
41
+ console.log({ debuggerId })
42
+ const p = await rpc.invoke('Profiler.enable')
43
+ await rpc.invoke('Profiler.start')
44
+ await new Promise((r) => {
45
+ setTimeout(r, 10000)
46
+ })
47
+ const profileResult = await rpc.invoke('Profiler.stop')
48
+ console.log({ profileResult })
49
+ const profile = profileResult.result.profile
50
+ const profilePath = join(tmpdir(), 'node-profile.cpuprofile')
51
+ const profileString = JSON.stringify(profile)
52
+ await writeFile(profilePath, profileString)
53
+ console.log('finished')
54
+ // const value = await rpc.invoke('Runtime.evaluate', {
55
+ // expression: '1+1',
56
+ // })
57
+ // await rpc.invoke('Debugger.pause')
58
+ // console.log({ value })
59
+ }
@@ -0,0 +1,5 @@
1
+ export const destroySocket = (socket) => {
2
+ try {
3
+ socket.destroy()
4
+ } catch {}
5
+ }
@@ -0,0 +1,32 @@
1
+ const Id = {
2
+ id: 1,
3
+ create() {
4
+ return this.id++
5
+ },
6
+ }
7
+
8
+ export const create = (ipc) => {
9
+ const callbacks = Object.create(null)
10
+ const handleMessage = (message) => {
11
+ if ('result' in message) {
12
+ const callback = callbacks[message.id]
13
+ callback(message)
14
+ delete callbacks[message.id]
15
+ }
16
+ }
17
+ ipc.on('message', handleMessage)
18
+ return {
19
+ invoke(method, params = {}) {
20
+ const id = Id.create()
21
+ const promise = new Promise((resolve, reject) => {
22
+ callbacks[id] = resolve
23
+ })
24
+ ipc.send({
25
+ method,
26
+ id,
27
+ params,
28
+ })
29
+ return promise
30
+ },
31
+ }
32
+ }
@@ -1,40 +1,11 @@
1
- import * as Callback from '../Callback/Callback.js'
2
- import * as Command from '../Command/Command.js'
3
- import * as GetResponse from '../GetResponse/GetResponse.js'
1
+ import * as HandleIpc from '../HandleIpc/HandleIpc.js'
2
+ import * as IpcChild from '../IpcChild/IpcChild.js'
3
+ import * as IpcChildType from '../IpcChildType/IpcChildType.js'
4
4
 
5
- export const electronInitialize = (port, folder) => {
6
- // TODO handle error
7
- const fakeSocket = {
8
- send: port.postMessage.bind(port),
9
- on(event, listener) {
10
- switch (event) {
11
- case 'close':
12
- port.on('close', listener)
13
- break
14
- case 'message':
15
- port.on('message', listener)
16
- break
17
- default:
18
- console.warn('socket event not implemented', event, listener)
19
- break
20
- }
21
- },
22
- }
23
- const handleOtherMessagesFromMessagePort = async (message) => {
24
- // console.log('got port message', message)
25
- if (message.result) {
26
- Callback.resolve(message.id, message.result)
27
- } else if (message.method) {
28
- if (message.id) {
29
- const response = await GetResponse.getResponse(message, fakeSocket)
30
- port.postMessage(response)
31
- } else {
32
- console.warn(`[shared process] sending messages without id is deprecated: ${message.method}`)
33
- Command.execute(message.method, fakeSocket, ...message.params)
34
- }
35
- } else {
36
- console.warn('unknown message', message)
37
- }
38
- }
39
- port.on('message', handleOtherMessagesFromMessagePort)
5
+ export const electronInitialize = async (port, folder) => {
6
+ const ipc = await IpcChild.listen({
7
+ method: IpcChildType.NodeMessagePort,
8
+ messagePort: port,
9
+ })
10
+ HandleIpc.handleIpc(ipc)
40
11
  }
@@ -1,11 +1,10 @@
1
+ import * as Character from '../Character/Character.js'
1
2
  import * as ExitCode from '../ExitCode/ExitCode.js'
3
+ import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
2
4
  import * as IsIgnoredError from '../IsIgnoredError/IsIgnoredError.js'
3
- import * as JsonRpcVersion from '../JsonRpcVersion/JsonRpcVersion.js'
4
5
  import * as Logger from '../Logger/Logger.js'
5
6
  import * as PrettyError from '../PrettyError/PrettyError.js'
6
7
  import * as Process from '../Process/Process.js'
7
- import * as Socket from '../Socket/Socket.js'
8
- import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
9
8
 
10
9
  export const state = {
11
10
  seenErrors: [],
@@ -30,17 +29,17 @@ export const handleError = (error) => {
30
29
  }
31
30
  state.seenErrors.push(error.message)
32
31
  const prettyError = preparePrettyError(error)
33
- Socket.send({
34
- jsonrpc: JsonRpcVersion.Two,
35
- method: /* Dialog.showErrorDialogWithOptions */ 'Dialog.showMessage',
36
- params: [
37
- {
38
- message: prettyError.message,
39
- codeFrame: prettyError.codeFrame,
40
- stack: prettyError.stack,
41
- },
42
- ],
43
- })
32
+ // Socket.send({
33
+ // jsonrpc: JsonRpcVersion.Two,
34
+ // method: /* Dialog.showErrorDialogWithOptions */ 'Dialog.showMessage',
35
+ // params: [
36
+ // {
37
+ // message: prettyError.message,
38
+ // codeFrame: prettyError.codeFrame,
39
+ // stack: prettyError.stack,
40
+ // },
41
+ // ],
42
+ // })
44
43
  printPrettyError(prettyError)
45
44
  }
46
45
 
@@ -64,6 +63,6 @@ export const handleUncaughtExceptionMonitor = (error, origin) => {
64
63
  return
65
64
  }
66
65
  const prettyError = PrettyError.prepare(error)
67
- Logger.error(prettyError.codeFrame + '\n' + prettyError.stack + '\n')
66
+ Logger.error(prettyError.codeFrame + Character.NewLine + prettyError.stack + Character.NewLine)
68
67
  Process.setExitCode(ExitCode.Error)
69
68
  }
@@ -119,13 +119,8 @@ const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
119
119
  )
120
120
  await replace(
121
121
  Path.join(root, 'dist', commitHash, 'packages', 'renderer-worker', 'dist', 'rendererWorkerMain.js'),
122
- `getColorThemeUrlWeb = (colorThemeId) => {
123
- return \`/extensions/builtin.theme-\${colorThemeId}/color-theme.json\`;
124
- };`,
125
- `const getColorThemeUrlWeb = (colorThemeId) => {
126
- const assetDir = getAssetDir()
127
- return \`\${assetDir}/themes/\${colorThemeId}.json\`
128
- }`
122
+ `return \`\${assetDir}/extensions/builtin.theme-\${colorThemeId}/color-theme.json\``,
123
+ `return \`\${assetDir}/themes/\${colorThemeId}.json\``
129
124
  )
130
125
  await replace(
131
126
  Path.join(root, 'dist', commitHash, 'packages', 'extension-host-worker', 'dist', 'extensionHostWorkerMain.js'),
@@ -134,13 +129,8 @@ const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
134
129
  )
135
130
  await replace(
136
131
  Path.join(root, 'dist', commitHash, 'packages', 'renderer-worker', 'dist', 'rendererWorkerMain.js'),
137
- `getIconThemeUrl = (iconThemeId) => {
138
- return \`/extensions/builtin.\${iconThemeId}/icon-theme.json\`;
139
- }`,
140
- `getIconThemeUrl = (iconThemeId) => {
141
- const assetDir = getAssetDir()
142
- return \`\${assetDir}/icon-themes/\${iconThemeId}.json\`
143
- }`
132
+ `return \`\${assetDir}/extensions/builtin.\${iconThemeId}/icon-theme.json\``,
133
+ `return \`\${assetDir}/icon-themes/\${iconThemeId}.json\``
144
134
  )
145
135
  await replace(
146
136
  Path.join(root, 'dist', commitHash, 'packages', 'renderer-worker', 'dist', 'rendererWorkerMain.js'),
@@ -0,0 +1,8 @@
1
+ import { fileURLToPath } from 'node:url'
2
+
3
+ export const getActualPath = (fileUri) => {
4
+ if (fileUri.startsWith('file://')) {
5
+ return fileURLToPath(fileUri)
6
+ }
7
+ return fileUri
8
+ }