@lvce-editor/process-explorer 2.4.0 → 3.0.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/bin/processExplorer.js +0 -0
- package/dist/index.js +130 -440
- package/package.json +6 -51
package/bin/processExplorer.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -1,341 +1,12 @@
|
|
|
1
|
-
import { IpcChildWithWebSocket, IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithNodeWorker, IpcChildWithNodeForkedProcess } from '@lvce-editor/ipc';
|
|
2
1
|
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
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
|
-
}
|
|
257
|
-
};
|
|
258
|
-
const defaultPreparePrettyError = error => {
|
|
259
|
-
return error;
|
|
260
|
-
};
|
|
261
|
-
const defaultLogError = () => {
|
|
262
|
-
// ignore
|
|
263
|
-
};
|
|
264
|
-
const defaultRequiresSocket = () => {
|
|
265
|
-
return false;
|
|
266
|
-
};
|
|
267
|
-
const defaultResolve = resolve;
|
|
268
|
-
|
|
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);
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
if ('method' in message) {
|
|
319
|
-
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
throw new JsonRpcError('unexpected message');
|
|
323
|
-
};
|
|
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);
|
|
334
|
-
};
|
|
335
|
-
const invoke$1 = (ipc, method, ...params) => {
|
|
336
|
-
return invokeHelper(ipc, method, params);
|
|
337
|
-
};
|
|
338
|
-
|
|
339
10
|
const state$1 = {
|
|
340
11
|
commands: Object.create(null)
|
|
341
12
|
};
|
|
@@ -404,14 +75,14 @@ const Auto = () => {
|
|
|
404
75
|
|
|
405
76
|
const getModule$1 = method => {
|
|
406
77
|
switch (method) {
|
|
78
|
+
case ElectronMessagePort:
|
|
79
|
+
return IpcChildWithElectronMessagePort;
|
|
80
|
+
case ElectronUtilityProcess:
|
|
81
|
+
return IpcChildWithElectronUtilityProcess;
|
|
407
82
|
case NodeForkedProcess:
|
|
408
83
|
return IpcChildWithNodeForkedProcess;
|
|
409
84
|
case NodeWorker:
|
|
410
85
|
return IpcChildWithNodeWorker;
|
|
411
|
-
case ElectronUtilityProcess:
|
|
412
|
-
return IpcChildWithElectronUtilityProcess;
|
|
413
|
-
case ElectronMessagePort:
|
|
414
|
-
return IpcChildWithElectronMessagePort;
|
|
415
86
|
case WebSocket:
|
|
416
87
|
return IpcChildWithWebSocket;
|
|
417
88
|
default:
|
|
@@ -423,9 +94,9 @@ const listen$1 = async ({
|
|
|
423
94
|
method,
|
|
424
95
|
...params
|
|
425
96
|
}) => {
|
|
426
|
-
const module =
|
|
97
|
+
const module = getModule$1(method);
|
|
427
98
|
// @ts-ignore
|
|
428
|
-
const rawIpc =
|
|
99
|
+
const rawIpc = module.listen(params);
|
|
429
100
|
// @ts-ignore
|
|
430
101
|
if (module.signal) {
|
|
431
102
|
// @ts-ignore
|
|
@@ -436,13 +107,6 @@ const listen$1 = async ({
|
|
|
436
107
|
return ipc;
|
|
437
108
|
};
|
|
438
109
|
|
|
439
|
-
const listen = async () => {
|
|
440
|
-
const ipc = await listen$1({
|
|
441
|
-
method: Auto()
|
|
442
|
-
});
|
|
443
|
-
handleIpc(ipc);
|
|
444
|
-
};
|
|
445
|
-
|
|
446
110
|
const MainProcess = -5;
|
|
447
111
|
|
|
448
112
|
const state = {
|
|
@@ -456,8 +120,8 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
456
120
|
object(messagePort);
|
|
457
121
|
// Assert.number(ipcId)
|
|
458
122
|
const ipc = await listen$1({
|
|
459
|
-
|
|
460
|
-
|
|
123
|
+
messagePort,
|
|
124
|
+
method: ElectronMessagePort
|
|
461
125
|
});
|
|
462
126
|
handleIpc(ipc);
|
|
463
127
|
if (ipcId === MainProcess) {
|
|
@@ -465,13 +129,9 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
465
129
|
}
|
|
466
130
|
};
|
|
467
131
|
|
|
468
|
-
const getMainProcessId = () => {
|
|
469
|
-
return process.ppid;
|
|
470
|
-
};
|
|
471
|
-
|
|
472
132
|
const isWindows = process.platform === 'win32';
|
|
473
133
|
|
|
474
|
-
const getModule = () => {
|
|
134
|
+
const getModule = async () => {
|
|
475
135
|
if (isWindows) {
|
|
476
136
|
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
|
|
477
137
|
}
|
|
@@ -482,13 +142,24 @@ const listProcessesWithMemoryUsage$2 = async rootPid => {
|
|
|
482
142
|
return module.listProcessesWithMemoryUsage(rootPid);
|
|
483
143
|
};
|
|
484
144
|
|
|
145
|
+
const getMainProcessId = () => {
|
|
146
|
+
return process.ppid;
|
|
147
|
+
};
|
|
148
|
+
|
|
485
149
|
const commandMap = {
|
|
486
150
|
'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
|
|
487
|
-
'
|
|
488
|
-
'
|
|
151
|
+
'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2,
|
|
152
|
+
'ProcessId.getMainProcessId': getMainProcessId
|
|
489
153
|
// 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
|
|
490
154
|
};
|
|
491
155
|
|
|
156
|
+
const listen = async () => {
|
|
157
|
+
const ipc = await listen$1({
|
|
158
|
+
method: Auto()
|
|
159
|
+
});
|
|
160
|
+
handleIpc(ipc);
|
|
161
|
+
};
|
|
162
|
+
|
|
492
163
|
const main = async () => {
|
|
493
164
|
registerCommands(commandMap);
|
|
494
165
|
await listen();
|
|
@@ -496,6 +167,60 @@ const main = async () => {
|
|
|
496
167
|
|
|
497
168
|
main();
|
|
498
169
|
|
|
170
|
+
const createPidMap = async () => {
|
|
171
|
+
return invoke('CreatePidMap.createPidMap');
|
|
172
|
+
};
|
|
173
|
+
|
|
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
|
+
const fallbackProcessNamePatterns = [{
|
|
191
|
+
matches: cmd => cmd.includes('--type=renderer'),
|
|
192
|
+
name: 'renderer'
|
|
193
|
+
}, {
|
|
194
|
+
matches: cmd => cmd.includes('--type=utility'),
|
|
195
|
+
name: 'utility'
|
|
196
|
+
}, {
|
|
197
|
+
matches: cmd => cmd.includes('tsserver.js'),
|
|
198
|
+
name: 'tsserver.js'
|
|
199
|
+
}, {
|
|
200
|
+
matches: cmd => cmd.includes('typingsInstaller.js'),
|
|
201
|
+
name: 'typingsInstaller.js'
|
|
202
|
+
}, {
|
|
203
|
+
matches: cmd => cmd.includes('extensionHostHelperProcessMain.js'),
|
|
204
|
+
name: 'extension-host-helper-process'
|
|
205
|
+
}, {
|
|
206
|
+
matches: cmd => cmd.includes('/bin/rg') || cmd.includes('rg.exe'),
|
|
207
|
+
name: 'ripgrep'
|
|
208
|
+
}, {
|
|
209
|
+
matches: cmd => cmd.startsWith('bash'),
|
|
210
|
+
name: 'bash'
|
|
211
|
+
}, {
|
|
212
|
+
matches: cmd => cmd.startsWith('/opt/sublime_text/sublime_text '),
|
|
213
|
+
name: 'sublime-text'
|
|
214
|
+
}, {
|
|
215
|
+
matches: cmd => cmd.includes('\\conhost.exe'),
|
|
216
|
+
name: 'conhost.exe'
|
|
217
|
+
}];
|
|
218
|
+
const getPatternName = cmd => {
|
|
219
|
+
return processNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
|
|
220
|
+
};
|
|
221
|
+
const getFallbackPatternName = cmd => {
|
|
222
|
+
return fallbackProcessNamePatterns.find(pattern => pattern.matches(cmd))?.name || '';
|
|
223
|
+
};
|
|
499
224
|
const getName = (pid, cmd, rootPid, pidMap) => {
|
|
500
225
|
number(pid);
|
|
501
226
|
string(cmd);
|
|
@@ -504,52 +229,18 @@ const getName = (pid, cmd, rootPid, pidMap) => {
|
|
|
504
229
|
if (pid === rootPid) {
|
|
505
230
|
return 'main';
|
|
506
231
|
}
|
|
507
|
-
|
|
508
|
-
|
|
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';
|
|
232
|
+
const patternName = getPatternName(cmd);
|
|
233
|
+
if (patternName) {
|
|
234
|
+
return patternName;
|
|
521
235
|
}
|
|
522
236
|
if (pid in pidMap) {
|
|
523
|
-
return pidMap[pid] ||
|
|
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';
|
|
533
|
-
}
|
|
534
|
-
if (cmd.includes('typingsInstaller.js')) {
|
|
535
|
-
return 'typingsInstaller.js';
|
|
536
|
-
}
|
|
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';
|
|
237
|
+
return pidMap[pid] || '<unknown>';
|
|
542
238
|
}
|
|
543
|
-
|
|
544
|
-
|
|
239
|
+
const fallbackPatternName = getFallbackPatternName(cmd);
|
|
240
|
+
if (fallbackPatternName) {
|
|
241
|
+
return fallbackPatternName;
|
|
545
242
|
}
|
|
546
|
-
|
|
547
|
-
return 'sublime-text';
|
|
548
|
-
}
|
|
549
|
-
if (cmd.includes('\\conhost.exe')) {
|
|
550
|
-
return 'conhost.exe';
|
|
551
|
-
}
|
|
552
|
-
return `${cmd}`;
|
|
243
|
+
return cmd;
|
|
553
244
|
};
|
|
554
245
|
|
|
555
246
|
const ENOENT = 'ENOENT';
|
|
@@ -557,7 +248,7 @@ const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
|
|
|
557
248
|
const ESRCH = 'ESRCH';
|
|
558
249
|
|
|
559
250
|
const isDlOpenError = error => {
|
|
560
|
-
return error
|
|
251
|
+
return error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
|
|
561
252
|
};
|
|
562
253
|
|
|
563
254
|
const loadWindowProcessTree = async () => {
|
|
@@ -572,30 +263,14 @@ const loadWindowProcessTree = async () => {
|
|
|
572
263
|
};
|
|
573
264
|
|
|
574
265
|
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
|
-
};
|
|
266
|
+
return Promise.withResolvers();
|
|
592
267
|
};
|
|
593
268
|
|
|
594
269
|
const getProcessList = async (rootPid, flags) => {
|
|
595
270
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
596
271
|
const {
|
|
597
|
-
|
|
598
|
-
|
|
272
|
+
promise,
|
|
273
|
+
resolve
|
|
599
274
|
} = withResolvers();
|
|
600
275
|
WindowsProcessTree.getProcessList(rootPid, resolve, flags);
|
|
601
276
|
return promise;
|
|
@@ -603,20 +278,19 @@ const getProcessList = async (rootPid, flags) => {
|
|
|
603
278
|
const addCpuUsage = async processList => {
|
|
604
279
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
605
280
|
const {
|
|
606
|
-
|
|
607
|
-
|
|
281
|
+
promise,
|
|
282
|
+
resolve
|
|
608
283
|
} = withResolvers();
|
|
609
|
-
|
|
284
|
+
const mutableProcessList = processList.map(process => ({
|
|
285
|
+
...process
|
|
286
|
+
}));
|
|
287
|
+
WindowsProcessTree.getProcessCpuUsage(mutableProcessList, resolve);
|
|
610
288
|
return promise;
|
|
611
289
|
};
|
|
612
290
|
|
|
613
291
|
const Memory = 1;
|
|
614
292
|
const CommandLine = 2;
|
|
615
293
|
|
|
616
|
-
const createPidMap = async () => {
|
|
617
|
-
return invoke('CreatePidMap.createPidMap');
|
|
618
|
-
};
|
|
619
|
-
|
|
620
294
|
// listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
621
295
|
|
|
622
296
|
/**
|
|
@@ -626,18 +300,15 @@ const createPidMap = async () => {
|
|
|
626
300
|
*/
|
|
627
301
|
const toResultItem = (item, rootPid, pidMap) => {
|
|
628
302
|
return {
|
|
303
|
+
cmd: item.commandLine,
|
|
304
|
+
memory: item.memory,
|
|
629
305
|
name: getName(item.pid, item.commandLine, rootPid, pidMap),
|
|
630
306
|
pid: item.pid,
|
|
631
|
-
ppid: item.ppid
|
|
632
|
-
memory: item.memory,
|
|
633
|
-
cmd: item.commandLine
|
|
307
|
+
ppid: item.ppid
|
|
634
308
|
};
|
|
635
309
|
};
|
|
636
310
|
const toResult = (completeProcessList, rootPid, pidMap) => {
|
|
637
|
-
const results =
|
|
638
|
-
for (const item of completeProcessList) {
|
|
639
|
-
results.push(toResultItem(item, rootPid, pidMap));
|
|
640
|
-
}
|
|
311
|
+
const results = Array.from(completeProcessList, item => toResultItem(item, rootPid, pidMap));
|
|
641
312
|
return results;
|
|
642
313
|
};
|
|
643
314
|
const listProcessesWithMemoryUsage$1 = async rootPid => {
|
|
@@ -699,7 +370,7 @@ const parseMemory = content => {
|
|
|
699
370
|
|
|
700
371
|
const getContent = async pid => {
|
|
701
372
|
try {
|
|
702
|
-
const filePath = join('/proc',
|
|
373
|
+
const filePath = join('/proc', String(pid), 'statm');
|
|
703
374
|
const content = await readFile(filePath, Utf8);
|
|
704
375
|
return content;
|
|
705
376
|
} catch (error) {
|
|
@@ -762,17 +433,36 @@ const splitLines = lines => {
|
|
|
762
433
|
|
|
763
434
|
// parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
764
435
|
|
|
765
|
-
const
|
|
436
|
+
const isSpace = character => {
|
|
437
|
+
return character === ' ' || character === '\t';
|
|
438
|
+
};
|
|
439
|
+
const readField = (line, startIndex) => {
|
|
440
|
+
let start = startIndex;
|
|
441
|
+
while (start < line.length && isSpace(line[start])) {
|
|
442
|
+
start++;
|
|
443
|
+
}
|
|
444
|
+
let end = start;
|
|
445
|
+
while (end < line.length && !isSpace(line[end])) {
|
|
446
|
+
end++;
|
|
447
|
+
}
|
|
448
|
+
return {
|
|
449
|
+
nextIndex: end,
|
|
450
|
+
value: line.slice(start, end)
|
|
451
|
+
};
|
|
452
|
+
};
|
|
766
453
|
const parsePsOutputLine = line => {
|
|
767
454
|
string(line);
|
|
768
|
-
const
|
|
769
|
-
|
|
455
|
+
const trimmedLine = line.trim();
|
|
456
|
+
const pidField = readField(trimmedLine, 0);
|
|
457
|
+
const ppidField = readField(trimmedLine, pidField.nextIndex);
|
|
458
|
+
const loadField = readField(trimmedLine, ppidField.nextIndex);
|
|
459
|
+
const memoryField = readField(trimmedLine, loadField.nextIndex);
|
|
460
|
+
const cmd = trimmedLine.slice(memoryField.nextIndex).trim();
|
|
461
|
+
if (pidField.value && ppidField.value && loadField.value && memoryField.value && cmd) {
|
|
770
462
|
return {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
// load: parseInt(matches[3]),
|
|
775
|
-
// mem: parseInt(matches[4]),
|
|
463
|
+
cmd,
|
|
464
|
+
pid: Number.parseInt(pidField.value),
|
|
465
|
+
ppid: Number.parseInt(ppidField.value)
|
|
776
466
|
};
|
|
777
467
|
}
|
|
778
468
|
throw new Error(`line could not be parsed: ${line}`);
|
|
@@ -791,9 +481,9 @@ const parsePsOutput = (stdout, rootPid, pidMap) => {
|
|
|
791
481
|
const parsedLines = lines.map(parsePsOutputLine);
|
|
792
482
|
for (const parsedLine of parsedLines) {
|
|
793
483
|
const {
|
|
484
|
+
cmd,
|
|
794
485
|
pid,
|
|
795
|
-
ppid
|
|
796
|
-
cmd
|
|
486
|
+
ppid
|
|
797
487
|
} = parsedLine;
|
|
798
488
|
const depth = pid === rootPid ? 1 : depthMap[ppid];
|
|
799
489
|
if (!depth) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/process-explorer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.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.
|
|
22
|
-
"@lvce-editor/ipc": "^
|
|
23
|
-
"@lvce-editor/json-rpc": "^
|
|
24
|
-
"@lvce-editor/verror": "^1.
|
|
21
|
+
"@lvce-editor/assert": "^1.5.1",
|
|
22
|
+
"@lvce-editor/ipc": "^16.0.0",
|
|
23
|
+
"@lvce-editor/json-rpc": "^8.0.0",
|
|
24
|
+
"@lvce-editor/verror": "^1.7.0"
|
|
25
25
|
},
|
|
26
26
|
"optionalDependencies": {
|
|
27
|
-
"@vscode/windows-process-tree": "^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
|
}
|