@lvce-editor/process-explorer 2.3.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 -442
- package/package.json +6 -51
package/bin/processExplorer.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
@@ -1,343 +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 state$2 = {
|
|
11
|
-
callbacks: Object.create(null)
|
|
12
|
-
};
|
|
13
|
-
const set = (id, fn) => {
|
|
14
|
-
state$2.callbacks[id] = fn;
|
|
15
|
-
};
|
|
16
|
-
const get = id => {
|
|
17
|
-
return state$2.callbacks[id];
|
|
18
|
-
};
|
|
19
|
-
const remove = id => {
|
|
20
|
-
delete state$2.callbacks[id];
|
|
21
|
-
};
|
|
22
|
-
let id = 0;
|
|
23
|
-
const create$3 = () => {
|
|
24
|
-
return ++id;
|
|
25
|
-
};
|
|
26
|
-
const warn = (...args) => {
|
|
27
|
-
console.warn(...args);
|
|
28
|
-
};
|
|
29
|
-
const registerPromise = () => {
|
|
30
|
-
const id = create$3();
|
|
31
|
-
const {
|
|
32
|
-
resolve,
|
|
33
|
-
promise
|
|
34
|
-
} = Promise.withResolvers();
|
|
35
|
-
set(id, resolve);
|
|
36
|
-
return {
|
|
37
|
-
id,
|
|
38
|
-
promise
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
const resolve = (id, response) => {
|
|
42
|
-
const fn = get(id);
|
|
43
|
-
if (!fn) {
|
|
44
|
-
console.log(response);
|
|
45
|
-
warn(`callback ${id} may already be disposed`);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
fn(response);
|
|
49
|
-
remove(id);
|
|
50
|
-
};
|
|
51
|
-
const create$2 = (method, params) => {
|
|
52
|
-
const {
|
|
53
|
-
id,
|
|
54
|
-
promise
|
|
55
|
-
} = registerPromise();
|
|
56
|
-
const message = {
|
|
57
|
-
jsonrpc: Two,
|
|
58
|
-
method,
|
|
59
|
-
params,
|
|
60
|
-
id
|
|
61
|
-
};
|
|
62
|
-
return {
|
|
63
|
-
message,
|
|
64
|
-
promise
|
|
65
|
-
};
|
|
66
|
-
};
|
|
67
|
-
class JsonRpcError extends Error {
|
|
68
|
-
constructor(message) {
|
|
69
|
-
super(message);
|
|
70
|
-
this.name = 'JsonRpcError';
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
const NewLine$1 = '\n';
|
|
74
|
-
const DomException = 'DOMException';
|
|
75
|
-
const ReferenceError$1 = 'ReferenceError';
|
|
76
|
-
const SyntaxError$1 = 'SyntaxError';
|
|
77
|
-
const TypeError$1 = 'TypeError';
|
|
78
|
-
const getErrorConstructor = (message, type) => {
|
|
79
|
-
if (type) {
|
|
80
|
-
switch (type) {
|
|
81
|
-
case DomException:
|
|
82
|
-
return DOMException;
|
|
83
|
-
case TypeError$1:
|
|
84
|
-
return TypeError;
|
|
85
|
-
case SyntaxError$1:
|
|
86
|
-
return SyntaxError;
|
|
87
|
-
case ReferenceError$1:
|
|
88
|
-
return ReferenceError;
|
|
89
|
-
default:
|
|
90
|
-
return Error;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (message.startsWith('TypeError: ')) {
|
|
94
|
-
return TypeError;
|
|
95
|
-
}
|
|
96
|
-
if (message.startsWith('SyntaxError: ')) {
|
|
97
|
-
return SyntaxError;
|
|
98
|
-
}
|
|
99
|
-
if (message.startsWith('ReferenceError: ')) {
|
|
100
|
-
return ReferenceError;
|
|
101
|
-
}
|
|
102
|
-
return Error;
|
|
103
|
-
};
|
|
104
|
-
const constructError = (message, type, name) => {
|
|
105
|
-
const ErrorConstructor = getErrorConstructor(message, type);
|
|
106
|
-
if (ErrorConstructor === DOMException && name) {
|
|
107
|
-
return new ErrorConstructor(message, name);
|
|
108
|
-
}
|
|
109
|
-
if (ErrorConstructor === Error) {
|
|
110
|
-
const error = new Error(message);
|
|
111
|
-
if (name && name !== 'VError') {
|
|
112
|
-
error.name = name;
|
|
113
|
-
}
|
|
114
|
-
return error;
|
|
115
|
-
}
|
|
116
|
-
return new ErrorConstructor(message);
|
|
117
|
-
};
|
|
118
|
-
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
119
|
-
return string.indexOf(NewLine$1, startIndex);
|
|
120
|
-
};
|
|
121
|
-
const getParentStack = error => {
|
|
122
|
-
let parentStack = error.stack || error.data || error.message || '';
|
|
123
|
-
if (parentStack.startsWith(' at')) {
|
|
124
|
-
parentStack = error.message + NewLine$1 + parentStack;
|
|
125
|
-
}
|
|
126
|
-
return parentStack;
|
|
127
|
-
};
|
|
128
|
-
const joinLines = lines => {
|
|
129
|
-
return lines.join(NewLine$1);
|
|
130
|
-
};
|
|
131
|
-
const MethodNotFound = -32601;
|
|
132
|
-
const Custom = -32001;
|
|
133
|
-
const splitLines$1 = lines => {
|
|
134
|
-
return lines.split(NewLine$1);
|
|
135
|
-
};
|
|
136
|
-
const restoreJsonRpcError = error => {
|
|
137
|
-
if (error && error instanceof Error) {
|
|
138
|
-
return error;
|
|
139
|
-
}
|
|
140
|
-
const currentStack = joinLines(splitLines$1(new Error().stack || '').slice(1));
|
|
141
|
-
if (error && error.code && error.code === MethodNotFound) {
|
|
142
|
-
const restoredError = new JsonRpcError(error.message);
|
|
143
|
-
const parentStack = getParentStack(error);
|
|
144
|
-
restoredError.stack = parentStack + NewLine$1 + currentStack;
|
|
145
|
-
return restoredError;
|
|
146
|
-
}
|
|
147
|
-
if (error && error.message) {
|
|
148
|
-
const restoredError = constructError(error.message, error.type, error.name);
|
|
149
|
-
if (error.data) {
|
|
150
|
-
if (error.data.stack && error.data.type && error.message) {
|
|
151
|
-
restoredError.stack = error.data.type + ': ' + error.message + NewLine$1 + error.data.stack + NewLine$1 + currentStack;
|
|
152
|
-
} else if (error.data.stack) {
|
|
153
|
-
restoredError.stack = error.data.stack;
|
|
154
|
-
}
|
|
155
|
-
if (error.data.codeFrame) {
|
|
156
|
-
// @ts-ignore
|
|
157
|
-
restoredError.codeFrame = error.data.codeFrame;
|
|
158
|
-
}
|
|
159
|
-
if (error.data.code) {
|
|
160
|
-
// @ts-ignore
|
|
161
|
-
restoredError.code = error.data.code;
|
|
162
|
-
}
|
|
163
|
-
if (error.data.type) {
|
|
164
|
-
// @ts-ignore
|
|
165
|
-
restoredError.name = error.data.type;
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
if (error.stack) {
|
|
169
|
-
const lowerStack = restoredError.stack || '';
|
|
170
|
-
// @ts-ignore
|
|
171
|
-
const indexNewLine = getNewLineIndex(lowerStack);
|
|
172
|
-
const parentStack = getParentStack(error);
|
|
173
|
-
// @ts-ignore
|
|
174
|
-
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
175
|
-
}
|
|
176
|
-
if (error.codeFrame) {
|
|
177
|
-
// @ts-ignore
|
|
178
|
-
restoredError.codeFrame = error.codeFrame;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
return restoredError;
|
|
182
|
-
}
|
|
183
|
-
if (typeof error === 'string') {
|
|
184
|
-
return new Error(`JsonRpc Error: ${error}`);
|
|
185
|
-
}
|
|
186
|
-
return new Error(`JsonRpc Error: ${error}`);
|
|
187
|
-
};
|
|
188
|
-
const unwrapJsonRpcResult = responseMessage => {
|
|
189
|
-
if ('error' in responseMessage) {
|
|
190
|
-
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
191
|
-
throw restoredError;
|
|
192
|
-
}
|
|
193
|
-
if ('result' in responseMessage) {
|
|
194
|
-
return responseMessage.result;
|
|
195
|
-
}
|
|
196
|
-
throw new JsonRpcError('unexpected response message');
|
|
197
|
-
};
|
|
198
|
-
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
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
|
-
};
|
|
208
|
-
const getErrorProperty = (error, prettyError) => {
|
|
209
|
-
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
210
|
-
return {
|
|
211
|
-
code: MethodNotFound,
|
|
212
|
-
message: error.message,
|
|
213
|
-
data: error.stack
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
code: Custom,
|
|
218
|
-
message: prettyError.message,
|
|
219
|
-
data: {
|
|
220
|
-
stack: prettyError.stack,
|
|
221
|
-
codeFrame: prettyError.codeFrame,
|
|
222
|
-
type: getErrorType(prettyError),
|
|
223
|
-
code: prettyError.code,
|
|
224
|
-
name: prettyError.name
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
};
|
|
228
|
-
const create$1 = (message, error) => {
|
|
229
|
-
return {
|
|
230
|
-
jsonrpc: Two,
|
|
231
|
-
id: message.id,
|
|
232
|
-
error
|
|
233
|
-
};
|
|
234
|
-
};
|
|
235
|
-
const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
236
|
-
const prettyError = preparePrettyError(error);
|
|
237
|
-
logError(error, prettyError);
|
|
238
|
-
const errorProperty = getErrorProperty(error, prettyError);
|
|
239
|
-
return create$1(message, errorProperty);
|
|
240
|
-
};
|
|
241
|
-
const create = (message, result) => {
|
|
242
|
-
return {
|
|
243
|
-
jsonrpc: Two,
|
|
244
|
-
id: message.id,
|
|
245
|
-
result: result ?? null
|
|
246
|
-
};
|
|
247
|
-
};
|
|
248
|
-
const getSuccessResponse = (message, result) => {
|
|
249
|
-
const resultProperty = result ?? null;
|
|
250
|
-
return create(message, resultProperty);
|
|
251
|
-
};
|
|
252
|
-
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
253
|
-
try {
|
|
254
|
-
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
255
|
-
return getSuccessResponse(message, result);
|
|
256
|
-
} catch (error) {
|
|
257
|
-
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
const defaultPreparePrettyError = error => {
|
|
261
|
-
return error;
|
|
262
|
-
};
|
|
263
|
-
const defaultLogError = () => {
|
|
264
|
-
// ignore
|
|
265
|
-
};
|
|
266
|
-
const defaultRequiresSocket = () => {
|
|
267
|
-
return false;
|
|
268
|
-
};
|
|
269
|
-
const defaultResolve = resolve;
|
|
270
|
-
|
|
271
|
-
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
272
|
-
const normalizeParams = args => {
|
|
273
|
-
if (args.length === 1) {
|
|
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
|
-
};
|
|
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;
|
|
306
|
-
if ('id' in message) {
|
|
307
|
-
if ('method' in message) {
|
|
308
|
-
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
309
|
-
try {
|
|
310
|
-
ipc.send(response);
|
|
311
|
-
} catch (error) {
|
|
312
|
-
const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
|
|
313
|
-
ipc.send(errorResponse);
|
|
314
|
-
}
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
resolve(message.id, message);
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
if ('method' in message) {
|
|
321
|
-
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
throw new JsonRpcError('unexpected message');
|
|
325
|
-
};
|
|
326
|
-
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
327
|
-
const {
|
|
328
|
-
message,
|
|
329
|
-
promise
|
|
330
|
-
} = create$2(method, params);
|
|
331
|
-
{
|
|
332
|
-
ipc.send(message);
|
|
333
|
-
}
|
|
334
|
-
const responseMessage = await promise;
|
|
335
|
-
return unwrapJsonRpcResult(responseMessage);
|
|
336
|
-
};
|
|
337
|
-
const invoke$1 = (ipc, method, ...params) => {
|
|
338
|
-
return invokeHelper(ipc, method, params);
|
|
339
|
-
};
|
|
340
|
-
|
|
341
10
|
const state$1 = {
|
|
342
11
|
commands: Object.create(null)
|
|
343
12
|
};
|
|
@@ -406,14 +75,14 @@ const Auto = () => {
|
|
|
406
75
|
|
|
407
76
|
const getModule$1 = method => {
|
|
408
77
|
switch (method) {
|
|
78
|
+
case ElectronMessagePort:
|
|
79
|
+
return IpcChildWithElectronMessagePort;
|
|
80
|
+
case ElectronUtilityProcess:
|
|
81
|
+
return IpcChildWithElectronUtilityProcess;
|
|
409
82
|
case NodeForkedProcess:
|
|
410
83
|
return IpcChildWithNodeForkedProcess;
|
|
411
84
|
case NodeWorker:
|
|
412
85
|
return IpcChildWithNodeWorker;
|
|
413
|
-
case ElectronUtilityProcess:
|
|
414
|
-
return IpcChildWithElectronUtilityProcess;
|
|
415
|
-
case ElectronMessagePort:
|
|
416
|
-
return IpcChildWithElectronMessagePort;
|
|
417
86
|
case WebSocket:
|
|
418
87
|
return IpcChildWithWebSocket;
|
|
419
88
|
default:
|
|
@@ -425,9 +94,9 @@ const listen$1 = async ({
|
|
|
425
94
|
method,
|
|
426
95
|
...params
|
|
427
96
|
}) => {
|
|
428
|
-
const module =
|
|
97
|
+
const module = getModule$1(method);
|
|
429
98
|
// @ts-ignore
|
|
430
|
-
const rawIpc =
|
|
99
|
+
const rawIpc = module.listen(params);
|
|
431
100
|
// @ts-ignore
|
|
432
101
|
if (module.signal) {
|
|
433
102
|
// @ts-ignore
|
|
@@ -438,13 +107,6 @@ const listen$1 = async ({
|
|
|
438
107
|
return ipc;
|
|
439
108
|
};
|
|
440
109
|
|
|
441
|
-
const listen = async () => {
|
|
442
|
-
const ipc = await listen$1({
|
|
443
|
-
method: Auto()
|
|
444
|
-
});
|
|
445
|
-
handleIpc(ipc);
|
|
446
|
-
};
|
|
447
|
-
|
|
448
110
|
const MainProcess = -5;
|
|
449
111
|
|
|
450
112
|
const state = {
|
|
@@ -458,8 +120,8 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
458
120
|
object(messagePort);
|
|
459
121
|
// Assert.number(ipcId)
|
|
460
122
|
const ipc = await listen$1({
|
|
461
|
-
|
|
462
|
-
|
|
123
|
+
messagePort,
|
|
124
|
+
method: ElectronMessagePort
|
|
463
125
|
});
|
|
464
126
|
handleIpc(ipc);
|
|
465
127
|
if (ipcId === MainProcess) {
|
|
@@ -467,13 +129,9 @@ const handleElectronMessagePort = async (messagePort, ipcId) => {
|
|
|
467
129
|
}
|
|
468
130
|
};
|
|
469
131
|
|
|
470
|
-
const getMainProcessId = () => {
|
|
471
|
-
return process.ppid;
|
|
472
|
-
};
|
|
473
|
-
|
|
474
132
|
const isWindows = process.platform === 'win32';
|
|
475
133
|
|
|
476
|
-
const getModule = () => {
|
|
134
|
+
const getModule = async () => {
|
|
477
135
|
if (isWindows) {
|
|
478
136
|
return Promise.resolve().then(function () { return ListProcessesWithMemoryUsageWindows; });
|
|
479
137
|
}
|
|
@@ -484,13 +142,24 @@ const listProcessesWithMemoryUsage$2 = async rootPid => {
|
|
|
484
142
|
return module.listProcessesWithMemoryUsage(rootPid);
|
|
485
143
|
};
|
|
486
144
|
|
|
145
|
+
const getMainProcessId = () => {
|
|
146
|
+
return process.ppid;
|
|
147
|
+
};
|
|
148
|
+
|
|
487
149
|
const commandMap = {
|
|
488
150
|
'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
|
|
489
|
-
'
|
|
490
|
-
'
|
|
151
|
+
'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage': listProcessesWithMemoryUsage$2,
|
|
152
|
+
'ProcessId.getMainProcessId': getMainProcessId
|
|
491
153
|
// 'ElectronContextMenu.openContextMenu': ElectronWebContentsView.handleContextMenu,
|
|
492
154
|
};
|
|
493
155
|
|
|
156
|
+
const listen = async () => {
|
|
157
|
+
const ipc = await listen$1({
|
|
158
|
+
method: Auto()
|
|
159
|
+
});
|
|
160
|
+
handleIpc(ipc);
|
|
161
|
+
};
|
|
162
|
+
|
|
494
163
|
const main = async () => {
|
|
495
164
|
registerCommands(commandMap);
|
|
496
165
|
await listen();
|
|
@@ -498,6 +167,60 @@ const main = async () => {
|
|
|
498
167
|
|
|
499
168
|
main();
|
|
500
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
|
+
};
|
|
501
224
|
const getName = (pid, cmd, rootPid, pidMap) => {
|
|
502
225
|
number(pid);
|
|
503
226
|
string(cmd);
|
|
@@ -506,52 +229,18 @@ const getName = (pid, cmd, rootPid, pidMap) => {
|
|
|
506
229
|
if (pid === rootPid) {
|
|
507
230
|
return 'main';
|
|
508
231
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
if (cmd.includes('--type=gpu-process')) {
|
|
513
|
-
return 'gpu-process';
|
|
514
|
-
}
|
|
515
|
-
if (cmd.includes('extensionHostMain.js')) {
|
|
516
|
-
return 'extension-host';
|
|
517
|
-
}
|
|
518
|
-
if (cmd.includes('ptyHostMain.js')) {
|
|
519
|
-
return 'pty-host';
|
|
520
|
-
}
|
|
521
|
-
if (cmd.includes('--lvce-window-kind=process-explorer')) {
|
|
522
|
-
return 'process-explorer';
|
|
232
|
+
const patternName = getPatternName(cmd);
|
|
233
|
+
if (patternName) {
|
|
234
|
+
return patternName;
|
|
523
235
|
}
|
|
524
236
|
if (pid in pidMap) {
|
|
525
|
-
return pidMap[pid] ||
|
|
526
|
-
}
|
|
527
|
-
if (cmd.includes('--type=renderer')) {
|
|
528
|
-
return `renderer`;
|
|
529
|
-
}
|
|
530
|
-
if (cmd.includes('--type=utility')) {
|
|
531
|
-
return 'utility';
|
|
532
|
-
}
|
|
533
|
-
if (cmd.includes('tsserver.js')) {
|
|
534
|
-
return 'tsserver.js';
|
|
535
|
-
}
|
|
536
|
-
if (cmd.includes('typingsInstaller.js')) {
|
|
537
|
-
return 'typingsInstaller.js';
|
|
538
|
-
}
|
|
539
|
-
if (cmd.includes('extensionHostHelperProcessMain.js')) {
|
|
540
|
-
return 'extension-host-helper-process';
|
|
541
|
-
}
|
|
542
|
-
if (cmd.includes('/bin/rg') || cmd.includes('rg.exe')) {
|
|
543
|
-
return 'ripgrep';
|
|
237
|
+
return pidMap[pid] || '<unknown>';
|
|
544
238
|
}
|
|
545
|
-
|
|
546
|
-
|
|
239
|
+
const fallbackPatternName = getFallbackPatternName(cmd);
|
|
240
|
+
if (fallbackPatternName) {
|
|
241
|
+
return fallbackPatternName;
|
|
547
242
|
}
|
|
548
|
-
|
|
549
|
-
return 'sublime-text';
|
|
550
|
-
}
|
|
551
|
-
if (cmd.includes('\\conhost.exe')) {
|
|
552
|
-
return 'conhost.exe';
|
|
553
|
-
}
|
|
554
|
-
return `${cmd}`;
|
|
243
|
+
return cmd;
|
|
555
244
|
};
|
|
556
245
|
|
|
557
246
|
const ENOENT = 'ENOENT';
|
|
@@ -559,7 +248,7 @@ const ERR_DLOPEN_FAILED = 'ERR_DLOPEN_FAILED';
|
|
|
559
248
|
const ESRCH = 'ESRCH';
|
|
560
249
|
|
|
561
250
|
const isDlOpenError = error => {
|
|
562
|
-
return error
|
|
251
|
+
return error instanceof Error && 'code' in error && error.code === ERR_DLOPEN_FAILED;
|
|
563
252
|
};
|
|
564
253
|
|
|
565
254
|
const loadWindowProcessTree = async () => {
|
|
@@ -574,30 +263,14 @@ const loadWindowProcessTree = async () => {
|
|
|
574
263
|
};
|
|
575
264
|
|
|
576
265
|
const withResolvers = () => {
|
|
577
|
-
|
|
578
|
-
* @type {any}
|
|
579
|
-
*/
|
|
580
|
-
let _resolve;
|
|
581
|
-
/**
|
|
582
|
-
* @type {any}
|
|
583
|
-
*/
|
|
584
|
-
let _reject;
|
|
585
|
-
const promise = new Promise((resolve, reject) => {
|
|
586
|
-
_resolve = resolve;
|
|
587
|
-
_reject = reject;
|
|
588
|
-
});
|
|
589
|
-
return {
|
|
590
|
-
resolve: _resolve,
|
|
591
|
-
reject: _reject,
|
|
592
|
-
promise
|
|
593
|
-
};
|
|
266
|
+
return Promise.withResolvers();
|
|
594
267
|
};
|
|
595
268
|
|
|
596
269
|
const getProcessList = async (rootPid, flags) => {
|
|
597
270
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
598
271
|
const {
|
|
599
|
-
|
|
600
|
-
|
|
272
|
+
promise,
|
|
273
|
+
resolve
|
|
601
274
|
} = withResolvers();
|
|
602
275
|
WindowsProcessTree.getProcessList(rootPid, resolve, flags);
|
|
603
276
|
return promise;
|
|
@@ -605,20 +278,19 @@ const getProcessList = async (rootPid, flags) => {
|
|
|
605
278
|
const addCpuUsage = async processList => {
|
|
606
279
|
const WindowsProcessTree = await loadWindowProcessTree();
|
|
607
280
|
const {
|
|
608
|
-
|
|
609
|
-
|
|
281
|
+
promise,
|
|
282
|
+
resolve
|
|
610
283
|
} = withResolvers();
|
|
611
|
-
|
|
284
|
+
const mutableProcessList = processList.map(process => ({
|
|
285
|
+
...process
|
|
286
|
+
}));
|
|
287
|
+
WindowsProcessTree.getProcessCpuUsage(mutableProcessList, resolve);
|
|
612
288
|
return promise;
|
|
613
289
|
};
|
|
614
290
|
|
|
615
291
|
const Memory = 1;
|
|
616
292
|
const CommandLine = 2;
|
|
617
293
|
|
|
618
|
-
const createPidMap = async () => {
|
|
619
|
-
return invoke('CreatePidMap.createPidMap');
|
|
620
|
-
};
|
|
621
|
-
|
|
622
294
|
// listProcesses windows implementation based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
623
295
|
|
|
624
296
|
/**
|
|
@@ -628,18 +300,15 @@ const createPidMap = async () => {
|
|
|
628
300
|
*/
|
|
629
301
|
const toResultItem = (item, rootPid, pidMap) => {
|
|
630
302
|
return {
|
|
303
|
+
cmd: item.commandLine,
|
|
304
|
+
memory: item.memory,
|
|
631
305
|
name: getName(item.pid, item.commandLine, rootPid, pidMap),
|
|
632
306
|
pid: item.pid,
|
|
633
|
-
ppid: item.ppid
|
|
634
|
-
memory: item.memory,
|
|
635
|
-
cmd: item.commandLine
|
|
307
|
+
ppid: item.ppid
|
|
636
308
|
};
|
|
637
309
|
};
|
|
638
310
|
const toResult = (completeProcessList, rootPid, pidMap) => {
|
|
639
|
-
const results =
|
|
640
|
-
for (const item of completeProcessList) {
|
|
641
|
-
results.push(toResultItem(item, rootPid, pidMap));
|
|
642
|
-
}
|
|
311
|
+
const results = Array.from(completeProcessList, item => toResultItem(item, rootPid, pidMap));
|
|
643
312
|
return results;
|
|
644
313
|
};
|
|
645
314
|
const listProcessesWithMemoryUsage$1 = async rootPid => {
|
|
@@ -701,7 +370,7 @@ const parseMemory = content => {
|
|
|
701
370
|
|
|
702
371
|
const getContent = async pid => {
|
|
703
372
|
try {
|
|
704
|
-
const filePath = join('/proc',
|
|
373
|
+
const filePath = join('/proc', String(pid), 'statm');
|
|
705
374
|
const content = await readFile(filePath, Utf8);
|
|
706
375
|
return content;
|
|
707
376
|
} catch (error) {
|
|
@@ -764,17 +433,36 @@ const splitLines = lines => {
|
|
|
764
433
|
|
|
765
434
|
// parse ps output based on vscode https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/node/ps.ts (License MIT)
|
|
766
435
|
|
|
767
|
-
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
|
+
};
|
|
768
453
|
const parsePsOutputLine = line => {
|
|
769
454
|
string(line);
|
|
770
|
-
const
|
|
771
|
-
|
|
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) {
|
|
772
462
|
return {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
// load: parseInt(matches[3]),
|
|
777
|
-
// mem: parseInt(matches[4]),
|
|
463
|
+
cmd,
|
|
464
|
+
pid: Number.parseInt(pidField.value),
|
|
465
|
+
ppid: Number.parseInt(ppidField.value)
|
|
778
466
|
};
|
|
779
467
|
}
|
|
780
468
|
throw new Error(`line could not be parsed: ${line}`);
|
|
@@ -793,9 +481,9 @@ const parsePsOutput = (stdout, rootPid, pidMap) => {
|
|
|
793
481
|
const parsedLines = lines.map(parsePsOutputLine);
|
|
794
482
|
for (const parsedLine of parsedLines) {
|
|
795
483
|
const {
|
|
484
|
+
cmd,
|
|
796
485
|
pid,
|
|
797
|
-
ppid
|
|
798
|
-
cmd
|
|
486
|
+
ppid
|
|
799
487
|
} = parsedLine;
|
|
800
488
|
const depth = pid === rootPid ? 1 : depthMap[ppid];
|
|
801
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
|
}
|