@lvce-editor/process-explorer 3.0.0 → 3.2.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.
Files changed (2) hide show
  1. package/dist/index.js +203 -190
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,55 +1,115 @@
1
+ import { ElectronMessagePortRpcClient, WebSocketRpcParent, NodeWebSocketRpcClient, NodeWorkerRpcClient, NodeForkedProcessRpcClient, ElectronUtilityProcessRpcClient } from '@lvce-editor/rpc';
1
2
  import { object, number, string } from '@lvce-editor/assert';
2
- import { handleJsonRpcMessage, resolve, invoke as invoke$1 } from '@lvce-editor/json-rpc';
3
- import { IpcChildWithWebSocket, IpcChildWithNodeWorker, IpcChildWithNodeForkedProcess, IpcChildWithElectronUtilityProcess, IpcChildWithElectronMessagePort } from '@lvce-editor/ipc';
3
+ import { RpcId, MainProcess, set as set$2 } from '@lvce-editor/rpc-registry';
4
4
  import { VError } from '@lvce-editor/verror';
5
5
  import { readFile } from 'node:fs/promises';
6
6
  import { join } from 'node:path';
7
7
  import { execFile as execFile$1 } from 'node:child_process';
8
8
  import { promisify } from 'node:util';
9
9
 
10
- const state$1 = {
11
- commands: Object.create(null)
10
+ const state = {
11
+ commandMap: {}
12
12
  };
13
- const registerCommand = (key, fn) => {
14
- state$1.commands[key] = fn;
13
+
14
+ const get = () => {
15
+ return state.commandMap;
15
16
  };
16
- const registerCommands = commandMap => {
17
- for (const [key, value] of Object.entries(commandMap)) {
18
- registerCommand(key, value);
19
- }
17
+
18
+ const requiresSocket = () => {
19
+ return false;
20
20
  };
21
- const getCommand = key => {
22
- return state$1.commands[key];
21
+
22
+ const createMessagePortRpc = async (create, messagePort) => {
23
+ return create({
24
+ commandMap: get(),
25
+ messagePort,
26
+ requiresSocket: requiresSocket
27
+ });
23
28
  };
24
29
 
25
- const execute = (command, ...args) => {
26
- const fn = getCommand(command);
27
- if (!fn) {
28
- throw new Error(`Command not found ${command}`);
30
+ const setRpc = (rpc, rpcId) => {
31
+ if (typeof rpcId !== 'number') {
32
+ return;
29
33
  }
30
- return fn(...args);
34
+ if (rpcId === RpcId.MainProcess) {
35
+ MainProcess.set(rpc);
36
+ return;
37
+ }
38
+ set$2(rpcId, rpc);
31
39
  };
32
40
 
33
- const preparePrettyError = error => {
34
- return error;
41
+ const handleMessagePort = async (messagePort, rpcId) => {
42
+ object(messagePort);
43
+ const rpc = await createMessagePortRpc(ElectronMessagePortRpcClient.create, messagePort);
44
+ setRpc(rpc, rpcId);
35
45
  };
36
- const logError = error => {
37
- console.error(error);
46
+
47
+ const handleElectronMessagePort = async (messagePort, rpcId) => {
48
+ await handleMessagePort(messagePort, rpcId);
38
49
  };
39
- const requiresSocket = () => {
40
- return false;
50
+
51
+ const createSocketRpc = async (create, webSocket) => {
52
+ return create({
53
+ commandMap: get(),
54
+ webSocket
55
+ });
56
+ };
57
+
58
+ const handleSocket = async (webSocket, rpcId) => {
59
+ object(webSocket);
60
+ const rpc = await createSocketRpc(WebSocketRpcParent.create, webSocket);
61
+ setRpc(rpc, rpcId);
41
62
  };
42
- const handleMessage = event => {
43
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
63
+
64
+ const createWebSocketRpc = async (create, handle, request) => {
65
+ return create({
66
+ commandMap: get(),
67
+ handle,
68
+ request,
69
+ requiresSocket: requiresSocket
70
+ });
71
+ };
72
+ const handleWebSocket = async (handle, request, rpcId) => {
73
+ object(handle);
74
+ object(request);
75
+ const rpc = await createWebSocketRpc(NodeWebSocketRpcClient.create, handle, request);
76
+ setRpc(rpc, rpcId);
44
77
  };
45
78
 
46
- const handleIpc = ipc => {
47
- if ('addEventListener' in ipc) {
48
- ipc.addEventListener('message', handleMessage);
49
- } else {
50
- // deprecated
51
- ipc.on('message', handleMessage);
79
+ const isWindows = process.platform === 'win32';
80
+
81
+ const getModule$1 = async () => {
82
+ if (isWindows) {
83
+ return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
52
84
  }
85
+ return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; });
86
+ };
87
+
88
+ const listProcessesWithMemoryUsage$2 = async rootPid => {
89
+ const module = await getModule$1();
90
+ return module.listProcessesWithMemoryUsage(rootPid);
91
+ };
92
+
93
+ const getMainProcessId = () => {
94
+ return process.ppid;
95
+ };
96
+
97
+ const commandMap = {
98
+ 'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
99
+ 'HandleMessagePort.handleMessagePort': handleMessagePort,
100
+ 'HandleSocket.handleSocket': handleSocket,
101
+ 'HandleWebSocket.handleWebSocket': handleWebSocket,
102
+ 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2,
103
+ 'ProcessId.getMainProcessId': getMainProcessId
104
+ // 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
105
+ };
106
+
107
+ const set$1 = commandMap => {
108
+ state.commandMap = commandMap;
109
+ };
110
+
111
+ const set = commandMap => {
112
+ set$1(commandMap);
53
113
  };
54
114
 
55
115
  const NodeWorker = 1;
@@ -73,18 +133,18 @@ const Auto = () => {
73
133
  throw new Error(`[shared-process] unknown ipc type`);
74
134
  };
75
135
 
76
- const getModule$1 = method => {
136
+ const getModule = method => {
77
137
  switch (method) {
78
138
  case ElectronMessagePort:
79
- return IpcChildWithElectronMessagePort;
139
+ return ElectronMessagePortRpcClient.create;
80
140
  case ElectronUtilityProcess:
81
- return IpcChildWithElectronUtilityProcess;
141
+ return ElectronUtilityProcessRpcClient.create;
82
142
  case NodeForkedProcess:
83
- return IpcChildWithNodeForkedProcess;
143
+ return NodeForkedProcessRpcClient.create;
84
144
  case NodeWorker:
85
- return IpcChildWithNodeWorker;
145
+ return NodeWorkerRpcClient.create;
86
146
  case WebSocket:
87
- return IpcChildWithWebSocket;
147
+ return NodeWebSocketRpcClient.create;
88
148
  default:
89
149
  throw new Error('unexpected ipc type');
90
150
  }
@@ -94,99 +154,75 @@ const listen$1 = async ({
94
154
  method,
95
155
  ...params
96
156
  }) => {
97
- const module = getModule$1(method);
98
- // @ts-ignore
99
- const rawIpc = module.listen(params);
100
- // @ts-ignore
101
- if (module.signal) {
102
- // @ts-ignore
103
- module.signal(rawIpc);
104
- }
105
- // @ts-ignore
106
- const ipc = module.wrap(rawIpc);
107
- return ipc;
157
+ const create = getModule(method);
158
+ const rpc = await create(params);
159
+ return rpc;
108
160
  };
109
161
 
110
- const MainProcess = -5;
111
-
112
- const state = {
113
- ipc: undefined
114
- };
115
- const invoke = (method, ...params) => {
116
- return invoke$1(state.ipc, method, ...params);
162
+ const listen = async () => {
163
+ set(commandMap);
164
+ await listen$1({
165
+ commandMap: commandMap,
166
+ method: Auto()
167
+ });
117
168
  };
118
169
 
119
- const handleElectronMessagePort = async (messagePort, ipcId) => {
120
- object(messagePort);
121
- // Assert.number(ipcId)
122
- const ipc = await listen$1({
123
- messagePort,
124
- method: ElectronMessagePort
125
- });
126
- handleIpc(ipc);
127
- if (ipcId === MainProcess) {
128
- state.ipc = ipc;
129
- }
170
+ const main = async () => {
171
+ await listen();
130
172
  };
131
173
 
132
- const isWindows = process.platform === 'win32';
174
+ main();
133
175
 
134
- const getModule = async () => {
135
- if (isWindows) {
136
- return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
137
- }
138
- return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; });
139
- };
140
- const listProcessesWithMemoryUsage$2 = async rootPid => {
141
- const module = await getModule();
142
- return module.listProcessesWithMemoryUsage(rootPid);
143
- };
176
+ const ENOENT = 'ENOENT';
177
+ const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
178
+ const ESRCH = 'ESRCH';
144
179
 
145
- const getMainProcessId = () => {
146
- return process.ppid;
180
+ const isDlOpenError = error => {
181
+ return error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
147
182
  };
148
183
 
149
- const commandMap = {
150
- 'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
151
- 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2,
152
- 'ProcessId.getMainProcessId': getMainProcessId
153
- // 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
184
+ const loadWindowProcessTree = async () => {
185
+ try {
186
+ return await import('@vscode/windows-process-tree');
187
+ } catch (error) {
188
+ if (isDlOpenError(error)) {
189
+ throw new VError(`Failed to load windows process tree: The native module "@vscode/windows-process-tree" is not compatible with this node version and must be compiled against a matching electron version using electron-rebuild`);
190
+ }
191
+ throw new VError(error, `Failed to load windows process tree`);
192
+ }
154
193
  };
155
194
 
156
- const listen = async () => {
157
- const ipc = await listen$1({
158
- method: Auto()
159
- });
160
- handleIpc(ipc);
195
+ const withResolvers = () => {
196
+ return Promise.withResolvers();
161
197
  };
162
198
 
163
- const main = async () => {
164
- registerCommands(commandMap);
165
- await listen();
199
+ const addCpuUsage = async processList => {
200
+ const WindowsProcessTree = await loadWindowProcessTree();
201
+ const {
202
+ promise,
203
+ resolve
204
+ } = withResolvers();
205
+ const mutableProcessList = processList.map(process => ({
206
+ ...process
207
+ }));
208
+ WindowsProcessTree.getProcessCpuUsage(mutableProcessList, resolve);
209
+ return promise;
166
210
  };
167
211
 
168
- main();
169
-
170
212
  const createPidMap = async () => {
171
- return invoke('CreatePidMap.createPidMap');
213
+ return MainProcess.invoke('CreatePidMap.createPidMap');
214
+ };
215
+
216
+ const getProcessList = async (rootPid, flags) => {
217
+ const WindowsProcessTree = await loadWindowProcessTree();
218
+ const {
219
+ promise,
220
+ resolve
221
+ } = withResolvers();
222
+ WindowsProcessTree.getProcessList(rootPid, resolve, flags);
223
+ return promise;
172
224
  };
173
225
 
174
- const processNamePatterns = [{
175
- matches: cmd => cmd.includes('--type=zygote'),
176
- name: 'zygote'
177
- }, {
178
- matches: cmd => cmd.includes('--type=gpu-process'),
179
- name: 'gpu-process'
180
- }, {
181
- matches: cmd => cmd.includes('extensionHostMain.js'),
182
- name: 'extension-host'
183
- }, {
184
- matches: cmd => cmd.includes('ptyHostMain.js'),
185
- name: 'pty-host'
186
- }, {
187
- matches: cmd => cmd.includes('--lvce-window-kind=process-explorer'),
188
- name: 'process-explorer'
189
- }];
190
226
  const fallbackProcessNamePatterns = [{
191
227
  matches: cmd => cmd.includes('--type=renderer'),
192
228
  name: 'renderer'
@@ -215,12 +251,32 @@ const fallbackProcessNamePatterns = [{
215
251
  matches: cmd => cmd.includes('\\conhost.exe'),
216
252
  name: 'conhost.exe'
217
253
  }];
218
- const getPatternName = cmd => {
219
- return processNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
220
- };
254
+
221
255
  const getFallbackPatternName = cmd => {
222
256
  return fallbackProcessNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
223
257
  };
258
+
259
+ const processNamePatterns = [{
260
+ matches: cmd => cmd.includes('--type=zygote'),
261
+ name: 'zygote'
262
+ }, {
263
+ matches: cmd => cmd.includes('--type=gpu-process'),
264
+ name: 'gpu-process'
265
+ }, {
266
+ matches: cmd => cmd.includes('extensionHostMain.js'),
267
+ name: 'extension-host'
268
+ }, {
269
+ matches: cmd => cmd.includes('ptyHostMain.js'),
270
+ name: 'pty-host'
271
+ }, {
272
+ matches: cmd => cmd.includes('--lvce-window-kind=process-explorer'),
273
+ name: 'process-explorer'
274
+ }];
275
+
276
+ const getPatternName = cmd => {
277
+ return processNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
278
+ };
279
+
224
280
  const getName = (pid, cmd, rootPid, pidMap) => {
225
281
  number(pid);
226
282
  string(cmd);
@@ -243,61 +299,6 @@ const getName = (pid, cmd, rootPid, pidMap) => {
243
299
  return cmd;
244
300
  };
245
301
 
246
- const ENOENT = 'ENOENT';
247
- const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
248
- const ESRCH = 'ESRCH';
249
-
250
- const isDlOpenError = error => {
251
- return error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
252
- };
253
-
254
- const loadWindowProcessTree = async () => {
255
- try {
256
- return await import('@vscode/windows-process-tree');
257
- } catch (error) {
258
- if (isDlOpenError(error)) {
259
- throw new VError(`Failed to load windows process tree: The native module "@vscode/windows-process-tree" is not compatible with this node version and must be compiled against a matching electron version using electron-rebuild`);
260
- }
261
- throw new VError(error, `Failed to load windows process tree`);
262
- }
263
- };
264
-
265
- const withResolvers = () => {
266
- return Promise.withResolvers();
267
- };
268
-
269
- const getProcessList = async (rootPid, flags) => {
270
- const WindowsProcessTree = await loadWindowProcessTree();
271
- const {
272
- promise,
273
- resolve
274
- } = withResolvers();
275
- WindowsProcessTree.getProcessList(rootPid, resolve, flags);
276
- return promise;
277
- };
278
- const addCpuUsage = async processList => {
279
- const WindowsProcessTree = await loadWindowProcessTree();
280
- const {
281
- promise,
282
- resolve
283
- } = withResolvers();
284
- const mutableProcessList = processList.map(process => ({
285
- ...process
286
- }));
287
- WindowsProcessTree.getProcessCpuUsage(mutableProcessList, resolve);
288
- return promise;
289
- };
290
-
291
- const Memory = 1;
292
- const CommandLine = 2;
293
-
294
- // listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
295
-
296
- /**
297
- * @param {import('@vscode/windows-process-tree').IProcessCpuInfo} item
298
- * @param {number} rootPid
299
- * @param {object} pidMap
300
- */
301
302
  const toResultItem = (item, rootPid, pidMap) => {
302
303
  return {
303
304
  cmd: item.commandLine,
@@ -307,10 +308,17 @@ const toResultItem = (item, rootPid, pidMap) => {
307
308
  ppid: item.ppid
308
309
  };
309
310
  };
311
+
310
312
  const toResult = (completeProcessList, rootPid, pidMap) => {
311
313
  const results = Array.from(completeProcessList, item => toResultItem(item, rootPid, pidMap));
312
314
  return results;
313
315
  };
316
+
317
+ const Memory = 1;
318
+ const CommandLine = 2;
319
+
320
+ // listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
321
+
314
322
  const listProcessesWithMemoryUsage$1 = async rootPid => {
315
323
  try {
316
324
  const processList = await getProcessList(rootPid, CommandLine | Memory);
@@ -334,13 +342,14 @@ const ListProcessesWithMemoryUsageWindows = {
334
342
 
335
343
  const Utf8 = 'utf8';
336
344
 
345
+ const isEnoentErrorLinux = error => {
346
+ return error.code === ENOENT;
347
+ };
348
+
337
349
  const isEnoentErrorWindows = error => {
338
350
  return error && error.message && error.message.includes('The system cannot find the path specified.');
339
351
  };
340
352
 
341
- const isEnoentErrorLinux = error => {
342
- return error.code === ENOENT;
343
- };
344
353
  const isEnoentError = error => {
345
354
  if (!error) {
346
355
  return false;
@@ -352,6 +361,19 @@ const isEsrchError = error => {
352
361
  return error && error.code === ESRCH;
353
362
  };
354
363
 
364
+ const getContent = async pid => {
365
+ try {
366
+ const filePath = join('/proc', String(pid), 'statm');
367
+ const content = await readFile(filePath, Utf8);
368
+ return content;
369
+ } catch (error) {
370
+ if (isEnoentError(error) || isEsrchError(error)) {
371
+ return '';
372
+ }
373
+ throw error;
374
+ }
375
+ };
376
+
355
377
  const isMacOs = process.platform === 'darwin';
356
378
 
357
379
  const EmptyString = '';
@@ -368,18 +390,6 @@ const parseMemory = content => {
368
390
  return memory;
369
391
  };
370
392
 
371
- const getContent = async pid => {
372
- try {
373
- const filePath = join('/proc', String(pid), 'statm');
374
- const content = await readFile(filePath, Utf8);
375
- return content;
376
- } catch (error) {
377
- if (isEnoentError(error) || isEsrchError(error)) {
378
- return '';
379
- }
380
- throw error;
381
- }
382
- };
383
393
  const getAccurateMemoryUsage = async pid => {
384
394
  try {
385
395
  number(pid);
@@ -427,15 +437,10 @@ const hasPositiveMemoryUsage = process => {
427
437
  return process.memory >= 0;
428
438
  };
429
439
 
430
- const splitLines = lines => {
431
- return lines.split(NewLine);
432
- };
433
-
434
- // parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
435
-
436
440
  const isSpace = character => {
437
441
  return character === ' ' || character === '\t';
438
442
  };
443
+
439
444
  const readField = (line, startIndex) => {
440
445
  let start = startIndex;
441
446
  while (start < line.length && isSpace(line[start])) {
@@ -450,6 +455,7 @@ const readField = (line, startIndex) => {
450
455
  value: line.slice(start, end)
451
456
  };
452
457
  };
458
+
453
459
  const parsePsOutputLine = line => {
454
460
  string(line);
455
461
  const trimmedLine = line.trim();
@@ -467,6 +473,13 @@ const parsePsOutputLine = line => {
467
473
  }
468
474
  throw new Error(`line could not be parsed: ${line}`);
469
475
  };
476
+
477
+ const splitLines = lines => {
478
+ return lines.split(NewLine);
479
+ };
480
+
481
+ // parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
482
+
470
483
  const parsePsOutput = (stdout, rootPid, pidMap) => {
471
484
  string(stdout);
472
485
  number(rootPid);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/process-explorer",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "Process Explorer",
5
5
  "main": "dist/index.js",
6
6
  "bin": "bin/processExplorer.js",
@@ -19,8 +19,8 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@lvce-editor/assert": "^1.5.1",
22
- "@lvce-editor/ipc": "^16.0.0",
23
- "@lvce-editor/json-rpc": "^8.0.0",
22
+ "@lvce-editor/rpc": "^6.4.0",
23
+ "@lvce-editor/rpc-registry": "^9.28.0",
24
24
  "@lvce-editor/verror": "^1.7.0"
25
25
  },
26
26
  "optionalDependencies": {