@lvce-editor/process-explorer 2.1.0 → 2.3.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.
- package/dist/index.js +211 -284
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IpcChildWithWebSocket, IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithNodeWorker, IpcChildWithNodeForkedProcess } from '@lvce-editor/ipc';
|
|
2
|
-
import { object, number
|
|
2
|
+
import { object, number, string } from '@lvce-editor/assert';
|
|
3
3
|
import { VError } from '@lvce-editor/verror';
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { join } from 'node:path';
|
|
@@ -7,104 +7,47 @@ import { execFile as execFile$1 } from 'node:child_process';
|
|
|
7
7
|
import { promisify } from 'node:util';
|
|
8
8
|
|
|
9
9
|
const Two = '2.0';
|
|
10
|
-
|
|
11
|
-
class AssertionError extends Error {
|
|
12
|
-
constructor(message) {
|
|
13
|
-
super(message);
|
|
14
|
-
this.name = 'AssertionError';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
const getType = value => {
|
|
18
|
-
switch (typeof value) {
|
|
19
|
-
case 'number':
|
|
20
|
-
return 'number';
|
|
21
|
-
case 'function':
|
|
22
|
-
return 'function';
|
|
23
|
-
case 'string':
|
|
24
|
-
return 'string';
|
|
25
|
-
case 'object':
|
|
26
|
-
if (value === null) {
|
|
27
|
-
return 'null';
|
|
28
|
-
}
|
|
29
|
-
if (Array.isArray(value)) {
|
|
30
|
-
return 'array';
|
|
31
|
-
}
|
|
32
|
-
return 'object';
|
|
33
|
-
case 'boolean':
|
|
34
|
-
return 'boolean';
|
|
35
|
-
default:
|
|
36
|
-
return 'unknown';
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
const number = value => {
|
|
40
|
-
const type = getType(value);
|
|
41
|
-
if (type !== 'number') {
|
|
42
|
-
throw new AssertionError('expected value to be of type number');
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const state$1$1 = {
|
|
10
|
+
const state$2 = {
|
|
47
11
|
callbacks: Object.create(null)
|
|
48
12
|
};
|
|
49
13
|
const set = (id, fn) => {
|
|
50
|
-
state$
|
|
14
|
+
state$2.callbacks[id] = fn;
|
|
51
15
|
};
|
|
52
16
|
const get = id => {
|
|
53
|
-
return state$
|
|
17
|
+
return state$2.callbacks[id];
|
|
54
18
|
};
|
|
55
19
|
const remove = id => {
|
|
56
|
-
delete state$
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const state$2 = {
|
|
60
|
-
id: 0
|
|
20
|
+
delete state$2.callbacks[id];
|
|
61
21
|
};
|
|
22
|
+
let id = 0;
|
|
62
23
|
const create$3 = () => {
|
|
63
|
-
return ++
|
|
24
|
+
return ++id;
|
|
64
25
|
};
|
|
65
|
-
|
|
66
26
|
const warn = (...args) => {
|
|
67
27
|
console.warn(...args);
|
|
68
28
|
};
|
|
69
|
-
|
|
70
|
-
const withResolvers$1 = () => {
|
|
71
|
-
/**
|
|
72
|
-
* @type {any}
|
|
73
|
-
*/
|
|
74
|
-
let _resolve;
|
|
75
|
-
const promise = new Promise(resolve => {
|
|
76
|
-
_resolve = resolve;
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
resolve: _resolve,
|
|
80
|
-
promise
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
|
|
84
29
|
const registerPromise = () => {
|
|
85
30
|
const id = create$3();
|
|
86
31
|
const {
|
|
87
32
|
resolve,
|
|
88
33
|
promise
|
|
89
|
-
} = withResolvers
|
|
34
|
+
} = Promise.withResolvers();
|
|
90
35
|
set(id, resolve);
|
|
91
36
|
return {
|
|
92
37
|
id,
|
|
93
38
|
promise
|
|
94
39
|
};
|
|
95
40
|
};
|
|
96
|
-
const resolve = (id,
|
|
97
|
-
number(id);
|
|
41
|
+
const resolve = (id, response) => {
|
|
98
42
|
const fn = get(id);
|
|
99
43
|
if (!fn) {
|
|
100
|
-
console.log(
|
|
44
|
+
console.log(response);
|
|
101
45
|
warn(`callback ${id} may already be disposed`);
|
|
102
46
|
return;
|
|
103
47
|
}
|
|
104
|
-
fn(
|
|
48
|
+
fn(response);
|
|
105
49
|
remove(id);
|
|
106
50
|
};
|
|
107
|
-
|
|
108
51
|
const create$2 = (method, params) => {
|
|
109
52
|
const {
|
|
110
53
|
id,
|
|
@@ -121,21 +64,17 @@ const create$2 = (method, params) => {
|
|
|
121
64
|
promise
|
|
122
65
|
};
|
|
123
66
|
};
|
|
124
|
-
|
|
125
67
|
class JsonRpcError extends Error {
|
|
126
68
|
constructor(message) {
|
|
127
69
|
super(message);
|
|
128
70
|
this.name = 'JsonRpcError';
|
|
129
71
|
}
|
|
130
72
|
}
|
|
131
|
-
|
|
132
73
|
const NewLine$1 = '\n';
|
|
133
|
-
|
|
134
74
|
const DomException = 'DOMException';
|
|
135
75
|
const ReferenceError$1 = 'ReferenceError';
|
|
136
76
|
const SyntaxError$1 = 'SyntaxError';
|
|
137
77
|
const TypeError$1 = 'TypeError';
|
|
138
|
-
|
|
139
78
|
const getErrorConstructor = (message, type) => {
|
|
140
79
|
if (type) {
|
|
141
80
|
switch (type) {
|
|
@@ -162,7 +101,6 @@ const getErrorConstructor = (message, type) => {
|
|
|
162
101
|
}
|
|
163
102
|
return Error;
|
|
164
103
|
};
|
|
165
|
-
|
|
166
104
|
const constructError = (message, type, name) => {
|
|
167
105
|
const ErrorConstructor = getErrorConstructor(message, type);
|
|
168
106
|
if (ErrorConstructor === DOMException && name) {
|
|
@@ -177,11 +115,9 @@ const constructError = (message, type, name) => {
|
|
|
177
115
|
}
|
|
178
116
|
return new ErrorConstructor(message);
|
|
179
117
|
};
|
|
180
|
-
|
|
181
118
|
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
182
119
|
return string.indexOf(NewLine$1, startIndex);
|
|
183
120
|
};
|
|
184
|
-
|
|
185
121
|
const getParentStack = error => {
|
|
186
122
|
let parentStack = error.stack || error.data || error.message || '';
|
|
187
123
|
if (parentStack.startsWith(' at')) {
|
|
@@ -189,18 +125,14 @@ const getParentStack = error => {
|
|
|
189
125
|
}
|
|
190
126
|
return parentStack;
|
|
191
127
|
};
|
|
192
|
-
|
|
193
128
|
const joinLines = lines => {
|
|
194
129
|
return lines.join(NewLine$1);
|
|
195
130
|
};
|
|
196
|
-
|
|
197
131
|
const MethodNotFound = -32601;
|
|
198
132
|
const Custom = -32001;
|
|
199
|
-
|
|
200
133
|
const splitLines$1 = lines => {
|
|
201
134
|
return lines.split(NewLine$1);
|
|
202
135
|
};
|
|
203
|
-
|
|
204
136
|
const restoreJsonRpcError = error => {
|
|
205
137
|
if (error && error instanceof Error) {
|
|
206
138
|
return error;
|
|
@@ -253,7 +185,6 @@ const restoreJsonRpcError = error => {
|
|
|
253
185
|
}
|
|
254
186
|
return new Error(`JsonRpc Error: ${error}`);
|
|
255
187
|
};
|
|
256
|
-
|
|
257
188
|
const unwrapJsonRpcResult = responseMessage => {
|
|
258
189
|
if ('error' in responseMessage) {
|
|
259
190
|
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
@@ -264,17 +195,16 @@ const unwrapJsonRpcResult = responseMessage => {
|
|
|
264
195
|
}
|
|
265
196
|
throw new JsonRpcError('unexpected response message');
|
|
266
197
|
};
|
|
267
|
-
|
|
268
|
-
const create$1 = (message, error) => {
|
|
269
|
-
return {
|
|
270
|
-
jsonrpc: Two,
|
|
271
|
-
id: message.id,
|
|
272
|
-
error
|
|
273
|
-
};
|
|
274
|
-
};
|
|
275
|
-
|
|
276
198
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
277
|
-
|
|
199
|
+
const getErrorType = prettyError => {
|
|
200
|
+
if (prettyError && prettyError.type) {
|
|
201
|
+
return prettyError.type;
|
|
202
|
+
}
|
|
203
|
+
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
|
|
204
|
+
return prettyError.constructor.name;
|
|
205
|
+
}
|
|
206
|
+
return undefined;
|
|
207
|
+
};
|
|
278
208
|
const getErrorProperty = (error, prettyError) => {
|
|
279
209
|
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
280
210
|
return {
|
|
@@ -289,18 +219,25 @@ const getErrorProperty = (error, prettyError) => {
|
|
|
289
219
|
data: {
|
|
290
220
|
stack: prettyError.stack,
|
|
291
221
|
codeFrame: prettyError.codeFrame,
|
|
292
|
-
type: prettyError
|
|
293
|
-
code: prettyError.code
|
|
222
|
+
type: getErrorType(prettyError),
|
|
223
|
+
code: prettyError.code,
|
|
224
|
+
name: prettyError.name
|
|
294
225
|
}
|
|
295
226
|
};
|
|
296
227
|
};
|
|
228
|
+
const create$1 = (message, error) => {
|
|
229
|
+
return {
|
|
230
|
+
jsonrpc: Two,
|
|
231
|
+
id: message.id,
|
|
232
|
+
error
|
|
233
|
+
};
|
|
234
|
+
};
|
|
297
235
|
const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
298
236
|
const prettyError = preparePrettyError(error);
|
|
299
237
|
logError(error, prettyError);
|
|
300
238
|
const errorProperty = getErrorProperty(error, prettyError);
|
|
301
239
|
return create$1(message, errorProperty);
|
|
302
240
|
};
|
|
303
|
-
|
|
304
241
|
const create = (message, result) => {
|
|
305
242
|
return {
|
|
306
243
|
jsonrpc: Two,
|
|
@@ -308,12 +245,10 @@ const create = (message, result) => {
|
|
|
308
245
|
result: result ?? null
|
|
309
246
|
};
|
|
310
247
|
};
|
|
311
|
-
|
|
312
248
|
const getSuccessResponse = (message, result) => {
|
|
313
249
|
const resultProperty = result ?? null;
|
|
314
250
|
return create(message, resultProperty);
|
|
315
251
|
};
|
|
316
|
-
|
|
317
252
|
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
318
253
|
try {
|
|
319
254
|
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
@@ -322,7 +257,6 @@ const getResponse = async (message, ipc, execute, preparePrettyError, logError,
|
|
|
322
257
|
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
323
258
|
}
|
|
324
259
|
};
|
|
325
|
-
|
|
326
260
|
const defaultPreparePrettyError = error => {
|
|
327
261
|
return error;
|
|
328
262
|
};
|
|
@@ -333,32 +267,42 @@ const defaultRequiresSocket = () => {
|
|
|
333
267
|
return false;
|
|
334
268
|
};
|
|
335
269
|
const defaultResolve = resolve;
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
let execute;
|
|
340
|
-
let preparePrettyError;
|
|
341
|
-
let logError;
|
|
342
|
-
let resolve;
|
|
343
|
-
let requiresSocket;
|
|
270
|
+
|
|
271
|
+
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
272
|
+
const normalizeParams = args => {
|
|
344
273
|
if (args.length === 1) {
|
|
345
|
-
const
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
message = args[1];
|
|
356
|
-
execute = args[2];
|
|
357
|
-
resolve = args[3];
|
|
358
|
-
preparePrettyError = args[4];
|
|
359
|
-
logError = args[5];
|
|
360
|
-
requiresSocket = args[6];
|
|
274
|
+
const options = args[0];
|
|
275
|
+
return {
|
|
276
|
+
ipc: options.ipc,
|
|
277
|
+
message: options.message,
|
|
278
|
+
execute: options.execute,
|
|
279
|
+
resolve: options.resolve || defaultResolve,
|
|
280
|
+
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
281
|
+
logError: options.logError || defaultLogError,
|
|
282
|
+
requiresSocket: options.requiresSocket || defaultRequiresSocket
|
|
283
|
+
};
|
|
361
284
|
}
|
|
285
|
+
return {
|
|
286
|
+
ipc: args[0],
|
|
287
|
+
message: args[1],
|
|
288
|
+
execute: args[2],
|
|
289
|
+
resolve: args[3],
|
|
290
|
+
preparePrettyError: args[4],
|
|
291
|
+
logError: args[5],
|
|
292
|
+
requiresSocket: args[6]
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
const handleJsonRpcMessage = async (...args) => {
|
|
296
|
+
const options = normalizeParams(args);
|
|
297
|
+
const {
|
|
298
|
+
message,
|
|
299
|
+
ipc,
|
|
300
|
+
execute,
|
|
301
|
+
resolve,
|
|
302
|
+
preparePrettyError,
|
|
303
|
+
logError,
|
|
304
|
+
requiresSocket
|
|
305
|
+
} = options;
|
|
362
306
|
if ('id' in message) {
|
|
363
307
|
if ('method' in message) {
|
|
364
308
|
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
@@ -379,60 +323,58 @@ const handleJsonRpcMessage = async (...args) => {
|
|
|
379
323
|
}
|
|
380
324
|
throw new JsonRpcError('unexpected message');
|
|
381
325
|
};
|
|
382
|
-
const
|
|
326
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
383
327
|
const {
|
|
384
328
|
message,
|
|
385
329
|
promise
|
|
386
330
|
} = create$2(method, params);
|
|
387
|
-
|
|
331
|
+
{
|
|
332
|
+
ipc.send(message);
|
|
333
|
+
}
|
|
388
334
|
const responseMessage = await promise;
|
|
389
|
-
|
|
390
|
-
|
|
335
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
336
|
+
};
|
|
337
|
+
const invoke$1 = (ipc, method, ...params) => {
|
|
338
|
+
return invokeHelper(ipc, method, params);
|
|
391
339
|
};
|
|
392
340
|
|
|
393
341
|
const state$1 = {
|
|
394
|
-
commands: Object.create(null)
|
|
342
|
+
commands: Object.create(null)
|
|
395
343
|
};
|
|
396
|
-
|
|
397
344
|
const registerCommand = (key, fn) => {
|
|
398
345
|
state$1.commands[key] = fn;
|
|
399
346
|
};
|
|
400
|
-
|
|
401
|
-
const registerCommands = (commandMap) => {
|
|
347
|
+
const registerCommands = commandMap => {
|
|
402
348
|
for (const [key, value] of Object.entries(commandMap)) {
|
|
403
349
|
registerCommand(key, value);
|
|
404
350
|
}
|
|
405
351
|
};
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
return state$1.commands[key]
|
|
352
|
+
const getCommand = key => {
|
|
353
|
+
return state$1.commands[key];
|
|
409
354
|
};
|
|
410
355
|
|
|
411
356
|
const execute = (command, ...args) => {
|
|
412
357
|
const fn = getCommand(command);
|
|
413
358
|
if (!fn) {
|
|
414
|
-
throw new Error(`Command not found ${command}`)
|
|
359
|
+
throw new Error(`Command not found ${command}`);
|
|
415
360
|
}
|
|
416
|
-
return fn(...args)
|
|
361
|
+
return fn(...args);
|
|
417
362
|
};
|
|
418
363
|
|
|
419
|
-
const preparePrettyError =
|
|
420
|
-
return error
|
|
364
|
+
const preparePrettyError = error => {
|
|
365
|
+
return error;
|
|
421
366
|
};
|
|
422
|
-
|
|
423
|
-
const logError = (error) => {
|
|
367
|
+
const logError = error => {
|
|
424
368
|
console.error(error);
|
|
425
369
|
};
|
|
426
|
-
|
|
427
370
|
const requiresSocket = () => {
|
|
428
|
-
return false
|
|
371
|
+
return false;
|
|
429
372
|
};
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket)
|
|
373
|
+
const handleMessage = event => {
|
|
374
|
+
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
|
|
433
375
|
};
|
|
434
376
|
|
|
435
|
-
const handleIpc =
|
|
377
|
+
const handleIpc = ipc => {
|
|
436
378
|
if ('addEventListener' in ipc) {
|
|
437
379
|
ipc.addEventListener('message', handleMessage);
|
|
438
380
|
} else {
|
|
@@ -446,39 +388,43 @@ const NodeForkedProcess = 2;
|
|
|
446
388
|
const ElectronUtilityProcess = 3;
|
|
447
389
|
const ElectronMessagePort = 4;
|
|
448
390
|
const WebSocket = 6;
|
|
449
|
-
|
|
450
391
|
const Auto = () => {
|
|
451
|
-
const {
|
|
392
|
+
const {
|
|
393
|
+
argv
|
|
394
|
+
} = process;
|
|
452
395
|
if (argv.includes('--ipc-type=node-worker')) {
|
|
453
|
-
return NodeWorker
|
|
396
|
+
return NodeWorker;
|
|
454
397
|
}
|
|
455
398
|
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
456
|
-
return NodeForkedProcess
|
|
399
|
+
return NodeForkedProcess;
|
|
457
400
|
}
|
|
458
401
|
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
459
|
-
return ElectronUtilityProcess
|
|
402
|
+
return ElectronUtilityProcess;
|
|
460
403
|
}
|
|
461
|
-
throw new Error(`[shared-process] unknown ipc type`)
|
|
404
|
+
throw new Error(`[shared-process] unknown ipc type`);
|
|
462
405
|
};
|
|
463
406
|
|
|
464
|
-
const getModule$1 =
|
|
407
|
+
const getModule$1 = method => {
|
|
465
408
|
switch (method) {
|
|
466
409
|
case NodeForkedProcess:
|
|
467
|
-
return IpcChildWithNodeForkedProcess
|
|
410
|
+
return IpcChildWithNodeForkedProcess;
|
|
468
411
|
case NodeWorker:
|
|
469
|
-
return IpcChildWithNodeWorker
|
|
412
|
+
return IpcChildWithNodeWorker;
|
|
470
413
|
case ElectronUtilityProcess:
|
|
471
|
-
return IpcChildWithElectronUtilityProcess
|
|
414
|
+
return IpcChildWithElectronUtilityProcess;
|
|
472
415
|
case ElectronMessagePort:
|
|
473
|
-
return IpcChildWithElectronMessagePort
|
|
416
|
+
return IpcChildWithElectronMessagePort;
|
|
474
417
|
case WebSocket:
|
|
475
|
-
return IpcChildWithWebSocket
|
|
418
|
+
return IpcChildWithWebSocket;
|
|
476
419
|
default:
|
|
477
|
-
throw new Error('unexpected ipc type')
|
|
420
|
+
throw new Error('unexpected ipc type');
|
|
478
421
|
}
|
|
479
422
|
};
|
|
480
423
|
|
|
481
|
-
const listen$1 = async ({
|
|
424
|
+
const listen$1 = async ({
|
|
425
|
+
method,
|
|
426
|
+
...params
|
|
427
|
+
}) => {
|
|
482
428
|
const module = await getModule$1(method);
|
|
483
429
|
// @ts-ignore
|
|
484
430
|
const rawIpc = await module.listen(params);
|
|
@@ -489,25 +435,23 @@ const listen$1 = async ({ method, ...params }) => {
|
|
|
489
435
|
}
|
|
490
436
|
// @ts-ignore
|
|
491
437
|
const ipc = module.wrap(rawIpc);
|
|
492
|
-
return ipc
|
|
438
|
+
return ipc;
|
|
493
439
|
};
|
|
494
440
|
|
|
495
441
|
const listen = async () => {
|
|
496
|
-
const ipc = await listen$1({
|
|
442
|
+
const ipc = await listen$1({
|
|
443
|
+
method: Auto()
|
|
444
|
+
});
|
|
497
445
|
handleIpc(ipc);
|
|
498
446
|
};
|
|
499
447
|
|
|
500
448
|
const MainProcess = -5;
|
|
501
449
|
|
|
502
450
|
const state = {
|
|
503
|
-
|
|
504
|
-
* @type {any}
|
|
505
|
-
*/
|
|
506
|
-
ipc: undefined,
|
|
451
|
+
ipc: undefined
|
|
507
452
|
};
|
|
508
|
-
|
|
509
453
|
const invoke = (method, ...params) => {
|
|
510
|
-
return invoke$1(state.ipc, method, ...params)
|
|
454
|
+
return invoke$1(state.ipc, method, ...params);
|
|
511
455
|
};
|
|
512
456
|
|
|
513
457
|
const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
@@ -515,7 +459,7 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
515
459
|
// Assert.number(ipcId)
|
|
516
460
|
const ipc = await listen$1({
|
|
517
461
|
method: ElectronMessagePort,
|
|
518
|
-
messagePort
|
|
462
|
+
messagePort
|
|
519
463
|
});
|
|
520
464
|
handleIpc(ipc);
|
|
521
465
|
if (ipcId === MainProcess) {
|
|
@@ -524,27 +468,26 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
524
468
|
};
|
|
525
469
|
|
|
526
470
|
const getMainProcessId = () => {
|
|
527
|
-
return process.ppid
|
|
471
|
+
return process.ppid;
|
|
528
472
|
};
|
|
529
473
|
|
|
530
474
|
const isWindows = process.platform === 'win32';
|
|
531
475
|
|
|
532
476
|
const getModule = () => {
|
|
533
477
|
if (isWindows) {
|
|
534
|
-
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; })
|
|
478
|
+
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
|
|
535
479
|
}
|
|
536
|
-
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; })
|
|
480
|
+
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageUnix; });
|
|
537
481
|
};
|
|
538
|
-
|
|
539
|
-
const listProcessesWithMemoryUsage$2 = async (rootPid) => {
|
|
482
|
+
const listProcessesWithMemoryUsage$2 = async rootPid => {
|
|
540
483
|
const module = await getModule();
|
|
541
|
-
return module.listProcessesWithMemoryUsage(rootPid)
|
|
484
|
+
return module.listProcessesWithMemoryUsage(rootPid);
|
|
542
485
|
};
|
|
543
486
|
|
|
544
487
|
const commandMap = {
|
|
545
488
|
'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
|
|
546
489
|
'ProcessId.getMainProcessId': getMainProcessId,
|
|
547
|
-
'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2
|
|
490
|
+
'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2
|
|
548
491
|
// 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
|
|
549
492
|
};
|
|
550
493
|
|
|
@@ -556,79 +499,77 @@ const main = async () => {
|
|
|
556
499
|
main();
|
|
557
500
|
|
|
558
501
|
const getName = (pid, cmd, rootPid, pidMap) => {
|
|
559
|
-
number
|
|
502
|
+
number(pid);
|
|
560
503
|
string(cmd);
|
|
561
|
-
number
|
|
504
|
+
number(rootPid);
|
|
562
505
|
object(pidMap);
|
|
563
506
|
if (pid === rootPid) {
|
|
564
|
-
return 'main'
|
|
507
|
+
return 'main';
|
|
565
508
|
}
|
|
566
509
|
if (cmd.includes('--type=zygote')) {
|
|
567
|
-
return 'zygote'
|
|
510
|
+
return 'zygote';
|
|
568
511
|
}
|
|
569
512
|
if (cmd.includes('--type=gpu-process')) {
|
|
570
|
-
return 'gpu-process'
|
|
513
|
+
return 'gpu-process';
|
|
571
514
|
}
|
|
572
515
|
if (cmd.includes('extensionHostMain.js')) {
|
|
573
|
-
return 'extension-host'
|
|
516
|
+
return 'extension-host';
|
|
574
517
|
}
|
|
575
518
|
if (cmd.includes('ptyHostMain.js')) {
|
|
576
|
-
return 'pty-host'
|
|
519
|
+
return 'pty-host';
|
|
577
520
|
}
|
|
578
521
|
if (cmd.includes('--lvce-window-kind=process-explorer')) {
|
|
579
|
-
return 'process-explorer'
|
|
522
|
+
return 'process-explorer';
|
|
580
523
|
}
|
|
581
524
|
if (pid in pidMap) {
|
|
582
|
-
return pidMap[pid] || `<unknown
|
|
525
|
+
return pidMap[pid] || `<unknown>`;
|
|
583
526
|
}
|
|
584
527
|
if (cmd.includes('--type=renderer')) {
|
|
585
|
-
return `renderer
|
|
528
|
+
return `renderer`;
|
|
586
529
|
}
|
|
587
530
|
if (cmd.includes('--type=utility')) {
|
|
588
|
-
return 'utility'
|
|
531
|
+
return 'utility';
|
|
589
532
|
}
|
|
590
533
|
if (cmd.includes('tsserver.js')) {
|
|
591
|
-
return 'tsserver.js'
|
|
534
|
+
return 'tsserver.js';
|
|
592
535
|
}
|
|
593
536
|
if (cmd.includes('typingsInstaller.js')) {
|
|
594
|
-
return 'typingsInstaller.js'
|
|
537
|
+
return 'typingsInstaller.js';
|
|
595
538
|
}
|
|
596
539
|
if (cmd.includes('extensionHostHelperProcessMain.js')) {
|
|
597
|
-
return 'extension-host-helper-process'
|
|
540
|
+
return 'extension-host-helper-process';
|
|
598
541
|
}
|
|
599
542
|
if (cmd.includes('/bin/rg') || cmd.includes('rg.exe')) {
|
|
600
|
-
return 'ripgrep'
|
|
543
|
+
return 'ripgrep';
|
|
601
544
|
}
|
|
602
545
|
if (cmd.startsWith('bash')) {
|
|
603
|
-
return 'bash'
|
|
546
|
+
return 'bash';
|
|
604
547
|
}
|
|
605
548
|
if (cmd.startsWith(`/opt/sublime_text/sublime_text `)) {
|
|
606
|
-
return 'sublime-text'
|
|
549
|
+
return 'sublime-text';
|
|
607
550
|
}
|
|
608
551
|
if (cmd.includes('\\conhost.exe')) {
|
|
609
|
-
return 'conhost.exe'
|
|
552
|
+
return 'conhost.exe';
|
|
610
553
|
}
|
|
611
|
-
return `${cmd}
|
|
554
|
+
return `${cmd}`;
|
|
612
555
|
};
|
|
613
556
|
|
|
614
557
|
const ENOENT = 'ENOENT';
|
|
615
558
|
const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
|
|
616
559
|
const ESRCH = 'ESRCH';
|
|
617
560
|
|
|
618
|
-
const isDlOpenError =
|
|
619
|
-
return error && error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED
|
|
561
|
+
const isDlOpenError = error => {
|
|
562
|
+
return error && error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
|
|
620
563
|
};
|
|
621
564
|
|
|
622
565
|
const loadWindowProcessTree = async () => {
|
|
623
566
|
try {
|
|
624
|
-
return await import('@vscode/windows-process-tree')
|
|
567
|
+
return await import('@vscode/windows-process-tree');
|
|
625
568
|
} catch (error) {
|
|
626
569
|
if (isDlOpenError(error)) {
|
|
627
|
-
throw new VError(
|
|
628
|
-
`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`,
|
|
629
|
-
)
|
|
570
|
+
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`);
|
|
630
571
|
}
|
|
631
|
-
throw new VError(error, `Failed to load windows process tree`)
|
|
572
|
+
throw new VError(error, `Failed to load windows process tree`);
|
|
632
573
|
}
|
|
633
574
|
};
|
|
634
575
|
|
|
@@ -648,45 +589,38 @@ const withResolvers = () => {
|
|
|
648
589
|
return {
|
|
649
590
|
resolve: _resolve,
|
|
650
591
|
reject: _reject,
|
|
651
|
-
promise
|
|
652
|
-
}
|
|
592
|
+
promise
|
|
593
|
+
};
|
|
653
594
|
};
|
|
654
595
|
|
|
655
|
-
/**
|
|
656
|
-
*
|
|
657
|
-
* @param {number} rootPid
|
|
658
|
-
* @param {number} flags
|
|
659
|
-
* @returns {Promise<any[] | undefined>}
|
|
660
|
-
*/
|
|
661
596
|
const getProcessList = async (rootPid, flags) => {
|
|
662
597
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
663
|
-
const {
|
|
598
|
+
const {
|
|
599
|
+
resolve,
|
|
600
|
+
promise
|
|
601
|
+
} = withResolvers();
|
|
664
602
|
WindowsProcessTree.getProcessList(rootPid, resolve, flags);
|
|
665
|
-
return promise
|
|
603
|
+
return promise;
|
|
666
604
|
};
|
|
667
|
-
|
|
668
|
-
/**
|
|
669
|
-
*
|
|
670
|
-
* @param {any[]} processList
|
|
671
|
-
* @returns Promise< WindowsProcessTree.IProcessCpuInfo[]>
|
|
672
|
-
*/
|
|
673
|
-
const addCpuUsage = async (processList) => {
|
|
605
|
+
const addCpuUsage = async processList => {
|
|
674
606
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
675
|
-
const {
|
|
607
|
+
const {
|
|
608
|
+
resolve,
|
|
609
|
+
promise
|
|
610
|
+
} = withResolvers();
|
|
676
611
|
WindowsProcessTree.getProcessCpuUsage(processList, resolve);
|
|
677
|
-
return promise
|
|
612
|
+
return promise;
|
|
678
613
|
};
|
|
679
614
|
|
|
680
615
|
const Memory = 1;
|
|
681
616
|
const CommandLine = 2;
|
|
682
617
|
|
|
683
618
|
const createPidMap = async () => {
|
|
684
|
-
return invoke('CreatePidMap.createPidMap')
|
|
619
|
+
return invoke('CreatePidMap.createPidMap');
|
|
685
620
|
};
|
|
686
621
|
|
|
687
622
|
// listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
688
623
|
|
|
689
|
-
|
|
690
624
|
/**
|
|
691
625
|
* @param {import('@vscode/windows-process-tree').IProcessCpuInfo} item
|
|
692
626
|
* @param {number} rootPid
|
|
@@ -698,36 +632,29 @@ const toResultItem = (item, rootPid, pidMap) => {
|
|
|
698
632
|
pid: item.pid,
|
|
699
633
|
ppid: item.ppid,
|
|
700
634
|
memory: item.memory,
|
|
701
|
-
cmd: item.commandLine
|
|
702
|
-
}
|
|
635
|
+
cmd: item.commandLine
|
|
636
|
+
};
|
|
703
637
|
};
|
|
704
|
-
|
|
705
|
-
/**
|
|
706
|
-
*
|
|
707
|
-
* @param {import('@vscode/windows-process-tree').IProcessCpuInfo[]} completeProcessList
|
|
708
|
-
* @param {number} rootPid
|
|
709
|
-
*/
|
|
710
638
|
const toResult = (completeProcessList, rootPid, pidMap) => {
|
|
711
639
|
const results = [];
|
|
712
640
|
for (const item of completeProcessList) {
|
|
713
641
|
results.push(toResultItem(item, rootPid, pidMap));
|
|
714
642
|
}
|
|
715
|
-
return results
|
|
643
|
+
return results;
|
|
716
644
|
};
|
|
717
|
-
|
|
718
|
-
const listProcessesWithMemoryUsage$1 = async (rootPid) => {
|
|
645
|
+
const listProcessesWithMemoryUsage$1 = async rootPid => {
|
|
719
646
|
try {
|
|
720
647
|
const processList = await getProcessList(rootPid, CommandLine | Memory);
|
|
721
648
|
if (!processList) {
|
|
722
|
-
throw new VError(`Root process ${rootPid} not found`)
|
|
649
|
+
throw new VError(`Root process ${rootPid} not found`);
|
|
723
650
|
}
|
|
724
651
|
const pidMap = await createPidMap();
|
|
725
652
|
const completeProcessList = await addCpuUsage(processList);
|
|
726
653
|
const result = toResult(completeProcessList, rootPid, pidMap);
|
|
727
|
-
return result
|
|
654
|
+
return result;
|
|
728
655
|
} catch (error) {
|
|
729
656
|
// @ts-ignore
|
|
730
|
-
throw new VError(error, `Failed to list processes`)
|
|
657
|
+
throw new VError(error, `Failed to list processes`);
|
|
731
658
|
}
|
|
732
659
|
};
|
|
733
660
|
|
|
@@ -738,23 +665,22 @@ const ListProcessesWithMemoryUsageWindows = {
|
|
|
738
665
|
|
|
739
666
|
const Utf8 = 'utf8';
|
|
740
667
|
|
|
741
|
-
const isEnoentErrorWindows =
|
|
742
|
-
return error && error.message && error.message.includes('The system cannot find the path specified.')
|
|
668
|
+
const isEnoentErrorWindows = error => {
|
|
669
|
+
return error && error.message && error.message.includes('The system cannot find the path specified.');
|
|
743
670
|
};
|
|
744
671
|
|
|
745
|
-
const isEnoentErrorLinux =
|
|
746
|
-
return error.code === ENOENT
|
|
672
|
+
const isEnoentErrorLinux = error => {
|
|
673
|
+
return error.code === ENOENT;
|
|
747
674
|
};
|
|
748
|
-
|
|
749
|
-
const isEnoentError = (error) => {
|
|
675
|
+
const isEnoentError = error => {
|
|
750
676
|
if (!error) {
|
|
751
|
-
return false
|
|
677
|
+
return false;
|
|
752
678
|
}
|
|
753
|
-
return isEnoentErrorLinux(error) || isEnoentErrorWindows(error)
|
|
679
|
+
return isEnoentErrorLinux(error) || isEnoentErrorWindows(error);
|
|
754
680
|
};
|
|
755
681
|
|
|
756
|
-
const isEsrchError =
|
|
757
|
-
return error && error.code === ESRCH
|
|
682
|
+
const isEsrchError = error => {
|
|
683
|
+
return error && error.code === ESRCH;
|
|
758
684
|
};
|
|
759
685
|
|
|
760
686
|
const isMacOs = process.platform === 'darwin';
|
|
@@ -763,105 +689,102 @@ const EmptyString = '';
|
|
|
763
689
|
const NewLine = '\n';
|
|
764
690
|
const Space = ' ';
|
|
765
691
|
|
|
766
|
-
const parseMemory =
|
|
692
|
+
const parseMemory = content => {
|
|
767
693
|
const trimmedContent = content.trim();
|
|
768
694
|
const numberBlocks = trimmedContent.split(Space);
|
|
769
695
|
const pageSize = 4096;
|
|
770
696
|
const rss = Number.parseInt(numberBlocks[1]) * pageSize;
|
|
771
697
|
const shared = Number.parseInt(numberBlocks[2]) * pageSize;
|
|
772
698
|
const memory = rss - shared;
|
|
773
|
-
return memory
|
|
699
|
+
return memory;
|
|
774
700
|
};
|
|
775
701
|
|
|
776
|
-
const getContent = async
|
|
702
|
+
const getContent = async pid => {
|
|
777
703
|
try {
|
|
778
704
|
const filePath = join('/proc', `${pid}`, 'statm');
|
|
779
705
|
const content = await readFile(filePath, Utf8);
|
|
780
|
-
return content
|
|
706
|
+
return content;
|
|
781
707
|
} catch (error) {
|
|
782
708
|
if (isEnoentError(error) || isEsrchError(error)) {
|
|
783
|
-
return ''
|
|
709
|
+
return '';
|
|
784
710
|
}
|
|
785
|
-
throw error
|
|
711
|
+
throw error;
|
|
786
712
|
}
|
|
787
713
|
};
|
|
788
|
-
|
|
789
|
-
const getAccurateMemoryUsage = async (pid) => {
|
|
714
|
+
const getAccurateMemoryUsage = async pid => {
|
|
790
715
|
try {
|
|
791
|
-
number
|
|
716
|
+
number(pid);
|
|
792
717
|
if (isMacOs) {
|
|
793
|
-
return 0
|
|
718
|
+
return 0;
|
|
794
719
|
}
|
|
795
720
|
const content = await getContent(pid);
|
|
796
721
|
if (!content) {
|
|
797
|
-
return -1
|
|
722
|
+
return -1;
|
|
798
723
|
}
|
|
799
724
|
const memory = parseMemory(content);
|
|
800
|
-
return memory
|
|
725
|
+
return memory;
|
|
801
726
|
} catch (error) {
|
|
802
|
-
throw new VError(error, 'Failed to get accurate memory usage')
|
|
727
|
+
throw new VError(error, 'Failed to get accurate memory usage');
|
|
803
728
|
}
|
|
804
729
|
};
|
|
805
730
|
|
|
806
|
-
const addAccurateMemoryUsage = async
|
|
731
|
+
const addAccurateMemoryUsage = async process => {
|
|
807
732
|
const accurateMemoryUsage = await getAccurateMemoryUsage(process.pid);
|
|
808
733
|
return {
|
|
809
734
|
...process,
|
|
810
|
-
memory: accurateMemoryUsage
|
|
811
|
-
}
|
|
735
|
+
memory: accurateMemoryUsage
|
|
736
|
+
};
|
|
812
737
|
};
|
|
813
738
|
|
|
814
739
|
const SIGINT = 'SIGINT';
|
|
815
740
|
|
|
816
741
|
const execFile = promisify(execFile$1);
|
|
817
|
-
|
|
818
742
|
const getPsOutput = async () => {
|
|
819
743
|
try {
|
|
820
|
-
const {
|
|
821
|
-
|
|
744
|
+
const {
|
|
745
|
+
stdout
|
|
746
|
+
} = await execFile('ps', ['-ax', '-o', 'pid=,ppid=,pcpu=,pmem=,command=']);
|
|
747
|
+
return stdout.trim();
|
|
822
748
|
} catch (error) {
|
|
823
749
|
// @ts-ignore
|
|
824
750
|
if (error && error.signal === SIGINT) {
|
|
825
|
-
return ''
|
|
751
|
+
return '';
|
|
826
752
|
}
|
|
827
|
-
throw new VError(error, `Failed to execute ps`)
|
|
753
|
+
throw new VError(error, `Failed to execute ps`);
|
|
828
754
|
}
|
|
829
755
|
};
|
|
830
756
|
|
|
831
|
-
const hasPositiveMemoryUsage =
|
|
832
|
-
return process.memory >= 0
|
|
757
|
+
const hasPositiveMemoryUsage = process => {
|
|
758
|
+
return process.memory >= 0;
|
|
833
759
|
};
|
|
834
760
|
|
|
835
|
-
const splitLines =
|
|
836
|
-
return lines.split(NewLine)
|
|
761
|
+
const splitLines = lines => {
|
|
762
|
+
return lines.split(NewLine);
|
|
837
763
|
};
|
|
838
764
|
|
|
839
765
|
// parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
840
766
|
|
|
841
|
-
|
|
842
767
|
const PID_CMD = /^\s*(\d+)\s+(\d+)\s+([\d.]+)\s+([\d.]+)\s+(.+)$/s;
|
|
843
|
-
|
|
844
|
-
const parsePsOutputLine = (line) => {
|
|
768
|
+
const parsePsOutputLine = line => {
|
|
845
769
|
string(line);
|
|
846
770
|
const matches = PID_CMD.exec(line.trim());
|
|
847
771
|
if (matches && matches.length === 6) {
|
|
848
772
|
return {
|
|
849
773
|
pid: Number.parseInt(matches[1]),
|
|
850
774
|
ppid: Number.parseInt(matches[2]),
|
|
851
|
-
cmd: matches[5]
|
|
775
|
+
cmd: matches[5]
|
|
852
776
|
// load: parseInt(matches[3]),
|
|
853
777
|
// mem: parseInt(matches[4]),
|
|
854
|
-
}
|
|
778
|
+
};
|
|
855
779
|
}
|
|
856
|
-
throw new Error(`line could not be parsed: ${line}`)
|
|
780
|
+
throw new Error(`line could not be parsed: ${line}`);
|
|
857
781
|
};
|
|
858
|
-
|
|
859
782
|
const parsePsOutput = (stdout, rootPid, pidMap) => {
|
|
860
783
|
string(stdout);
|
|
861
|
-
number
|
|
784
|
+
number(rootPid);
|
|
862
785
|
object(pidMap);
|
|
863
786
|
if (stdout === EmptyString) {
|
|
864
|
-
return []
|
|
787
|
+
return [];
|
|
865
788
|
}
|
|
866
789
|
const lines = splitLines(stdout);
|
|
867
790
|
const result = [];
|
|
@@ -869,22 +792,26 @@ const parsePsOutput = (stdout, rootPid, pidMap) => {
|
|
|
869
792
|
depthMap[rootPid] = 1;
|
|
870
793
|
const parsedLines = lines.map(parsePsOutputLine);
|
|
871
794
|
for (const parsedLine of parsedLines) {
|
|
872
|
-
const {
|
|
795
|
+
const {
|
|
796
|
+
pid,
|
|
797
|
+
ppid,
|
|
798
|
+
cmd
|
|
799
|
+
} = parsedLine;
|
|
873
800
|
const depth = pid === rootPid ? 1 : depthMap[ppid];
|
|
874
801
|
if (!depth) {
|
|
875
|
-
continue
|
|
802
|
+
continue;
|
|
876
803
|
}
|
|
877
804
|
result.push({
|
|
878
805
|
...parsedLine,
|
|
879
806
|
depth,
|
|
880
|
-
name: getName(pid, cmd, rootPid, pidMap)
|
|
807
|
+
name: getName(pid, cmd, rootPid, pidMap)
|
|
881
808
|
});
|
|
882
809
|
depthMap[pid] = depth + 1;
|
|
883
810
|
}
|
|
884
|
-
return result
|
|
811
|
+
return result;
|
|
885
812
|
};
|
|
886
813
|
|
|
887
|
-
const listProcessesWithMemoryUsage = async
|
|
814
|
+
const listProcessesWithMemoryUsage = async rootPid => {
|
|
888
815
|
// console.time('getPsOutput')
|
|
889
816
|
const stdout = await getPsOutput();
|
|
890
817
|
const pidMap = await createPidMap();
|
|
@@ -897,7 +824,7 @@ const listProcessesWithMemoryUsage = async (rootPid) => {
|
|
|
897
824
|
const parsedWithAccurateMemoryUsage = await Promise.all(parsed.map(addAccurateMemoryUsage));
|
|
898
825
|
// console.timeEnd('addAccurateMemoryUsage')
|
|
899
826
|
const filtered = parsedWithAccurateMemoryUsage.filter(hasPositiveMemoryUsage);
|
|
900
|
-
return filtered
|
|
827
|
+
return filtered;
|
|
901
828
|
};
|
|
902
829
|
|
|
903
830
|
const ListProcessesWithMemoryUsageUnix = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/process-explorer",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Process Explorer",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": "bin/processExplorer.js",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"node": ">=18"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@lvce-editor/assert": "^1.
|
|
22
|
-
"@lvce-editor/ipc": "^
|
|
23
|
-
"@lvce-editor/json-rpc": "^
|
|
24
|
-
"@lvce-editor/verror": "^1.
|
|
21
|
+
"@lvce-editor/assert": "^1.3.0",
|
|
22
|
+
"@lvce-editor/ipc": "^11.4.0",
|
|
23
|
+
"@lvce-editor/json-rpc": "^5.2.0",
|
|
24
|
+
"@lvce-editor/verror": "^1.6.0"
|
|
25
25
|
},
|
|
26
26
|
"optionalDependencies": {
|
|
27
27
|
"@vscode/windows-process-tree": "^0.6.0"
|