@lvce-editor/process-explorer 2.4.0 → 3.1.0

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.
File without changes
package/dist/index.js CHANGED
@@ -1,384 +1,90 @@
1
- import { IpcChildWithWebSocket, IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithNodeWorker, IpcChildWithNodeForkedProcess } from '@lvce-editor/ipc';
1
+ import { ElectronMessagePortRpcClient, WebSocketRpcParent, NodeWebSocketRpcClient, NodeWorkerRpcClient, NodeForkedProcessRpcClient, ElectronUtilityProcessRpcClient } from '@lvce-editor/rpc';
2
2
  import { object, number, string } from '@lvce-editor/assert';
3
+ import { RpcId, MainProcess, set as set$1 } from '@lvce-editor/rpc-registry';
3
4
  import { VError } from '@lvce-editor/verror';
4
5
  import { readFile } from 'node:fs/promises';
5
6
  import { join } from 'node:path';
6
7
  import { execFile as execFile$1 } from 'node:child_process';
7
8
  import { promisify } from 'node:util';
8
9
 
9
- const Two = '2.0';
10
- const callbacks = Object.create(null);
11
- const set = (id, fn) => {
12
- callbacks[id] = fn;
13
- };
14
- const get = id => {
15
- return callbacks[id];
16
- };
17
- const remove = id => {
18
- delete callbacks[id];
19
- };
20
- let id = 0;
21
- const create$3 = () => {
22
- return ++id;
23
- };
24
- const registerPromise = () => {
25
- const id = create$3();
26
- const {
27
- resolve,
28
- promise
29
- } = Promise.withResolvers();
30
- set(id, resolve);
31
- return {
32
- id,
33
- promise
34
- };
35
- };
36
- const create$2 = (method, params) => {
37
- const {
38
- id,
39
- promise
40
- } = registerPromise();
41
- const message = {
42
- jsonrpc: Two,
43
- method,
44
- params,
45
- id
46
- };
47
- return {
48
- message,
49
- promise
50
- };
51
- };
52
- class JsonRpcError extends Error {
53
- constructor(message) {
54
- super(message);
55
- this.name = 'JsonRpcError';
56
- }
57
- }
58
- const NewLine$1 = '\n';
59
- const DomException = 'DOMException';
60
- const ReferenceError$1 = 'ReferenceError';
61
- const SyntaxError$1 = 'SyntaxError';
62
- const TypeError$1 = 'TypeError';
63
- const getErrorConstructor = (message, type) => {
64
- if (type) {
65
- switch (type) {
66
- case DomException:
67
- return DOMException;
68
- case TypeError$1:
69
- return TypeError;
70
- case SyntaxError$1:
71
- return SyntaxError;
72
- case ReferenceError$1:
73
- return ReferenceError;
74
- default:
75
- return Error;
76
- }
77
- }
78
- if (message.startsWith('TypeError: ')) {
79
- return TypeError;
80
- }
81
- if (message.startsWith('SyntaxError: ')) {
82
- return SyntaxError;
83
- }
84
- if (message.startsWith('ReferenceError: ')) {
85
- return ReferenceError;
86
- }
87
- return Error;
88
- };
89
- const constructError = (message, type, name) => {
90
- const ErrorConstructor = getErrorConstructor(message, type);
91
- if (ErrorConstructor === DOMException && name) {
92
- return new ErrorConstructor(message, name);
93
- }
94
- if (ErrorConstructor === Error) {
95
- const error = new Error(message);
96
- if (name && name !== 'VError') {
97
- error.name = name;
98
- }
99
- return error;
100
- }
101
- return new ErrorConstructor(message);
102
- };
103
- const getNewLineIndex = (string, startIndex = undefined) => {
104
- return string.indexOf(NewLine$1, startIndex);
105
- };
106
- const getParentStack = error => {
107
- let parentStack = error.stack || error.data || error.message || '';
108
- if (parentStack.startsWith(' at')) {
109
- parentStack = error.message + NewLine$1 + parentStack;
110
- }
111
- return parentStack;
112
- };
113
- const joinLines = lines => {
114
- return lines.join(NewLine$1);
115
- };
116
- const MethodNotFound = -32601;
117
- const Custom = -32001;
118
- const splitLines$1 = lines => {
119
- return lines.split(NewLine$1);
120
- };
121
- const restoreJsonRpcError = error => {
122
- if (error && error instanceof Error) {
123
- return error;
124
- }
125
- const currentStack = joinLines(splitLines$1(new Error().stack || '').slice(1));
126
- if (error && error.code && error.code === MethodNotFound) {
127
- const restoredError = new JsonRpcError(error.message);
128
- const parentStack = getParentStack(error);
129
- restoredError.stack = parentStack + NewLine$1 + currentStack;
130
- return restoredError;
131
- }
132
- if (error && error.message) {
133
- const restoredError = constructError(error.message, error.type, error.name);
134
- if (error.data) {
135
- if (error.data.stack && error.data.type && error.message) {
136
- restoredError.stack = error.data.type + ': ' + error.message + NewLine$1 + error.data.stack + NewLine$1 + currentStack;
137
- } else if (error.data.stack) {
138
- restoredError.stack = error.data.stack;
139
- }
140
- if (error.data.codeFrame) {
141
- // @ts-ignore
142
- restoredError.codeFrame = error.data.codeFrame;
143
- }
144
- if (error.data.code) {
145
- // @ts-ignore
146
- restoredError.code = error.data.code;
147
- }
148
- if (error.data.type) {
149
- // @ts-ignore
150
- restoredError.name = error.data.type;
151
- }
152
- } else {
153
- if (error.stack) {
154
- const lowerStack = restoredError.stack || '';
155
- // @ts-ignore
156
- const indexNewLine = getNewLineIndex(lowerStack);
157
- const parentStack = getParentStack(error);
158
- // @ts-ignore
159
- restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
160
- }
161
- if (error.codeFrame) {
162
- // @ts-ignore
163
- restoredError.codeFrame = error.codeFrame;
164
- }
165
- }
166
- return restoredError;
167
- }
168
- if (typeof error === 'string') {
169
- return new Error(`JsonRpc Error: ${error}`);
170
- }
171
- return new Error(`JsonRpc Error: ${error}`);
172
- };
173
- const unwrapJsonRpcResult = responseMessage => {
174
- if ('error' in responseMessage) {
175
- const restoredError = restoreJsonRpcError(responseMessage.error);
176
- throw restoredError;
177
- }
178
- if ('result' in responseMessage) {
179
- return responseMessage.result;
180
- }
181
- throw new JsonRpcError('unexpected response message');
182
- };
183
- const warn = (...args) => {
184
- console.warn(...args);
185
- };
186
- const resolve = (id, response) => {
187
- const fn = get(id);
188
- if (!fn) {
189
- console.log(response);
190
- warn(`callback ${id} may already be disposed`);
191
- return;
192
- }
193
- fn(response);
194
- remove(id);
195
- };
196
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
197
- const getErrorType = prettyError => {
198
- if (prettyError && prettyError.type) {
199
- return prettyError.type;
200
- }
201
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
202
- return prettyError.constructor.name;
203
- }
204
- return undefined;
205
- };
206
- const getErrorProperty = (error, prettyError) => {
207
- if (error && error.code === E_COMMAND_NOT_FOUND) {
208
- return {
209
- code: MethodNotFound,
210
- message: error.message,
211
- data: error.stack
212
- };
213
- }
214
- return {
215
- code: Custom,
216
- message: prettyError.message,
217
- data: {
218
- stack: prettyError.stack,
219
- codeFrame: prettyError.codeFrame,
220
- type: getErrorType(prettyError),
221
- code: prettyError.code,
222
- name: prettyError.name
223
- }
224
- };
225
- };
226
- const create$1 = (message, error) => {
227
- return {
228
- jsonrpc: Two,
229
- id: message.id,
230
- error
231
- };
232
- };
233
- const getErrorResponse = (message, error, preparePrettyError, logError) => {
234
- const prettyError = preparePrettyError(error);
235
- logError(error, prettyError);
236
- const errorProperty = getErrorProperty(error, prettyError);
237
- return create$1(message, errorProperty);
238
- };
239
- const create = (message, result) => {
240
- return {
241
- jsonrpc: Two,
242
- id: message.id,
243
- result: result ?? null
244
- };
245
- };
246
- const getSuccessResponse = (message, result) => {
247
- const resultProperty = result ?? null;
248
- return create(message, resultProperty);
249
- };
250
- const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
251
- try {
252
- const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
253
- return getSuccessResponse(message, result);
254
- } catch (error) {
255
- return getErrorResponse(message, error, preparePrettyError, logError);
256
- }
10
+ const state = {
11
+ commandMap: {}
257
12
  };
258
- const defaultPreparePrettyError = error => {
259
- return error;
13
+ const set = commandMap => {
14
+ state.commandMap = commandMap;
260
15
  };
261
- const defaultLogError = () => {
262
- // ignore
16
+ const get = () => {
17
+ return state.commandMap;
263
18
  };
264
- const defaultRequiresSocket = () => {
19
+
20
+ const requiresSocket = () => {
265
21
  return false;
266
22
  };
267
- const defaultResolve = resolve;
268
23
 
269
- // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
270
- const normalizeParams = args => {
271
- if (args.length === 1) {
272
- const options = args[0];
273
- return {
274
- ipc: options.ipc,
275
- message: options.message,
276
- execute: options.execute,
277
- resolve: options.resolve || defaultResolve,
278
- preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
279
- logError: options.logError || defaultLogError,
280
- requiresSocket: options.requiresSocket || defaultRequiresSocket
281
- };
282
- }
283
- return {
284
- ipc: args[0],
285
- message: args[1],
286
- execute: args[2],
287
- resolve: args[3],
288
- preparePrettyError: args[4],
289
- logError: args[5],
290
- requiresSocket: args[6]
291
- };
292
- };
293
- const handleJsonRpcMessage = async (...args) => {
294
- const options = normalizeParams(args);
295
- const {
296
- message,
297
- ipc,
298
- execute,
299
- resolve,
300
- preparePrettyError,
301
- logError,
302
- requiresSocket
303
- } = options;
304
- if ('id' in message) {
305
- if ('method' in message) {
306
- const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
307
- try {
308
- ipc.send(response);
309
- } catch (error) {
310
- const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
311
- ipc.send(errorResponse);
312
- }
313
- return;
314
- }
315
- resolve(message.id, message);
24
+ const setRpc = (rpc, rpcId) => {
25
+ if (typeof rpcId !== 'number') {
316
26
  return;
317
27
  }
318
- if ('method' in message) {
319
- await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
28
+ if (rpcId === RpcId.MainProcess) {
29
+ MainProcess.set(rpc);
320
30
  return;
321
31
  }
322
- throw new JsonRpcError('unexpected message');
32
+ set$1(rpcId, rpc);
323
33
  };
324
- const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
325
- const {
326
- message,
327
- promise
328
- } = create$2(method, params);
329
- {
330
- ipc.send(message);
331
- }
332
- const responseMessage = await promise;
333
- return unwrapJsonRpcResult(responseMessage);
34
+
35
+ const createMessagePortRpc = async (create, messagePort) => {
36
+ return create({
37
+ commandMap: get(),
38
+ messagePort,
39
+ requiresSocket: requiresSocket
40
+ });
334
41
  };
335
- const invoke$1 = (ipc, method, ...params) => {
336
- return invokeHelper(ipc, method, params);
42
+ const handleMessagePort = async (messagePort, rpcId) => {
43
+ object(messagePort);
44
+ const rpc = await createMessagePortRpc(ElectronMessagePortRpcClient.create, messagePort);
45
+ setRpc(rpc, rpcId);
337
46
  };
338
47
 
339
- const state$1 = {
340
- commands: Object.create(null)
48
+ const handleElectronMessagePort = async (messagePort, rpcId) => {
49
+ await handleMessagePort(messagePort, rpcId);
341
50
  };
342
- const registerCommand = (key, fn) => {
343
- state$1.commands[key] = fn;
344
- };
345
- const registerCommands = commandMap => {
346
- for (const [key, value] of Object.entries(commandMap)) {
347
- registerCommand(key, value);
348
- }
51
+
52
+ const createSocketRpc = async (create, webSocket) => {
53
+ return create({
54
+ commandMap: get(),
55
+ webSocket
56
+ });
349
57
  };
350
- const getCommand = key => {
351
- return state$1.commands[key];
58
+ const handleSocket = async (webSocket, rpcId) => {
59
+ object(webSocket);
60
+ const rpc = await createSocketRpc(WebSocketRpcParent.create, webSocket);
61
+ setRpc(rpc, rpcId);
352
62
  };
353
63
 
354
- const execute = (command, ...args) => {
355
- const fn = getCommand(command);
356
- if (!fn) {
357
- throw new Error(`Command not found ${command}`);
358
- }
359
- return fn(...args);
360
- };
64
+ const isWindows = process.platform === 'win32';
361
65
 
362
- const preparePrettyError = error => {
363
- return error;
364
- };
365
- const logError = error => {
366
- console.error(error);
66
+ const getModule$1 = async () => {
67
+ if (isWindows) {
68
+ return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
69
+ }
70
+ return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; });
367
71
  };
368
- const requiresSocket = () => {
369
- return false;
72
+ const listProcessesWithMemoryUsage$2 = async rootPid => {
73
+ const module = await getModule$1();
74
+ return module.listProcessesWithMemoryUsage(rootPid);
370
75
  };
371
- const handleMessage = event => {
372
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
76
+
77
+ const getMainProcessId = () => {
78
+ return process.ppid;
373
79
  };
374
80
 
375
- const handleIpc = ipc => {
376
- if ('addEventListener' in ipc) {
377
- ipc.addEventListener('message', handleMessage);
378
- } else {
379
- // deprecated
380
- ipc.on('message', handleMessage);
381
- }
81
+ const commandMap = {
82
+ 'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
83
+ 'HandleMessagePort.handleMessagePort': handleMessagePort,
84
+ 'HandleSocket.handleSocket': handleSocket,
85
+ 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2,
86
+ 'ProcessId.getMainProcessId': getMainProcessId
87
+ // 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
382
88
  };
383
89
 
384
90
  const NodeWorker = 1;
@@ -402,18 +108,18 @@ const Auto = () => {
402
108
  throw new Error(`[shared-process] unknown ipc type`);
403
109
  };
404
110
 
405
- const getModule$1 = method => {
111
+ const getModule = method => {
406
112
  switch (method) {
113
+ case ElectronMessagePort:
114
+ return ElectronMessagePortRpcClient.create;
115
+ case ElectronUtilityProcess:
116
+ return ElectronUtilityProcessRpcClient.create;
407
117
  case NodeForkedProcess:
408
- return IpcChildWithNodeForkedProcess;
118
+ return NodeForkedProcessRpcClient.create;
409
119
  case NodeWorker:
410
- return IpcChildWithNodeWorker;
411
- case ElectronUtilityProcess:
412
- return IpcChildWithElectronUtilityProcess;
413
- case ElectronMessagePort:
414
- return IpcChildWithElectronMessagePort;
120
+ return NodeWorkerRpcClient.create;
415
121
  case WebSocket:
416
- return IpcChildWithWebSocket;
122
+ return NodeWebSocketRpcClient.create;
417
123
  default:
418
124
  throw new Error('unexpected ipc type');
419
125
  }
@@ -423,79 +129,79 @@ const listen$1 = async ({
423
129
  method,
424
130
  ...params
425
131
  }) => {
426
- const module = await getModule$1(method);
427
- // @ts-ignore
428
- const rawIpc = await module.listen(params);
429
- // @ts-ignore
430
- if (module.signal) {
431
- // @ts-ignore
432
- module.signal(rawIpc);
433
- }
434
- // @ts-ignore
435
- const ipc = module.wrap(rawIpc);
436
- return ipc;
132
+ const create = getModule(method);
133
+ const rpc = await create(params);
134
+ return rpc;
437
135
  };
438
136
 
439
137
  const listen = async () => {
440
- const ipc = await listen$1({
138
+ set(commandMap);
139
+ await listen$1({
140
+ commandMap: commandMap,
441
141
  method: Auto()
442
142
  });
443
- handleIpc(ipc);
444
- };
445
-
446
- const MainProcess = -5;
447
-
448
- const state = {
449
- ipc: undefined
450
- };
451
- const invoke = (method, ...params) => {
452
- return invoke$1(state.ipc, method, ...params);
453
- };
454
-
455
- const handleElectronMessagePort = async (messagePort, ipcId) => {
456
- object(messagePort);
457
- // Assert.number(ipcId)
458
- const ipc = await listen$1({
459
- method: ElectronMessagePort,
460
- messagePort
461
- });
462
- handleIpc(ipc);
463
- if (ipcId === MainProcess) {
464
- state.ipc = ipc;
465
- }
466
- };
467
-
468
- const getMainProcessId = () => {
469
- return process.ppid;
470
- };
471
-
472
- const isWindows = process.platform === 'win32';
473
-
474
- const getModule = () => {
475
- if (isWindows) {
476
- return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
477
- }
478
- return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; });
479
- };
480
- const listProcessesWithMemoryUsage$2 = async rootPid => {
481
- const module = await getModule();
482
- return module.listProcessesWithMemoryUsage(rootPid);
483
- };
484
-
485
- const commandMap = {
486
- 'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
487
- 'ProcessId.getMainProcessId': getMainProcessId,
488
- 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2
489
- // 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
490
143
  };
491
144
 
492
145
  const main = async () => {
493
- registerCommands(commandMap);
494
146
  await listen();
495
147
  };
496
148
 
497
149
  main();
498
150
 
151
+ const createPidMap = async () => {
152
+ return MainProcess.invoke('CreatePidMap.createPidMap');
153
+ };
154
+
155
+ const processNamePatterns = [{
156
+ matches: cmd => cmd.includes('--type=zygote'),
157
+ name: 'zygote'
158
+ }, {
159
+ matches: cmd => cmd.includes('--type=gpu-process'),
160
+ name: 'gpu-process'
161
+ }, {
162
+ matches: cmd => cmd.includes('extensionHostMain.js'),
163
+ name: 'extension-host'
164
+ }, {
165
+ matches: cmd => cmd.includes('ptyHostMain.js'),
166
+ name: 'pty-host'
167
+ }, {
168
+ matches: cmd => cmd.includes('--lvce-window-kind=process-explorer'),
169
+ name: 'process-explorer'
170
+ }];
171
+ const fallbackProcessNamePatterns = [{
172
+ matches: cmd => cmd.includes('--type=renderer'),
173
+ name: 'renderer'
174
+ }, {
175
+ matches: cmd => cmd.includes('--type=utility'),
176
+ name: 'utility'
177
+ }, {
178
+ matches: cmd => cmd.includes('tsserver.js'),
179
+ name: 'tsserver.js'
180
+ }, {
181
+ matches: cmd => cmd.includes('typingsInstaller.js'),
182
+ name: 'typingsInstaller.js'
183
+ }, {
184
+ matches: cmd => cmd.includes('extensionHostHelperProcessMain.js'),
185
+ name: 'extension-host-helper-process'
186
+ }, {
187
+ matches: cmd => cmd.includes('/bin/rg') || cmd.includes('rg.exe'),
188
+ name: 'ripgrep'
189
+ }, {
190
+ matches: cmd => cmd.startsWith('bash'),
191
+ name: 'bash'
192
+ }, {
193
+ matches: cmd => cmd.startsWith('/opt/sublime_text/sublime_text '),
194
+ name: 'sublime-text'
195
+ }, {
196
+ matches: cmd => cmd.includes('\\conhost.exe'),
197
+ name: 'conhost.exe'
198
+ }];
199
+ const getPatternName = cmd => {
200
+ return processNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
201
+ };
202
+ const getFallbackPatternName = cmd => {
203
+ return fallbackProcessNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
204
+ };
499
205
  const getName = (pid, cmd, rootPid, pidMap) => {
500
206
  number(pid);
501
207
  string(cmd);
@@ -504,52 +210,18 @@ const getName = (pid, cmd, rootPid, pidMap) => {
504
210
  if (pid === rootPid) {
505
211
  return 'main';
506
212
  }
507
- if (cmd.includes('--type=zygote')) {
508
- return 'zygote';
509
- }
510
- if (cmd.includes('--type=gpu-process')) {
511
- return 'gpu-process';
512
- }
513
- if (cmd.includes('extensionHostMain.js')) {
514
- return 'extension-host';
515
- }
516
- if (cmd.includes('ptyHostMain.js')) {
517
- return 'pty-host';
518
- }
519
- if (cmd.includes('--lvce-window-kind=process-explorer')) {
520
- return 'process-explorer';
213
+ const patternName = getPatternName(cmd);
214
+ if (patternName) {
215
+ return patternName;
521
216
  }
522
217
  if (pid in pidMap) {
523
- return pidMap[pid] || `<unknown>`;
524
- }
525
- if (cmd.includes('--type=renderer')) {
526
- return `renderer`;
527
- }
528
- if (cmd.includes('--type=utility')) {
529
- return 'utility';
530
- }
531
- if (cmd.includes('tsserver.js')) {
532
- return 'tsserver.js';
218
+ return pidMap[pid] || '<unknown>';
533
219
  }
534
- if (cmd.includes('typingsInstaller.js')) {
535
- return 'typingsInstaller.js';
220
+ const fallbackPatternName = getFallbackPatternName(cmd);
221
+ if (fallbackPatternName) {
222
+ return fallbackPatternName;
536
223
  }
537
- if (cmd.includes('extensionHostHelperProcessMain.js')) {
538
- return 'extension-host-helper-process';
539
- }
540
- if (cmd.includes('/bin/rg') || cmd.includes('rg.exe')) {
541
- return 'ripgrep';
542
- }
543
- if (cmd.startsWith('bash')) {
544
- return 'bash';
545
- }
546
- if (cmd.startsWith(`/opt/sublime_text/sublime_text `)) {
547
- return 'sublime-text';
548
- }
549
- if (cmd.includes('\\conhost.exe')) {
550
- return 'conhost.exe';
551
- }
552
- return `${cmd}`;
224
+ return cmd;
553
225
  };
554
226
 
555
227
  const ENOENT = 'ENOENT';
@@ -557,7 +229,7 @@ const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
557
229
  const ESRCH = 'ESRCH';
558
230
 
559
231
  const isDlOpenError = error => {
560
- return error && error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
232
+ return error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
561
233
  };
562
234
 
563
235
  const loadWindowProcessTree = async () => {
@@ -572,30 +244,14 @@ const loadWindowProcessTree = async () => {
572
244
  };
573
245
 
574
246
  const withResolvers = () => {
575
- /**
576
- * @type {any}
577
- */
578
- let _resolve;
579
- /**
580
- * @type {any}
581
- */
582
- let _reject;
583
- const promise = new Promise((resolve, reject) => {
584
- _resolve = resolve;
585
- _reject = reject;
586
- });
587
- return {
588
- resolve: _resolve,
589
- reject: _reject,
590
- promise
591
- };
247
+ return Promise.withResolvers();
592
248
  };
593
249
 
594
250
  const getProcessList = async (rootPid, flags) => {
595
251
  const WindowsProcessTree = await loadWindowProcessTree();
596
252
  const {
597
- resolve,
598
- promise
253
+ promise,
254
+ resolve
599
255
  } = withResolvers();
600
256
  WindowsProcessTree.getProcessList(rootPid, resolve, flags);
601
257
  return promise;
@@ -603,20 +259,19 @@ const getProcessList = async (rootPid, flags) => {
603
259
  const addCpuUsage = async processList => {
604
260
  const WindowsProcessTree = await loadWindowProcessTree();
605
261
  const {
606
- resolve,
607
- promise
262
+ promise,
263
+ resolve
608
264
  } = withResolvers();
609
- WindowsProcessTree.getProcessCpuUsage(processList, resolve);
265
+ const mutableProcessList = processList.map(process => ({
266
+ ...process
267
+ }));
268
+ WindowsProcessTree.getProcessCpuUsage(mutableProcessList, resolve);
610
269
  return promise;
611
270
  };
612
271
 
613
272
  const Memory = 1;
614
273
  const CommandLine = 2;
615
274
 
616
- const createPidMap = async () => {
617
- return invoke('CreatePidMap.createPidMap');
618
- };
619
-
620
275
  // listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
621
276
 
622
277
  /**
@@ -626,18 +281,15 @@ const createPidMap = async () => {
626
281
  */
627
282
  const toResultItem = (item, rootPid, pidMap) => {
628
283
  return {
284
+ cmd: item.commandLine,
285
+ memory: item.memory,
629
286
  name: getName(item.pid, item.commandLine, rootPid, pidMap),
630
287
  pid: item.pid,
631
- ppid: item.ppid,
632
- memory: item.memory,
633
- cmd: item.commandLine
288
+ ppid: item.ppid
634
289
  };
635
290
  };
636
291
  const toResult = (completeProcessList, rootPid, pidMap) => {
637
- const results = [];
638
- for (const item of completeProcessList) {
639
- results.push(toResultItem(item, rootPid, pidMap));
640
- }
292
+ const results = Array.from(completeProcessList, item => toResultItem(item, rootPid, pidMap));
641
293
  return results;
642
294
  };
643
295
  const listProcessesWithMemoryUsage$1 = async rootPid => {
@@ -699,7 +351,7 @@ const parseMemory = content => {
699
351
 
700
352
  const getContent = async pid => {
701
353
  try {
702
- const filePath = join('/proc', `${pid}`, 'statm');
354
+ const filePath = join('/proc', String(pid), 'statm');
703
355
  const content = await readFile(filePath, Utf8);
704
356
  return content;
705
357
  } catch (error) {
@@ -762,17 +414,36 @@ const splitLines = lines => {
762
414
 
763
415
  // parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
764
416
 
765
- const PID_CMD = /^\s*(\d+)\s+(\d+)\s+([\d.]+)\s+([\d.]+)\s+(.+)$/s;
417
+ const isSpace = character => {
418
+ return character === ' ' || character === '\t';
419
+ };
420
+ const readField = (line, startIndex) => {
421
+ let start = startIndex;
422
+ while (start < line.length && isSpace(line[start])) {
423
+ start++;
424
+ }
425
+ let end = start;
426
+ while (end < line.length && !isSpace(line[end])) {
427
+ end++;
428
+ }
429
+ return {
430
+ nextIndex: end,
431
+ value: line.slice(start, end)
432
+ };
433
+ };
766
434
  const parsePsOutputLine = line => {
767
435
  string(line);
768
- const matches = PID_CMD.exec(line.trim());
769
- if (matches && matches.length === 6) {
436
+ const trimmedLine = line.trim();
437
+ const pidField = readField(trimmedLine, 0);
438
+ const ppidField = readField(trimmedLine, pidField.nextIndex);
439
+ const loadField = readField(trimmedLine, ppidField.nextIndex);
440
+ const memoryField = readField(trimmedLine, loadField.nextIndex);
441
+ const cmd = trimmedLine.slice(memoryField.nextIndex).trim();
442
+ if (pidField.value && ppidField.value && loadField.value && memoryField.value && cmd) {
770
443
  return {
771
- pid: Number.parseInt(matches[1]),
772
- ppid: Number.parseInt(matches[2]),
773
- cmd: matches[5]
774
- // load: parseInt(matches[3]),
775
- // mem: parseInt(matches[4]),
444
+ cmd,
445
+ pid: Number.parseInt(pidField.value),
446
+ ppid: Number.parseInt(ppidField.value)
776
447
  };
777
448
  }
778
449
  throw new Error(`line could not be parsed: ${line}`);
@@ -791,9 +462,9 @@ const parsePsOutput = (stdout, rootPid, pidMap) => {
791
462
  const parsedLines = lines.map(parsePsOutputLine);
792
463
  for (const parsedLine of parsedLines) {
793
464
  const {
465
+ cmd,
794
466
  pid,
795
- ppid,
796
- cmd
467
+ ppid
797
468
  } = parsedLine;
798
469
  const depth = pid === rootPid ? 1 : depthMap[ppid];
799
470
  if (!depth) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/process-explorer",
3
- "version": "2.4.0",
3
+ "version": "3.1.0",
4
4
  "description": "Process Explorer",
5
5
  "main": "dist/index.js",
6
6
  "bin": "bin/processExplorer.js",
@@ -18,57 +18,12 @@
18
18
  "node": ">=18"
19
19
  },
20
20
  "dependencies": {
21
- "@lvce-editor/assert": "^1.3.0",
22
- "@lvce-editor/ipc": "^13.7.0",
23
- "@lvce-editor/json-rpc": "^5.4.0",
24
- "@lvce-editor/verror": "^1.6.0"
21
+ "@lvce-editor/assert": "^1.5.1",
22
+ "@lvce-editor/rpc": "^6.4.0",
23
+ "@lvce-editor/rpc-registry": "^9.27.0",
24
+ "@lvce-editor/verror": "^1.7.0"
25
25
  },
26
26
  "optionalDependencies": {
27
- "@vscode/windows-process-tree": "^0.6.0"
28
- },
29
- "xo": {
30
- "rules": {
31
- "unicorn/filename-case": "off",
32
- "indent": "off",
33
- "semi": "off",
34
- "no-unused-vars": "off",
35
- "unicorn/numeric-separators-style": "off",
36
- "no-extra-semi": "off",
37
- "arrow-body-style": "off",
38
- "padded-blocks": "off",
39
- "capitalized-comments": "off",
40
- "padding-line-between-statements": "off",
41
- "arrow-parens": "off",
42
- "no-warning-comments": "off",
43
- "array-bracket-spacing": "off",
44
- "comma-spacing": "off",
45
- "unicorn/no-array-callback-reference": "off",
46
- "comma-dangle": "off",
47
- "operator-linebreak": "off",
48
- "no-case-declarations": "off",
49
- "no-undef": "off",
50
- "object-curly-spacing": "off",
51
- "object-shorthand": "off",
52
- "complexity": "off",
53
- "no-labels": "off",
54
- "no-multi-assign": "off",
55
- "max-params": "off",
56
- "no-bitwise": "off",
57
- "unicorn/prefer-math-trunc": "off",
58
- "no-await-in-loop": "off",
59
- "unicorn/prefer-add-event-listener": "off",
60
- "no-unused-expressions": "off",
61
- "node/prefer-global/process": "off",
62
- "unicorn/prevent-abbreviations": "off",
63
- "unicorn/no-process-exit": "off",
64
- "quotes": "off",
65
- "n/prefer-global/process": [
66
- "error",
67
- "always"
68
- ]
69
- },
70
- "ignores": [
71
- "distmin"
72
- ]
27
+ "@vscode/windows-process-tree": "^0.7.0"
73
28
  }
74
29
  }