@lvce-editor/file-system-process 1.2.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1388 -122
- package/package.json +1 -9
package/dist/index.js
CHANGED
|
@@ -1,20 +1,113 @@
|
|
|
1
1
|
import * as fs from 'node:fs/promises';
|
|
2
2
|
import * as os from 'node:os';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { string, object } from '@lvce-editor/assert';
|
|
5
|
-
import { VError } from '@lvce-editor/verror';
|
|
6
4
|
import { join } from 'node:path';
|
|
7
5
|
import { existsSync } from 'node:fs';
|
|
8
|
-
import { NodeWebSocketRpcClient, ElectronMessagePortRpcClient, ElectronUtilityProcessRpcClient, NodeWorkerRpcClient, NodeForkedProcessRpcClient } from '@lvce-editor/rpc';
|
|
9
|
-
import { invoke as invoke$1 } from '@lvce-editor/json-rpc';
|
|
10
6
|
import _trash from 'trash';
|
|
7
|
+
import { Buffer } from 'node:buffer';
|
|
8
|
+
|
|
9
|
+
class AssertionError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'AssertionError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const getType = value => {
|
|
16
|
+
switch (typeof value) {
|
|
17
|
+
case 'number':
|
|
18
|
+
return 'number';
|
|
19
|
+
case 'function':
|
|
20
|
+
return 'function';
|
|
21
|
+
case 'string':
|
|
22
|
+
return 'string';
|
|
23
|
+
case 'object':
|
|
24
|
+
if (value === null) {
|
|
25
|
+
return 'null';
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
return 'array';
|
|
29
|
+
}
|
|
30
|
+
return 'object';
|
|
31
|
+
case 'boolean':
|
|
32
|
+
return 'boolean';
|
|
33
|
+
default:
|
|
34
|
+
return 'unknown';
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const object = value => {
|
|
38
|
+
const type = getType(value);
|
|
39
|
+
if (type !== 'object') {
|
|
40
|
+
throw new AssertionError('expected value to be of type object');
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const string = value => {
|
|
44
|
+
const type = getType(value);
|
|
45
|
+
if (type !== 'string') {
|
|
46
|
+
throw new AssertionError('expected value to be of type string');
|
|
47
|
+
}
|
|
48
|
+
};
|
|
11
49
|
|
|
12
50
|
const Utf8 = 'utf8';
|
|
13
51
|
|
|
14
52
|
const ENOENT = 'ENOENT';
|
|
15
53
|
const EXDEV = 'EXDEV';
|
|
16
54
|
|
|
17
|
-
|
|
55
|
+
const normalizeLine = line => {
|
|
56
|
+
if (line.startsWith('Error: ')) {
|
|
57
|
+
return line.slice('Error: '.length);
|
|
58
|
+
}
|
|
59
|
+
if (line.startsWith('VError: ')) {
|
|
60
|
+
return line.slice('VError: '.length);
|
|
61
|
+
}
|
|
62
|
+
return line;
|
|
63
|
+
};
|
|
64
|
+
const getCombinedMessage = (error, message) => {
|
|
65
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
66
|
+
if (message) {
|
|
67
|
+
return `${message}: ${stringifiedError}`;
|
|
68
|
+
}
|
|
69
|
+
return stringifiedError;
|
|
70
|
+
};
|
|
71
|
+
const NewLine$2 = '\n';
|
|
72
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
73
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
74
|
+
};
|
|
75
|
+
const mergeStacks = (parent, child) => {
|
|
76
|
+
if (!child) {
|
|
77
|
+
return parent;
|
|
78
|
+
}
|
|
79
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
80
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
81
|
+
if (childNewLineIndex === -1) {
|
|
82
|
+
return parent;
|
|
83
|
+
}
|
|
84
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
85
|
+
const childRest = child.slice(childNewLineIndex);
|
|
86
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
87
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
88
|
+
return parentFirstLine + childRest;
|
|
89
|
+
}
|
|
90
|
+
return child;
|
|
91
|
+
};
|
|
92
|
+
class VError extends Error {
|
|
93
|
+
constructor(error, message) {
|
|
94
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
95
|
+
super(combinedMessage);
|
|
96
|
+
this.name = 'VError';
|
|
97
|
+
if (error instanceof Error) {
|
|
98
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
99
|
+
}
|
|
100
|
+
if (error.codeFrame) {
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
this.codeFrame = error.codeFrame;
|
|
103
|
+
}
|
|
104
|
+
if (error.code) {
|
|
105
|
+
// @ts-ignore
|
|
106
|
+
this.code = error.code;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
18
111
|
const getDisplayPath = path => {
|
|
19
112
|
if (path === '') {
|
|
20
113
|
return '<empty string>';
|
|
@@ -22,10 +115,8 @@ const getDisplayPath = path => {
|
|
|
22
115
|
return path;
|
|
23
116
|
};
|
|
24
117
|
class FileNotFoundError extends VError {
|
|
25
|
-
// @ts-ignore
|
|
26
118
|
constructor(path) {
|
|
27
119
|
super(`File not found: '${getDisplayPath(path)}'`);
|
|
28
|
-
// @ts-ignore
|
|
29
120
|
this.code = ENOENT;
|
|
30
121
|
}
|
|
31
122
|
}
|
|
@@ -39,10 +130,6 @@ const Socket = 8;
|
|
|
39
130
|
const Symlink = 9;
|
|
40
131
|
const Unknown = 12;
|
|
41
132
|
|
|
42
|
-
/**
|
|
43
|
-
* @param {import('fs').Dirent|import('fs').StatsBase} dirent
|
|
44
|
-
*/
|
|
45
|
-
// @ts-ignore
|
|
46
133
|
const getDirentType = dirent => {
|
|
47
134
|
if (dirent.isFile()) {
|
|
48
135
|
return File;
|
|
@@ -106,76 +193,57 @@ const isEnoentError = error => {
|
|
|
106
193
|
return isEnoentErrorLinux(error) || isEnoentErrorWindows(error);
|
|
107
194
|
};
|
|
108
195
|
|
|
109
|
-
const
|
|
110
|
-
|
|
196
|
+
const rpcs = Object.create(null);
|
|
197
|
+
const set$7 = (id, rpc) => {
|
|
198
|
+
rpcs[id] = rpc;
|
|
111
199
|
};
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const isElectron = Boolean(getElectronRunAsNode()) || 'electron' in process.versions;
|
|
115
|
-
|
|
116
|
-
const NodeWorker = 1;
|
|
117
|
-
const NodeForkedProcess = 2;
|
|
118
|
-
const ElectronUtilityProcess = 3;
|
|
119
|
-
const ElectronMessagePort = 4;
|
|
120
|
-
const WebSocket = 6;
|
|
121
|
-
const Auto = argv => {
|
|
122
|
-
if (argv.includes('--ipc-type=node-worker')) {
|
|
123
|
-
return NodeWorker;
|
|
124
|
-
}
|
|
125
|
-
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
126
|
-
return NodeForkedProcess;
|
|
127
|
-
}
|
|
128
|
-
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
129
|
-
return ElectronUtilityProcess;
|
|
130
|
-
}
|
|
131
|
-
throw new Error(`[file-system-process] unknown ipc type`);
|
|
200
|
+
const get$1 = id => {
|
|
201
|
+
return rpcs[id];
|
|
132
202
|
};
|
|
133
203
|
|
|
134
|
-
|
|
135
|
-
switch (method) {
|
|
136
|
-
case NodeForkedProcess:
|
|
137
|
-
return NodeForkedProcessRpcClient;
|
|
138
|
-
case NodeWorker:
|
|
139
|
-
return NodeWorkerRpcClient;
|
|
140
|
-
case ElectronUtilityProcess:
|
|
141
|
-
return ElectronUtilityProcessRpcClient;
|
|
142
|
-
case ElectronMessagePort:
|
|
143
|
-
return ElectronMessagePortRpcClient;
|
|
144
|
-
case WebSocket:
|
|
145
|
-
return NodeWebSocketRpcClient;
|
|
146
|
-
default:
|
|
147
|
-
throw new Error('unexpected ipc type');
|
|
148
|
-
}
|
|
149
|
-
};
|
|
204
|
+
/* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
150
205
|
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
206
|
+
const create$6 = rpcId => {
|
|
207
|
+
return {
|
|
208
|
+
// @ts-ignore
|
|
209
|
+
invoke(method, ...params) {
|
|
210
|
+
const rpc = get$1(rpcId);
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
return rpc.invoke(method, ...params);
|
|
213
|
+
},
|
|
214
|
+
// @ts-ignore
|
|
215
|
+
invokeAndTransfer(method, ...params) {
|
|
216
|
+
const rpc = get$1(rpcId);
|
|
217
|
+
// @ts-ignore
|
|
218
|
+
return rpc.invokeAndTransfer(method, ...params);
|
|
219
|
+
},
|
|
220
|
+
set(rpc) {
|
|
221
|
+
set$7(rpcId, rpc);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
168
224
|
};
|
|
169
|
-
const
|
|
170
|
-
|
|
225
|
+
const MainProcess$1 = -5;
|
|
226
|
+
const {
|
|
227
|
+
invoke: invoke$3,
|
|
228
|
+
set: set$3
|
|
229
|
+
} = create$6(MainProcess$1);
|
|
230
|
+
const MainProcess = {
|
|
231
|
+
__proto__: null,
|
|
232
|
+
invoke: invoke$3,
|
|
233
|
+
set: set$3
|
|
171
234
|
};
|
|
172
235
|
|
|
173
|
-
|
|
236
|
+
const {
|
|
237
|
+
invoke: invoke$1,
|
|
238
|
+
set: set$1
|
|
239
|
+
} = MainProcess;
|
|
240
|
+
|
|
174
241
|
const trash$2 = async path => {
|
|
175
242
|
if (!existsSync(path)) {
|
|
176
243
|
return;
|
|
177
244
|
}
|
|
178
|
-
|
|
245
|
+
// @ts-ignore
|
|
246
|
+
await invoke$1('Trash.trash', path);
|
|
179
247
|
};
|
|
180
248
|
|
|
181
249
|
// @ts-ignore
|
|
@@ -183,17 +251,22 @@ const trash$1 = async path => {
|
|
|
183
251
|
await _trash(path);
|
|
184
252
|
};
|
|
185
253
|
|
|
186
|
-
const
|
|
254
|
+
const getTrashFn = isElectron => {
|
|
187
255
|
if (isElectron) {
|
|
188
256
|
return trash$2;
|
|
189
257
|
}
|
|
190
258
|
return trash$1;
|
|
191
259
|
};
|
|
192
260
|
|
|
193
|
-
|
|
261
|
+
const getElectronRunAsNode = () => {
|
|
262
|
+
return process.env.ELECTRON_RUN_AS_NODE;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const isElectron = Boolean(getElectronRunAsNode()) || 'electron' in process.versions;
|
|
266
|
+
|
|
194
267
|
const trash = async path => {
|
|
195
268
|
try {
|
|
196
|
-
const fn =
|
|
269
|
+
const fn = getTrashFn(isElectron);
|
|
197
270
|
await fn(path);
|
|
198
271
|
} catch (error) {
|
|
199
272
|
throw new VError(error, 'Failed to move item to trash');
|
|
@@ -201,8 +274,6 @@ const trash = async path => {
|
|
|
201
274
|
};
|
|
202
275
|
|
|
203
276
|
// TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
|
|
204
|
-
|
|
205
|
-
// @ts-ignore
|
|
206
277
|
const assertUri = uri => {
|
|
207
278
|
if (!uri.startsWith('file://')) {
|
|
208
279
|
throw new Error(`path must be a valid file uri`);
|
|
@@ -224,20 +295,11 @@ const copy = async (sourceUri, targetUri) => {
|
|
|
224
295
|
throw new VError(error, `Failed to copy "${sourceUri}" to "${targetUri}"`);
|
|
225
296
|
}
|
|
226
297
|
};
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
*
|
|
230
|
-
* @param {string} uri
|
|
231
|
-
* @param {BufferEncoding} encoding
|
|
232
|
-
* @returns
|
|
233
|
-
*/
|
|
234
|
-
// @ts-ignore
|
|
235
298
|
const readFile = async (uri, encoding = Utf8) => {
|
|
236
299
|
try {
|
|
237
300
|
string(uri);
|
|
238
301
|
assertUri(uri);
|
|
239
302
|
const path = fileURLToPath(uri);
|
|
240
|
-
// @ts-ignore
|
|
241
303
|
const content = await fs.readFile(path, encoding);
|
|
242
304
|
return content;
|
|
243
305
|
} catch (error) {
|
|
@@ -247,14 +309,6 @@ const readFile = async (uri, encoding = Utf8) => {
|
|
|
247
309
|
throw new VError(error, `Failed to read file "${uri}"`);
|
|
248
310
|
}
|
|
249
311
|
};
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
*
|
|
253
|
-
* @param {string} uri
|
|
254
|
-
* @param {string} content
|
|
255
|
-
* @param {BufferEncoding} encoding
|
|
256
|
-
*/
|
|
257
|
-
// @ts-ignore
|
|
258
312
|
const writeFile = async (uri, content, encoding = Utf8) => {
|
|
259
313
|
try {
|
|
260
314
|
assertUri(uri);
|
|
@@ -263,7 +317,6 @@ const writeFile = async (uri, content, encoding = Utf8) => {
|
|
|
263
317
|
const path = fileURLToPath(uri);
|
|
264
318
|
// queue would be more correct for concurrent writes but also slower
|
|
265
319
|
// Queue.add(`writeFile/${path}`, () =>
|
|
266
|
-
// @ts-ignore
|
|
267
320
|
await fs.writeFile(path, content, encoding);
|
|
268
321
|
} catch (error) {
|
|
269
322
|
if (isEnoentError(error)) {
|
|
@@ -272,8 +325,6 @@ const writeFile = async (uri, content, encoding = Utf8) => {
|
|
|
272
325
|
throw new VError(error, `Failed to write to file "${uri}"`);
|
|
273
326
|
}
|
|
274
327
|
};
|
|
275
|
-
|
|
276
|
-
// @ts-ignore
|
|
277
328
|
const isOkayToRemove = path => {
|
|
278
329
|
if (path === '/') {
|
|
279
330
|
return false;
|
|
@@ -286,9 +337,7 @@ const isOkayToRemove = path => {
|
|
|
286
337
|
}
|
|
287
338
|
return true;
|
|
288
339
|
};
|
|
289
|
-
|
|
290
|
-
// @ts-ignore
|
|
291
|
-
const remove = async uri => {
|
|
340
|
+
const remove$1 = async uri => {
|
|
292
341
|
assertUri(uri);
|
|
293
342
|
const path = fileURLToPath(uri);
|
|
294
343
|
if (!isOkayToRemove(path)) {
|
|
@@ -304,19 +353,12 @@ const remove = async uri => {
|
|
|
304
353
|
throw new VError(error, `Failed to remove "${uri}"`);
|
|
305
354
|
}
|
|
306
355
|
};
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* @param {import('fs').Dirent} dirent
|
|
310
|
-
*/
|
|
311
|
-
// @ts-ignore
|
|
312
356
|
const toPrettyDirent = dirent => {
|
|
313
357
|
return {
|
|
314
358
|
name: dirent.name,
|
|
315
359
|
type: getDirentType(dirent)
|
|
316
360
|
};
|
|
317
361
|
};
|
|
318
|
-
|
|
319
|
-
// @ts-ignore
|
|
320
362
|
const readDirWithFileTypes = async uri => {
|
|
321
363
|
try {
|
|
322
364
|
assertUri(uri);
|
|
@@ -330,8 +372,6 @@ const readDirWithFileTypes = async uri => {
|
|
|
330
372
|
throw new VError(error, `Failed to read directory "${uri}"`);
|
|
331
373
|
}
|
|
332
374
|
};
|
|
333
|
-
|
|
334
|
-
// @ts-ignore
|
|
335
375
|
const mkdir = async uri => {
|
|
336
376
|
try {
|
|
337
377
|
assertUri(uri);
|
|
@@ -343,8 +383,6 @@ const mkdir = async uri => {
|
|
|
343
383
|
throw new VError(error, `Failed to create directory "${uri}"`);
|
|
344
384
|
}
|
|
345
385
|
};
|
|
346
|
-
|
|
347
|
-
// @ts-ignore
|
|
348
386
|
const fallbackRename = async (oldUri, newUri) => {
|
|
349
387
|
try {
|
|
350
388
|
const oldPath = fileURLToPath(oldUri);
|
|
@@ -359,8 +397,6 @@ const fallbackRename = async (oldUri, newUri) => {
|
|
|
359
397
|
throw new VError(error, `Failed to rename "${oldUri}" to "${newUri}"`);
|
|
360
398
|
}
|
|
361
399
|
};
|
|
362
|
-
|
|
363
|
-
// @ts-ignore
|
|
364
400
|
const rename = async (oldUri, newUri) => {
|
|
365
401
|
try {
|
|
366
402
|
const oldPath = fileURLToPath(oldUri);
|
|
@@ -376,23 +412,16 @@ const rename = async (oldUri, newUri) => {
|
|
|
376
412
|
const getPathSeparator = () => {
|
|
377
413
|
return '/';
|
|
378
414
|
};
|
|
379
|
-
|
|
380
|
-
// TODO handle error
|
|
381
|
-
// @ts-ignore
|
|
382
415
|
const stat = async uri => {
|
|
383
416
|
const path = fileURLToPath(uri);
|
|
384
417
|
const stats = await fs.stat(path);
|
|
385
418
|
const type = getDirentType(stats);
|
|
386
419
|
return type;
|
|
387
420
|
};
|
|
388
|
-
|
|
389
|
-
// @ts-ignore
|
|
390
421
|
const chmod = async (uri, permissions) => {
|
|
391
422
|
const path = fileURLToPath(uri);
|
|
392
423
|
await fs.chmod(path, permissions);
|
|
393
424
|
};
|
|
394
|
-
|
|
395
|
-
// @ts-ignore
|
|
396
425
|
const readJson = async uri => {
|
|
397
426
|
try {
|
|
398
427
|
string(uri);
|
|
@@ -408,14 +437,1198 @@ const readJson = async uri => {
|
|
|
408
437
|
throw new VError(error, `Failed to read file as json "${uri}"`);
|
|
409
438
|
}
|
|
410
439
|
};
|
|
411
|
-
|
|
412
|
-
// @ts-ignore
|
|
413
440
|
const getFolderSize = async uri => {
|
|
414
441
|
const path = fileURLToPath(uri);
|
|
415
442
|
const total = await getFolderSizeInternal(path);
|
|
416
443
|
return total;
|
|
417
444
|
};
|
|
418
445
|
|
|
446
|
+
const isMessagePort = value => {
|
|
447
|
+
return value && value instanceof MessagePort;
|
|
448
|
+
};
|
|
449
|
+
const isMessagePortMain = value => {
|
|
450
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
451
|
+
};
|
|
452
|
+
const isOffscreenCanvas = value => {
|
|
453
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
454
|
+
};
|
|
455
|
+
const isInstanceOf = (value, constructorName) => {
|
|
456
|
+
return value?.constructor?.name === constructorName;
|
|
457
|
+
};
|
|
458
|
+
const isSocket = value => {
|
|
459
|
+
return isInstanceOf(value, 'Socket');
|
|
460
|
+
};
|
|
461
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
462
|
+
const isTransferrable = value => {
|
|
463
|
+
for (const fn of transferrables) {
|
|
464
|
+
if (fn(value)) {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return false;
|
|
469
|
+
};
|
|
470
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
471
|
+
if (!value) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
if (isTransferrable(value)) {
|
|
475
|
+
transferrables.push(value);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
if (Array.isArray(value)) {
|
|
479
|
+
for (const item of value) {
|
|
480
|
+
walkValue(item, transferrables, isTransferrable);
|
|
481
|
+
}
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
if (typeof value === 'object') {
|
|
485
|
+
for (const property of Object.values(value)) {
|
|
486
|
+
walkValue(property, transferrables, isTransferrable);
|
|
487
|
+
}
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
const getTransferrables = value => {
|
|
492
|
+
const transferrables = [];
|
|
493
|
+
walkValue(value, transferrables, isTransferrable);
|
|
494
|
+
return transferrables;
|
|
495
|
+
};
|
|
496
|
+
const removeValues = (value, toRemove) => {
|
|
497
|
+
if (!value) {
|
|
498
|
+
return value;
|
|
499
|
+
}
|
|
500
|
+
if (Array.isArray(value)) {
|
|
501
|
+
const newItems = [];
|
|
502
|
+
for (const item of value) {
|
|
503
|
+
if (!toRemove.includes(item)) {
|
|
504
|
+
newItems.push(removeValues(item, toRemove));
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return newItems;
|
|
508
|
+
}
|
|
509
|
+
if (typeof value === 'object') {
|
|
510
|
+
const newObject = Object.create(null);
|
|
511
|
+
for (const [key, property] of Object.entries(value)) {
|
|
512
|
+
if (!toRemove.includes(property)) {
|
|
513
|
+
newObject[key] = removeValues(property, toRemove);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return newObject;
|
|
517
|
+
}
|
|
518
|
+
return value;
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
// workaround for electron not supporting transferrable objects
|
|
522
|
+
// as parameters. If the transferrable object is a parameter, in electron
|
|
523
|
+
// only an empty objected is received in the main process
|
|
524
|
+
const fixElectronParameters = value => {
|
|
525
|
+
const transfer = getTransferrables(value);
|
|
526
|
+
const newValue = removeValues(value, transfer);
|
|
527
|
+
return {
|
|
528
|
+
newValue,
|
|
529
|
+
transfer
|
|
530
|
+
};
|
|
531
|
+
};
|
|
532
|
+
const getActualDataElectron = event => {
|
|
533
|
+
const {
|
|
534
|
+
data,
|
|
535
|
+
ports
|
|
536
|
+
} = event;
|
|
537
|
+
if (ports.length === 0) {
|
|
538
|
+
return data;
|
|
539
|
+
}
|
|
540
|
+
return {
|
|
541
|
+
...data,
|
|
542
|
+
params: [...ports, ...data.params]
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
const attachEvents = that => {
|
|
546
|
+
const handleMessage = (...args) => {
|
|
547
|
+
const data = that.getData(...args);
|
|
548
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
549
|
+
data
|
|
550
|
+
}));
|
|
551
|
+
};
|
|
552
|
+
that.onMessage(handleMessage);
|
|
553
|
+
const handleClose = event => {
|
|
554
|
+
that.dispatchEvent(new Event('close'));
|
|
555
|
+
};
|
|
556
|
+
that.onClose(handleClose);
|
|
557
|
+
};
|
|
558
|
+
class Ipc extends EventTarget {
|
|
559
|
+
constructor(rawIpc) {
|
|
560
|
+
super();
|
|
561
|
+
this._rawIpc = rawIpc;
|
|
562
|
+
attachEvents(this);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
566
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
567
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
568
|
+
const NewLine$1 = '\n';
|
|
569
|
+
const joinLines$1 = lines => {
|
|
570
|
+
return lines.join(NewLine$1);
|
|
571
|
+
};
|
|
572
|
+
const RE_AT = /^\s+at/;
|
|
573
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
574
|
+
const isNormalStackLine = line => {
|
|
575
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
576
|
+
};
|
|
577
|
+
const getDetails = lines => {
|
|
578
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
579
|
+
if (index === -1) {
|
|
580
|
+
return {
|
|
581
|
+
actualMessage: joinLines$1(lines),
|
|
582
|
+
rest: []
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
let lastIndex = index - 1;
|
|
586
|
+
while (++lastIndex < lines.length) {
|
|
587
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
return {
|
|
592
|
+
actualMessage: lines[index - 1],
|
|
593
|
+
rest: lines.slice(index, lastIndex)
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
const splitLines$1 = lines => {
|
|
597
|
+
return lines.split(NewLine$1);
|
|
598
|
+
};
|
|
599
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
600
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
601
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
602
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
603
|
+
};
|
|
604
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
605
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
606
|
+
};
|
|
607
|
+
const getMessageCodeBlock = stderr => {
|
|
608
|
+
const lines = splitLines$1(stderr);
|
|
609
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
610
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
611
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
612
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
613
|
+
return relevantMessage;
|
|
614
|
+
};
|
|
615
|
+
const isModuleNotFoundMessage = line => {
|
|
616
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
617
|
+
};
|
|
618
|
+
const getModuleNotFoundError = stderr => {
|
|
619
|
+
const lines = splitLines$1(stderr);
|
|
620
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
621
|
+
const message = lines[messageIndex];
|
|
622
|
+
return {
|
|
623
|
+
message,
|
|
624
|
+
code: ERR_MODULE_NOT_FOUND
|
|
625
|
+
};
|
|
626
|
+
};
|
|
627
|
+
const isModuleNotFoundError = stderr => {
|
|
628
|
+
if (!stderr) {
|
|
629
|
+
return false;
|
|
630
|
+
}
|
|
631
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
632
|
+
};
|
|
633
|
+
const isModulesSyntaxError = stderr => {
|
|
634
|
+
if (!stderr) {
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
638
|
+
};
|
|
639
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
640
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
641
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
642
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
643
|
+
};
|
|
644
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
645
|
+
const message = getMessageCodeBlock(stderr);
|
|
646
|
+
return {
|
|
647
|
+
message: `Incompatible native node module: ${message}`,
|
|
648
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
649
|
+
};
|
|
650
|
+
};
|
|
651
|
+
const getModuleSyntaxError = () => {
|
|
652
|
+
return {
|
|
653
|
+
message: `ES Modules are not supported in electron`,
|
|
654
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
655
|
+
};
|
|
656
|
+
};
|
|
657
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
658
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
659
|
+
return getNativeModuleErrorMessage(stderr);
|
|
660
|
+
}
|
|
661
|
+
if (isModulesSyntaxError(stderr)) {
|
|
662
|
+
return getModuleSyntaxError();
|
|
663
|
+
}
|
|
664
|
+
if (isModuleNotFoundError(stderr)) {
|
|
665
|
+
return getModuleNotFoundError(stderr);
|
|
666
|
+
}
|
|
667
|
+
const lines = splitLines$1(stderr);
|
|
668
|
+
const {
|
|
669
|
+
actualMessage,
|
|
670
|
+
rest
|
|
671
|
+
} = getDetails(lines);
|
|
672
|
+
return {
|
|
673
|
+
message: actualMessage,
|
|
674
|
+
code: '',
|
|
675
|
+
stack: rest
|
|
676
|
+
};
|
|
677
|
+
};
|
|
678
|
+
class IpcError extends VError {
|
|
679
|
+
// @ts-ignore
|
|
680
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
681
|
+
if (stdout || stderr) {
|
|
682
|
+
// @ts-ignore
|
|
683
|
+
const {
|
|
684
|
+
message,
|
|
685
|
+
code,
|
|
686
|
+
stack
|
|
687
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
688
|
+
const cause = new Error(message);
|
|
689
|
+
// @ts-ignore
|
|
690
|
+
cause.code = code;
|
|
691
|
+
cause.stack = stack;
|
|
692
|
+
super(cause, betterMessage);
|
|
693
|
+
} else {
|
|
694
|
+
super(betterMessage);
|
|
695
|
+
}
|
|
696
|
+
// @ts-ignore
|
|
697
|
+
this.name = 'IpcError';
|
|
698
|
+
// @ts-ignore
|
|
699
|
+
this.stdout = stdout;
|
|
700
|
+
// @ts-ignore
|
|
701
|
+
this.stderr = stderr;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
const listen$b = ({
|
|
705
|
+
messagePort
|
|
706
|
+
}) => {
|
|
707
|
+
if (!isMessagePortMain(messagePort)) {
|
|
708
|
+
throw new IpcError('port must be of type MessagePortMain');
|
|
709
|
+
}
|
|
710
|
+
return messagePort;
|
|
711
|
+
};
|
|
712
|
+
const signal$c = messagePort => {
|
|
713
|
+
messagePort.start();
|
|
714
|
+
};
|
|
715
|
+
class IpcChildWithElectronMessagePort extends Ipc {
|
|
716
|
+
getData = getActualDataElectron;
|
|
717
|
+
send(message) {
|
|
718
|
+
this._rawIpc.postMessage(message);
|
|
719
|
+
}
|
|
720
|
+
sendAndTransfer(message) {
|
|
721
|
+
const {
|
|
722
|
+
newValue,
|
|
723
|
+
transfer
|
|
724
|
+
} = fixElectronParameters(message);
|
|
725
|
+
this._rawIpc.postMessage(newValue, transfer);
|
|
726
|
+
}
|
|
727
|
+
dispose() {
|
|
728
|
+
this._rawIpc.close();
|
|
729
|
+
}
|
|
730
|
+
onMessage(callback) {
|
|
731
|
+
this._rawIpc.on('message', callback);
|
|
732
|
+
}
|
|
733
|
+
onClose(callback) {
|
|
734
|
+
this._rawIpc.on('close', callback);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
const wrap$j = messagePort => {
|
|
738
|
+
return new IpcChildWithElectronMessagePort(messagePort);
|
|
739
|
+
};
|
|
740
|
+
const IpcChildWithElectronMessagePort$1 = {
|
|
741
|
+
__proto__: null,
|
|
742
|
+
listen: listen$b,
|
|
743
|
+
signal: signal$c,
|
|
744
|
+
wrap: wrap$j
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
// @ts-ignore
|
|
748
|
+
const getUtilityProcessPortData = event => {
|
|
749
|
+
const {
|
|
750
|
+
data,
|
|
751
|
+
ports
|
|
752
|
+
} = event;
|
|
753
|
+
if (ports.length === 0) {
|
|
754
|
+
return data;
|
|
755
|
+
}
|
|
756
|
+
return {
|
|
757
|
+
...data,
|
|
758
|
+
params: [...ports, ...data.params]
|
|
759
|
+
};
|
|
760
|
+
};
|
|
761
|
+
const readyMessage = 'ready';
|
|
762
|
+
const listen$a = () => {
|
|
763
|
+
// @ts-ignore
|
|
764
|
+
const {
|
|
765
|
+
parentPort
|
|
766
|
+
} = process;
|
|
767
|
+
if (!parentPort) {
|
|
768
|
+
throw new Error('parent port must be defined');
|
|
769
|
+
}
|
|
770
|
+
return parentPort;
|
|
771
|
+
};
|
|
772
|
+
const signal$b = parentPort => {
|
|
773
|
+
parentPort.postMessage(readyMessage);
|
|
774
|
+
};
|
|
775
|
+
class IpcChildWithElectronUtilityProcess extends Ipc {
|
|
776
|
+
getData(event) {
|
|
777
|
+
return getUtilityProcessPortData(event);
|
|
778
|
+
}
|
|
779
|
+
send(message) {
|
|
780
|
+
this._rawIpc.postMessage(message);
|
|
781
|
+
}
|
|
782
|
+
sendAndTransfer(message) {
|
|
783
|
+
const {
|
|
784
|
+
newValue,
|
|
785
|
+
transfer
|
|
786
|
+
} = fixElectronParameters(message);
|
|
787
|
+
this._rawIpc.postMessage(newValue, transfer);
|
|
788
|
+
}
|
|
789
|
+
dispose() {
|
|
790
|
+
this._rawIpc.close();
|
|
791
|
+
}
|
|
792
|
+
onClose(callback) {
|
|
793
|
+
this._rawIpc.on('close', callback);
|
|
794
|
+
}
|
|
795
|
+
onMessage(callback) {
|
|
796
|
+
this._rawIpc.on('message', callback);
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
const wrap$i = parentPort => {
|
|
800
|
+
return new IpcChildWithElectronUtilityProcess(parentPort);
|
|
801
|
+
};
|
|
802
|
+
const IpcChildWithElectronUtilityProcess$1 = {
|
|
803
|
+
__proto__: null,
|
|
804
|
+
listen: listen$a,
|
|
805
|
+
signal: signal$b,
|
|
806
|
+
wrap: wrap$i
|
|
807
|
+
};
|
|
808
|
+
const getActualData = (message, handle) => {
|
|
809
|
+
if (handle) {
|
|
810
|
+
return {
|
|
811
|
+
...message,
|
|
812
|
+
params: [handle, ...message.params]
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
return message;
|
|
816
|
+
};
|
|
817
|
+
const getTransferrablesNode = value => {
|
|
818
|
+
const transferrables = getTransferrables(value);
|
|
819
|
+
if (transferrables.length === 0) {
|
|
820
|
+
throw new Error(`no transferrables found`);
|
|
821
|
+
}
|
|
822
|
+
return transferrables[0];
|
|
823
|
+
};
|
|
824
|
+
const listen$5 = async () => {
|
|
825
|
+
if (!process.send) {
|
|
826
|
+
throw new Error('process.send must be defined');
|
|
827
|
+
}
|
|
828
|
+
return process;
|
|
829
|
+
};
|
|
830
|
+
const signal$7 = process => {
|
|
831
|
+
process.send(readyMessage);
|
|
832
|
+
};
|
|
833
|
+
class IpcChildWithNodeForkedProcess extends Ipc {
|
|
834
|
+
getData(message, handle) {
|
|
835
|
+
return getActualData(message, handle);
|
|
836
|
+
}
|
|
837
|
+
onClose(callback) {
|
|
838
|
+
this._rawIpc.on('close', callback);
|
|
839
|
+
}
|
|
840
|
+
send(message) {
|
|
841
|
+
this._rawIpc.send(message);
|
|
842
|
+
}
|
|
843
|
+
onMessage(callback) {
|
|
844
|
+
this._rawIpc.on('message', callback);
|
|
845
|
+
}
|
|
846
|
+
sendAndTransfer(message) {
|
|
847
|
+
const transfer = getTransferrablesNode(message);
|
|
848
|
+
this._rawIpc.send(message, transfer);
|
|
849
|
+
}
|
|
850
|
+
dispose() {
|
|
851
|
+
// ignore
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
const wrap$d = process => {
|
|
855
|
+
return new IpcChildWithNodeForkedProcess(process);
|
|
856
|
+
};
|
|
857
|
+
const IpcChildWithNodeForkedProcess$1 = {
|
|
858
|
+
__proto__: null,
|
|
859
|
+
listen: listen$5,
|
|
860
|
+
signal: signal$7,
|
|
861
|
+
wrap: wrap$d
|
|
862
|
+
};
|
|
863
|
+
const listen$3 = async () => {
|
|
864
|
+
const {
|
|
865
|
+
parentPort
|
|
866
|
+
} = await import('node:worker_threads');
|
|
867
|
+
if (!parentPort) {
|
|
868
|
+
throw new IpcError('parentPort is required');
|
|
869
|
+
}
|
|
870
|
+
return parentPort;
|
|
871
|
+
};
|
|
872
|
+
const signal$5 = parentPort => {
|
|
873
|
+
parentPort.postMessage(readyMessage);
|
|
874
|
+
};
|
|
875
|
+
class IpcChildWithNodeWorker extends Ipc {
|
|
876
|
+
getData(data) {
|
|
877
|
+
return data;
|
|
878
|
+
}
|
|
879
|
+
onClose(callback) {
|
|
880
|
+
this._rawIpc.on('close', callback);
|
|
881
|
+
}
|
|
882
|
+
send(message) {
|
|
883
|
+
this._rawIpc.postMessage(message);
|
|
884
|
+
}
|
|
885
|
+
onMessage(callback) {
|
|
886
|
+
this._rawIpc.on('message', callback);
|
|
887
|
+
}
|
|
888
|
+
sendAndTransfer(message) {
|
|
889
|
+
const transfer = getTransferrablesNode(message);
|
|
890
|
+
this._rawIpc.postMessage(message, transfer);
|
|
891
|
+
}
|
|
892
|
+
dispose() {
|
|
893
|
+
this._rawIpc.close();
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
const wrap$b = parentPort => {
|
|
897
|
+
return new IpcChildWithNodeWorker(parentPort);
|
|
898
|
+
};
|
|
899
|
+
const IpcChildWithNodeWorker$1 = {
|
|
900
|
+
__proto__: null,
|
|
901
|
+
listen: listen$3,
|
|
902
|
+
signal: signal$5,
|
|
903
|
+
wrap: wrap$b
|
|
904
|
+
};
|
|
905
|
+
const Open = 2;
|
|
906
|
+
const Close = 3;
|
|
907
|
+
const addListener = (emitter, type, callback) => {
|
|
908
|
+
if ('addEventListener' in emitter) {
|
|
909
|
+
emitter.addEventListener(type, callback);
|
|
910
|
+
} else {
|
|
911
|
+
emitter.on(type, callback);
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
const removeListener = (emitter, type, callback) => {
|
|
915
|
+
if ('removeEventListener' in emitter) {
|
|
916
|
+
emitter.removeEventListener(type, callback);
|
|
917
|
+
} else {
|
|
918
|
+
emitter.off(type, callback);
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
const getFirstEvent = (eventEmitter, eventMap) => {
|
|
922
|
+
const {
|
|
923
|
+
resolve,
|
|
924
|
+
promise
|
|
925
|
+
} = Promise.withResolvers();
|
|
926
|
+
const listenerMap = Object.create(null);
|
|
927
|
+
const cleanup = value => {
|
|
928
|
+
for (const event of Object.keys(eventMap)) {
|
|
929
|
+
removeListener(eventEmitter, event, listenerMap[event]);
|
|
930
|
+
}
|
|
931
|
+
resolve(value);
|
|
932
|
+
};
|
|
933
|
+
for (const [event, type] of Object.entries(eventMap)) {
|
|
934
|
+
const listener = event => {
|
|
935
|
+
cleanup({
|
|
936
|
+
type,
|
|
937
|
+
event
|
|
938
|
+
});
|
|
939
|
+
};
|
|
940
|
+
addListener(eventEmitter, event, listener);
|
|
941
|
+
listenerMap[event] = listener;
|
|
942
|
+
}
|
|
943
|
+
return promise;
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// @ts-ignore
|
|
947
|
+
const getFirstWebSocketEvent = async webSocket => {
|
|
948
|
+
// @ts-ignore
|
|
949
|
+
const {
|
|
950
|
+
WebSocket
|
|
951
|
+
} = await import('ws');
|
|
952
|
+
switch (webSocket.readyState) {
|
|
953
|
+
case WebSocket.OPEN:
|
|
954
|
+
return {
|
|
955
|
+
type: Open,
|
|
956
|
+
event: undefined
|
|
957
|
+
};
|
|
958
|
+
case WebSocket.CLOSED:
|
|
959
|
+
return {
|
|
960
|
+
type: Close,
|
|
961
|
+
event: undefined
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
// @ts-ignore
|
|
965
|
+
const {
|
|
966
|
+
type,
|
|
967
|
+
event
|
|
968
|
+
} = await getFirstEvent(webSocket, {
|
|
969
|
+
open: Open,
|
|
970
|
+
close: Close
|
|
971
|
+
});
|
|
972
|
+
return {
|
|
973
|
+
type,
|
|
974
|
+
event
|
|
975
|
+
};
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
// @ts-ignore
|
|
979
|
+
const isWebSocketOpen = async webSocket => {
|
|
980
|
+
// @ts-ignore
|
|
981
|
+
const {
|
|
982
|
+
WebSocket
|
|
983
|
+
} = await import('ws');
|
|
984
|
+
return webSocket.readyState === WebSocket.OPEN;
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
// @ts-ignore
|
|
988
|
+
const serialize = message => {
|
|
989
|
+
return JSON.stringify(message);
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
// @ts-ignore
|
|
993
|
+
const deserialize = message => {
|
|
994
|
+
return JSON.parse(message.toString());
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
// @ts-ignore
|
|
998
|
+
const handleUpgrade$1 = async (...args) => {
|
|
999
|
+
const module = await Promise.resolve().then(function () { return index; });
|
|
1000
|
+
// @ts-ignore
|
|
1001
|
+
return module.handleUpgrade(...args);
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
// @ts-ignore
|
|
1005
|
+
const listen$1$1 = async ({
|
|
1006
|
+
request,
|
|
1007
|
+
handle
|
|
1008
|
+
}) => {
|
|
1009
|
+
if (!request) {
|
|
1010
|
+
throw new IpcError('request must be defined');
|
|
1011
|
+
}
|
|
1012
|
+
if (!handle) {
|
|
1013
|
+
throw new IpcError('handle must be defined');
|
|
1014
|
+
}
|
|
1015
|
+
const webSocket = await handleUpgrade$1(request, handle);
|
|
1016
|
+
webSocket.pause();
|
|
1017
|
+
if (!(await isWebSocketOpen(webSocket))) {
|
|
1018
|
+
await getFirstWebSocketEvent(webSocket);
|
|
1019
|
+
}
|
|
1020
|
+
return webSocket;
|
|
1021
|
+
};
|
|
1022
|
+
const signal$4 = webSocket => {
|
|
1023
|
+
webSocket.resume();
|
|
1024
|
+
};
|
|
1025
|
+
|
|
1026
|
+
// @ts-ignore
|
|
1027
|
+
const wrap$9 = webSocket => {
|
|
1028
|
+
return {
|
|
1029
|
+
webSocket,
|
|
1030
|
+
/**
|
|
1031
|
+
* @type {any}
|
|
1032
|
+
*/
|
|
1033
|
+
wrappedListener: undefined,
|
|
1034
|
+
// @ts-ignore
|
|
1035
|
+
on(event, listener) {
|
|
1036
|
+
switch (event) {
|
|
1037
|
+
case 'message':
|
|
1038
|
+
// @ts-ignore
|
|
1039
|
+
const wrappedListener = message => {
|
|
1040
|
+
const data = deserialize(message);
|
|
1041
|
+
const event = {
|
|
1042
|
+
data,
|
|
1043
|
+
target: this
|
|
1044
|
+
};
|
|
1045
|
+
listener(event);
|
|
1046
|
+
};
|
|
1047
|
+
webSocket.on('message', wrappedListener);
|
|
1048
|
+
break;
|
|
1049
|
+
case 'close':
|
|
1050
|
+
webSocket.on('close', listener);
|
|
1051
|
+
break;
|
|
1052
|
+
default:
|
|
1053
|
+
throw new Error('unknown event listener type');
|
|
1054
|
+
}
|
|
1055
|
+
},
|
|
1056
|
+
// @ts-ignore
|
|
1057
|
+
off(event, listener) {
|
|
1058
|
+
this.webSocket.off(event, listener);
|
|
1059
|
+
},
|
|
1060
|
+
// @ts-ignore
|
|
1061
|
+
send(message) {
|
|
1062
|
+
const stringifiedMessage = serialize(message);
|
|
1063
|
+
this.webSocket.send(stringifiedMessage);
|
|
1064
|
+
},
|
|
1065
|
+
dispose() {
|
|
1066
|
+
this.webSocket.close();
|
|
1067
|
+
},
|
|
1068
|
+
start() {
|
|
1069
|
+
throw new Error('start method is deprecated');
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
};
|
|
1073
|
+
const IpcChildWithWebSocket = {
|
|
1074
|
+
__proto__: null,
|
|
1075
|
+
listen: listen$1$1,
|
|
1076
|
+
signal: signal$4,
|
|
1077
|
+
wrap: wrap$9
|
|
1078
|
+
};
|
|
1079
|
+
|
|
1080
|
+
const Two = '2.0';
|
|
1081
|
+
const create$4$1 = (method, params) => {
|
|
1082
|
+
return {
|
|
1083
|
+
jsonrpc: Two,
|
|
1084
|
+
method,
|
|
1085
|
+
params
|
|
1086
|
+
};
|
|
1087
|
+
};
|
|
1088
|
+
const callbacks = Object.create(null);
|
|
1089
|
+
const set = (id, fn) => {
|
|
1090
|
+
callbacks[id] = fn;
|
|
1091
|
+
};
|
|
1092
|
+
const get = id => {
|
|
1093
|
+
return callbacks[id];
|
|
1094
|
+
};
|
|
1095
|
+
const remove = id => {
|
|
1096
|
+
delete callbacks[id];
|
|
1097
|
+
};
|
|
1098
|
+
let id = 0;
|
|
1099
|
+
const create$3 = () => {
|
|
1100
|
+
return ++id;
|
|
1101
|
+
};
|
|
1102
|
+
const registerPromise = () => {
|
|
1103
|
+
const id = create$3();
|
|
1104
|
+
const {
|
|
1105
|
+
resolve,
|
|
1106
|
+
promise
|
|
1107
|
+
} = Promise.withResolvers();
|
|
1108
|
+
set(id, resolve);
|
|
1109
|
+
return {
|
|
1110
|
+
id,
|
|
1111
|
+
promise
|
|
1112
|
+
};
|
|
1113
|
+
};
|
|
1114
|
+
const create$2 = (method, params) => {
|
|
1115
|
+
const {
|
|
1116
|
+
id,
|
|
1117
|
+
promise
|
|
1118
|
+
} = registerPromise();
|
|
1119
|
+
const message = {
|
|
1120
|
+
jsonrpc: Two,
|
|
1121
|
+
method,
|
|
1122
|
+
params,
|
|
1123
|
+
id
|
|
1124
|
+
};
|
|
1125
|
+
return {
|
|
1126
|
+
message,
|
|
1127
|
+
promise
|
|
1128
|
+
};
|
|
1129
|
+
};
|
|
1130
|
+
class JsonRpcError extends Error {
|
|
1131
|
+
constructor(message) {
|
|
1132
|
+
super(message);
|
|
1133
|
+
this.name = 'JsonRpcError';
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const NewLine = '\n';
|
|
1137
|
+
const DomException = 'DOMException';
|
|
1138
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
1139
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
1140
|
+
const TypeError$1 = 'TypeError';
|
|
1141
|
+
const getErrorConstructor = (message, type) => {
|
|
1142
|
+
if (type) {
|
|
1143
|
+
switch (type) {
|
|
1144
|
+
case DomException:
|
|
1145
|
+
return DOMException;
|
|
1146
|
+
case TypeError$1:
|
|
1147
|
+
return TypeError;
|
|
1148
|
+
case SyntaxError$1:
|
|
1149
|
+
return SyntaxError;
|
|
1150
|
+
case ReferenceError$1:
|
|
1151
|
+
return ReferenceError;
|
|
1152
|
+
default:
|
|
1153
|
+
return Error;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
if (message.startsWith('TypeError: ')) {
|
|
1157
|
+
return TypeError;
|
|
1158
|
+
}
|
|
1159
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
1160
|
+
return SyntaxError;
|
|
1161
|
+
}
|
|
1162
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
1163
|
+
return ReferenceError;
|
|
1164
|
+
}
|
|
1165
|
+
return Error;
|
|
1166
|
+
};
|
|
1167
|
+
const constructError = (message, type, name) => {
|
|
1168
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
1169
|
+
if (ErrorConstructor === DOMException && name) {
|
|
1170
|
+
return new ErrorConstructor(message, name);
|
|
1171
|
+
}
|
|
1172
|
+
if (ErrorConstructor === Error) {
|
|
1173
|
+
const error = new Error(message);
|
|
1174
|
+
if (name && name !== 'VError') {
|
|
1175
|
+
error.name = name;
|
|
1176
|
+
}
|
|
1177
|
+
return error;
|
|
1178
|
+
}
|
|
1179
|
+
return new ErrorConstructor(message);
|
|
1180
|
+
};
|
|
1181
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
1182
|
+
return string.indexOf(NewLine, startIndex);
|
|
1183
|
+
};
|
|
1184
|
+
const getParentStack = error => {
|
|
1185
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
1186
|
+
if (parentStack.startsWith(' at')) {
|
|
1187
|
+
parentStack = error.message + NewLine + parentStack;
|
|
1188
|
+
}
|
|
1189
|
+
return parentStack;
|
|
1190
|
+
};
|
|
1191
|
+
const joinLines = lines => {
|
|
1192
|
+
return lines.join(NewLine);
|
|
1193
|
+
};
|
|
1194
|
+
const MethodNotFound = -32601;
|
|
1195
|
+
const Custom = -32001;
|
|
1196
|
+
const splitLines = lines => {
|
|
1197
|
+
return lines.split(NewLine);
|
|
1198
|
+
};
|
|
1199
|
+
const restoreJsonRpcError = error => {
|
|
1200
|
+
if (error && error instanceof Error) {
|
|
1201
|
+
return error;
|
|
1202
|
+
}
|
|
1203
|
+
const currentStack = joinLines(splitLines(new Error().stack || '').slice(1));
|
|
1204
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
1205
|
+
const restoredError = new JsonRpcError(error.message);
|
|
1206
|
+
const parentStack = getParentStack(error);
|
|
1207
|
+
restoredError.stack = parentStack + NewLine + currentStack;
|
|
1208
|
+
return restoredError;
|
|
1209
|
+
}
|
|
1210
|
+
if (error && error.message) {
|
|
1211
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
1212
|
+
if (error.data) {
|
|
1213
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
1214
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
1215
|
+
} else if (error.data.stack) {
|
|
1216
|
+
restoredError.stack = error.data.stack;
|
|
1217
|
+
}
|
|
1218
|
+
if (error.data.codeFrame) {
|
|
1219
|
+
// @ts-ignore
|
|
1220
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
1221
|
+
}
|
|
1222
|
+
if (error.data.code) {
|
|
1223
|
+
// @ts-ignore
|
|
1224
|
+
restoredError.code = error.data.code;
|
|
1225
|
+
}
|
|
1226
|
+
if (error.data.type) {
|
|
1227
|
+
// @ts-ignore
|
|
1228
|
+
restoredError.name = error.data.type;
|
|
1229
|
+
}
|
|
1230
|
+
} else {
|
|
1231
|
+
if (error.stack) {
|
|
1232
|
+
const lowerStack = restoredError.stack || '';
|
|
1233
|
+
// @ts-ignore
|
|
1234
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
1235
|
+
const parentStack = getParentStack(error);
|
|
1236
|
+
// @ts-ignore
|
|
1237
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
1238
|
+
}
|
|
1239
|
+
if (error.codeFrame) {
|
|
1240
|
+
// @ts-ignore
|
|
1241
|
+
restoredError.codeFrame = error.codeFrame;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
return restoredError;
|
|
1245
|
+
}
|
|
1246
|
+
if (typeof error === 'string') {
|
|
1247
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
1248
|
+
}
|
|
1249
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
1250
|
+
};
|
|
1251
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
1252
|
+
if ('error' in responseMessage) {
|
|
1253
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
1254
|
+
throw restoredError;
|
|
1255
|
+
}
|
|
1256
|
+
if ('result' in responseMessage) {
|
|
1257
|
+
return responseMessage.result;
|
|
1258
|
+
}
|
|
1259
|
+
throw new JsonRpcError('unexpected response message');
|
|
1260
|
+
};
|
|
1261
|
+
const warn = (...args) => {
|
|
1262
|
+
console.warn(...args);
|
|
1263
|
+
};
|
|
1264
|
+
const resolve = (id, response) => {
|
|
1265
|
+
const fn = get(id);
|
|
1266
|
+
if (!fn) {
|
|
1267
|
+
console.log(response);
|
|
1268
|
+
warn(`callback ${id} may already be disposed`);
|
|
1269
|
+
return;
|
|
1270
|
+
}
|
|
1271
|
+
fn(response);
|
|
1272
|
+
remove(id);
|
|
1273
|
+
};
|
|
1274
|
+
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
1275
|
+
const getErrorType = prettyError => {
|
|
1276
|
+
if (prettyError && prettyError.type) {
|
|
1277
|
+
return prettyError.type;
|
|
1278
|
+
}
|
|
1279
|
+
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
|
|
1280
|
+
return prettyError.constructor.name;
|
|
1281
|
+
}
|
|
1282
|
+
return undefined;
|
|
1283
|
+
};
|
|
1284
|
+
const getErrorProperty = (error, prettyError) => {
|
|
1285
|
+
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
1286
|
+
return {
|
|
1287
|
+
code: MethodNotFound,
|
|
1288
|
+
message: error.message,
|
|
1289
|
+
data: error.stack
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
return {
|
|
1293
|
+
code: Custom,
|
|
1294
|
+
message: prettyError.message,
|
|
1295
|
+
data: {
|
|
1296
|
+
stack: prettyError.stack,
|
|
1297
|
+
codeFrame: prettyError.codeFrame,
|
|
1298
|
+
type: getErrorType(prettyError),
|
|
1299
|
+
code: prettyError.code,
|
|
1300
|
+
name: prettyError.name
|
|
1301
|
+
}
|
|
1302
|
+
};
|
|
1303
|
+
};
|
|
1304
|
+
const create$1 = (message, error) => {
|
|
1305
|
+
return {
|
|
1306
|
+
jsonrpc: Two,
|
|
1307
|
+
id: message.id,
|
|
1308
|
+
error
|
|
1309
|
+
};
|
|
1310
|
+
};
|
|
1311
|
+
const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
1312
|
+
const prettyError = preparePrettyError(error);
|
|
1313
|
+
logError(error, prettyError);
|
|
1314
|
+
const errorProperty = getErrorProperty(error, prettyError);
|
|
1315
|
+
return create$1(message, errorProperty);
|
|
1316
|
+
};
|
|
1317
|
+
const create = (message, result) => {
|
|
1318
|
+
return {
|
|
1319
|
+
jsonrpc: Two,
|
|
1320
|
+
id: message.id,
|
|
1321
|
+
result: result ?? null
|
|
1322
|
+
};
|
|
1323
|
+
};
|
|
1324
|
+
const getSuccessResponse = (message, result) => {
|
|
1325
|
+
const resultProperty = result ?? null;
|
|
1326
|
+
return create(message, resultProperty);
|
|
1327
|
+
};
|
|
1328
|
+
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
1329
|
+
try {
|
|
1330
|
+
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
1331
|
+
return getSuccessResponse(message, result);
|
|
1332
|
+
} catch (error) {
|
|
1333
|
+
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
const defaultPreparePrettyError = error => {
|
|
1337
|
+
return error;
|
|
1338
|
+
};
|
|
1339
|
+
const defaultLogError = () => {
|
|
1340
|
+
// ignore
|
|
1341
|
+
};
|
|
1342
|
+
const defaultRequiresSocket = () => {
|
|
1343
|
+
return false;
|
|
1344
|
+
};
|
|
1345
|
+
const defaultResolve = resolve;
|
|
1346
|
+
|
|
1347
|
+
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
1348
|
+
const normalizeParams = args => {
|
|
1349
|
+
if (args.length === 1) {
|
|
1350
|
+
const options = args[0];
|
|
1351
|
+
return {
|
|
1352
|
+
ipc: options.ipc,
|
|
1353
|
+
message: options.message,
|
|
1354
|
+
execute: options.execute,
|
|
1355
|
+
resolve: options.resolve || defaultResolve,
|
|
1356
|
+
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
1357
|
+
logError: options.logError || defaultLogError,
|
|
1358
|
+
requiresSocket: options.requiresSocket || defaultRequiresSocket
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
return {
|
|
1362
|
+
ipc: args[0],
|
|
1363
|
+
message: args[1],
|
|
1364
|
+
execute: args[2],
|
|
1365
|
+
resolve: args[3],
|
|
1366
|
+
preparePrettyError: args[4],
|
|
1367
|
+
logError: args[5],
|
|
1368
|
+
requiresSocket: args[6]
|
|
1369
|
+
};
|
|
1370
|
+
};
|
|
1371
|
+
const handleJsonRpcMessage = async (...args) => {
|
|
1372
|
+
const options = normalizeParams(args);
|
|
1373
|
+
const {
|
|
1374
|
+
message,
|
|
1375
|
+
ipc,
|
|
1376
|
+
execute,
|
|
1377
|
+
resolve,
|
|
1378
|
+
preparePrettyError,
|
|
1379
|
+
logError,
|
|
1380
|
+
requiresSocket
|
|
1381
|
+
} = options;
|
|
1382
|
+
if ('id' in message) {
|
|
1383
|
+
if ('method' in message) {
|
|
1384
|
+
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
1385
|
+
try {
|
|
1386
|
+
ipc.send(response);
|
|
1387
|
+
} catch (error) {
|
|
1388
|
+
const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
|
|
1389
|
+
ipc.send(errorResponse);
|
|
1390
|
+
}
|
|
1391
|
+
return;
|
|
1392
|
+
}
|
|
1393
|
+
resolve(message.id, message);
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
if ('method' in message) {
|
|
1397
|
+
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
throw new JsonRpcError('unexpected message');
|
|
1401
|
+
};
|
|
1402
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
1403
|
+
const {
|
|
1404
|
+
message,
|
|
1405
|
+
promise
|
|
1406
|
+
} = create$2(method, params);
|
|
1407
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
1408
|
+
ipc.sendAndTransfer(message);
|
|
1409
|
+
} else {
|
|
1410
|
+
ipc.send(message);
|
|
1411
|
+
}
|
|
1412
|
+
const responseMessage = await promise;
|
|
1413
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
1414
|
+
};
|
|
1415
|
+
const send = (transport, method, ...params) => {
|
|
1416
|
+
const message = create$4$1(method, params);
|
|
1417
|
+
transport.send(message);
|
|
1418
|
+
};
|
|
1419
|
+
const invoke = (ipc, method, ...params) => {
|
|
1420
|
+
return invokeHelper(ipc, method, params, false);
|
|
1421
|
+
};
|
|
1422
|
+
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
1423
|
+
return invokeHelper(ipc, method, params, true);
|
|
1424
|
+
};
|
|
1425
|
+
|
|
1426
|
+
const commands = Object.create(null);
|
|
1427
|
+
const register = commandMap => {
|
|
1428
|
+
Object.assign(commands, commandMap);
|
|
1429
|
+
};
|
|
1430
|
+
const getCommand = key => {
|
|
1431
|
+
return commands[key];
|
|
1432
|
+
};
|
|
1433
|
+
const execute = (command, ...args) => {
|
|
1434
|
+
const fn = getCommand(command);
|
|
1435
|
+
if (!fn) {
|
|
1436
|
+
throw new Error(`command not found ${command}`);
|
|
1437
|
+
}
|
|
1438
|
+
return fn(...args);
|
|
1439
|
+
};
|
|
1440
|
+
|
|
1441
|
+
const createRpc = ipc => {
|
|
1442
|
+
const rpc = {
|
|
1443
|
+
// @ts-ignore
|
|
1444
|
+
ipc,
|
|
1445
|
+
/**
|
|
1446
|
+
* @deprecated
|
|
1447
|
+
*/
|
|
1448
|
+
send(method, ...params) {
|
|
1449
|
+
send(ipc, method, ...params);
|
|
1450
|
+
},
|
|
1451
|
+
invoke(method, ...params) {
|
|
1452
|
+
return invoke(ipc, method, ...params);
|
|
1453
|
+
},
|
|
1454
|
+
invokeAndTransfer(method, ...params) {
|
|
1455
|
+
return invokeAndTransfer(ipc, method, ...params);
|
|
1456
|
+
},
|
|
1457
|
+
async dispose() {
|
|
1458
|
+
await ipc?.dispose();
|
|
1459
|
+
}
|
|
1460
|
+
};
|
|
1461
|
+
return rpc;
|
|
1462
|
+
};
|
|
1463
|
+
const requiresSocket = () => {
|
|
1464
|
+
return false;
|
|
1465
|
+
};
|
|
1466
|
+
const preparePrettyError = error => {
|
|
1467
|
+
return error;
|
|
1468
|
+
};
|
|
1469
|
+
const logError = () => {
|
|
1470
|
+
// handled by renderer worker
|
|
1471
|
+
};
|
|
1472
|
+
const handleMessage = event => {
|
|
1473
|
+
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
1474
|
+
const actualExecute = event?.target?.execute || execute;
|
|
1475
|
+
return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
1476
|
+
};
|
|
1477
|
+
const handleIpc = ipc => {
|
|
1478
|
+
if ('addEventListener' in ipc) {
|
|
1479
|
+
ipc.addEventListener('message', handleMessage);
|
|
1480
|
+
} else if ('on' in ipc) {
|
|
1481
|
+
// deprecated
|
|
1482
|
+
ipc.on('message', handleMessage);
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
const listen$2 = async (module, options) => {
|
|
1486
|
+
const rawIpc = await module.listen(options);
|
|
1487
|
+
if (module.signal) {
|
|
1488
|
+
module.signal(rawIpc);
|
|
1489
|
+
}
|
|
1490
|
+
const ipc = module.wrap(rawIpc);
|
|
1491
|
+
return ipc;
|
|
1492
|
+
};
|
|
1493
|
+
const create$e = async ({
|
|
1494
|
+
commandMap,
|
|
1495
|
+
messagePort,
|
|
1496
|
+
requiresSocket
|
|
1497
|
+
}) => {
|
|
1498
|
+
// TODO create a commandMap per rpc instance
|
|
1499
|
+
register(commandMap);
|
|
1500
|
+
const ipc = await listen$2(IpcChildWithElectronMessagePort$1, {
|
|
1501
|
+
messagePort
|
|
1502
|
+
});
|
|
1503
|
+
if (requiresSocket) {
|
|
1504
|
+
ipc.requiresSocket = requiresSocket;
|
|
1505
|
+
}
|
|
1506
|
+
handleIpc(ipc);
|
|
1507
|
+
const rpc = createRpc(ipc);
|
|
1508
|
+
return rpc;
|
|
1509
|
+
};
|
|
1510
|
+
const ElectronMessagePortRpcClient = {
|
|
1511
|
+
__proto__: null,
|
|
1512
|
+
create: create$e
|
|
1513
|
+
};
|
|
1514
|
+
const create$d = async ({
|
|
1515
|
+
commandMap
|
|
1516
|
+
}) => {
|
|
1517
|
+
// TODO create a commandMap per rpc instance
|
|
1518
|
+
register(commandMap);
|
|
1519
|
+
const ipc = await listen$2(IpcChildWithElectronUtilityProcess$1);
|
|
1520
|
+
handleIpc(ipc);
|
|
1521
|
+
const rpc = createRpc(ipc);
|
|
1522
|
+
return rpc;
|
|
1523
|
+
};
|
|
1524
|
+
const ElectronUtilityProcessRpcClient = {
|
|
1525
|
+
__proto__: null,
|
|
1526
|
+
create: create$d
|
|
1527
|
+
};
|
|
1528
|
+
const create$7 = async ({
|
|
1529
|
+
commandMap
|
|
1530
|
+
}) => {
|
|
1531
|
+
// TODO create a commandMap per rpc instance
|
|
1532
|
+
register(commandMap);
|
|
1533
|
+
const ipc = await listen$2(IpcChildWithNodeForkedProcess$1);
|
|
1534
|
+
handleIpc(ipc);
|
|
1535
|
+
const rpc = createRpc(ipc);
|
|
1536
|
+
return rpc;
|
|
1537
|
+
};
|
|
1538
|
+
const NodeForkedProcessRpcClient = {
|
|
1539
|
+
__proto__: null,
|
|
1540
|
+
create: create$7
|
|
1541
|
+
};
|
|
1542
|
+
const create$5 = async ({
|
|
1543
|
+
commandMap,
|
|
1544
|
+
request,
|
|
1545
|
+
handle,
|
|
1546
|
+
requiresSocket
|
|
1547
|
+
}) => {
|
|
1548
|
+
// TODO create a commandMap per rpc instance
|
|
1549
|
+
register(commandMap);
|
|
1550
|
+
const ipc = await listen$2(IpcChildWithWebSocket, {
|
|
1551
|
+
request,
|
|
1552
|
+
handle
|
|
1553
|
+
});
|
|
1554
|
+
if (requiresSocket) {
|
|
1555
|
+
ipc.requiresSocket = requiresSocket;
|
|
1556
|
+
}
|
|
1557
|
+
handleIpc(ipc);
|
|
1558
|
+
const rpc = createRpc(ipc);
|
|
1559
|
+
return rpc;
|
|
1560
|
+
};
|
|
1561
|
+
const NodeWebSocketRpcClient = {
|
|
1562
|
+
__proto__: null,
|
|
1563
|
+
create: create$5
|
|
1564
|
+
};
|
|
1565
|
+
const create$4 = async ({
|
|
1566
|
+
commandMap
|
|
1567
|
+
}) => {
|
|
1568
|
+
// TODO create a commandMap per rpc instance
|
|
1569
|
+
register(commandMap);
|
|
1570
|
+
const ipc = await listen$2(IpcChildWithNodeWorker$1);
|
|
1571
|
+
handleIpc(ipc);
|
|
1572
|
+
const rpc = createRpc(ipc);
|
|
1573
|
+
return rpc;
|
|
1574
|
+
};
|
|
1575
|
+
const NodeWorkerRpcClient = {
|
|
1576
|
+
__proto__: null,
|
|
1577
|
+
create: create$4
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
const NodeWorker = 1;
|
|
1581
|
+
const NodeForkedProcess = 2;
|
|
1582
|
+
const ElectronUtilityProcess = 3;
|
|
1583
|
+
const ElectronMessagePort = 4;
|
|
1584
|
+
const WebSocket = 6;
|
|
1585
|
+
const Auto = argv => {
|
|
1586
|
+
if (argv.includes('--ipc-type=node-worker')) {
|
|
1587
|
+
return NodeWorker;
|
|
1588
|
+
}
|
|
1589
|
+
if (argv.includes('--ipc-type=node-forked-process')) {
|
|
1590
|
+
return NodeForkedProcess;
|
|
1591
|
+
}
|
|
1592
|
+
if (argv.includes('--ipc-type=electron-utility-process')) {
|
|
1593
|
+
return ElectronUtilityProcess;
|
|
1594
|
+
}
|
|
1595
|
+
throw new Error(`[file-system-process] unknown ipc type`);
|
|
1596
|
+
};
|
|
1597
|
+
|
|
1598
|
+
const getModule = method => {
|
|
1599
|
+
switch (method) {
|
|
1600
|
+
case NodeForkedProcess:
|
|
1601
|
+
return NodeForkedProcessRpcClient.create;
|
|
1602
|
+
case NodeWorker:
|
|
1603
|
+
return NodeWorkerRpcClient.create;
|
|
1604
|
+
case ElectronUtilityProcess:
|
|
1605
|
+
return ElectronUtilityProcessRpcClient.create;
|
|
1606
|
+
case ElectronMessagePort:
|
|
1607
|
+
return ElectronMessagePortRpcClient.create;
|
|
1608
|
+
case WebSocket:
|
|
1609
|
+
return NodeWebSocketRpcClient.create;
|
|
1610
|
+
default:
|
|
1611
|
+
throw new Error('unexpected ipc type');
|
|
1612
|
+
}
|
|
1613
|
+
};
|
|
1614
|
+
|
|
1615
|
+
const listen$1 = async ({
|
|
1616
|
+
method,
|
|
1617
|
+
...params
|
|
1618
|
+
}) => {
|
|
1619
|
+
const create = getModule(method);
|
|
1620
|
+
const rpc = await create(params);
|
|
1621
|
+
return rpc;
|
|
1622
|
+
};
|
|
1623
|
+
|
|
1624
|
+
const handleElectronMessagePort = async (messagePort, ...params) => {
|
|
1625
|
+
object(messagePort);
|
|
1626
|
+
await listen$1({
|
|
1627
|
+
method: ElectronMessagePort,
|
|
1628
|
+
messagePort
|
|
1629
|
+
});
|
|
1630
|
+
};
|
|
1631
|
+
|
|
419
1632
|
const handleWebSocket = async (handle, request) => {
|
|
420
1633
|
object(handle);
|
|
421
1634
|
object(request);
|
|
@@ -426,6 +1639,24 @@ const handleWebSocket = async (handle, request) => {
|
|
|
426
1639
|
});
|
|
427
1640
|
};
|
|
428
1641
|
|
|
1642
|
+
const createMainProcessRpc = async port => {
|
|
1643
|
+
try {
|
|
1644
|
+
const rpc = await ElectronMessagePortRpcClient.create({
|
|
1645
|
+
commandMap: {},
|
|
1646
|
+
messagePort: port
|
|
1647
|
+
});
|
|
1648
|
+
return rpc;
|
|
1649
|
+
} catch (error) {
|
|
1650
|
+
throw new VError(error, `Failed to create main process rpc`);
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1654
|
+
const initialize = async port => {
|
|
1655
|
+
// TODO only connect to main process if platform is electron else not
|
|
1656
|
+
const rpc = await createMainProcessRpc(port);
|
|
1657
|
+
set$1(rpc);
|
|
1658
|
+
};
|
|
1659
|
+
|
|
429
1660
|
const commandMap = {
|
|
430
1661
|
'FileSystem.chmod': chmod,
|
|
431
1662
|
'FileSystem.copy': copy,
|
|
@@ -435,11 +1666,13 @@ const commandMap = {
|
|
|
435
1666
|
'FileSystem.readDirWithFileTypes': readDirWithFileTypes,
|
|
436
1667
|
'FileSystem.readFile': readFile,
|
|
437
1668
|
'FileSystem.readJson': readJson,
|
|
438
|
-
'FileSystem.remove': remove,
|
|
1669
|
+
'FileSystem.remove': remove$1,
|
|
439
1670
|
'FileSystem.rename': rename,
|
|
440
1671
|
'FileSystem.stat': stat,
|
|
441
1672
|
'FileSystem.writeFile': writeFile,
|
|
442
|
-
'
|
|
1673
|
+
'HandleElectronMessagePort.handleElectronMessagePort': handleElectronMessagePort,
|
|
1674
|
+
'HandleWebSocket.handleWebSocket': handleWebSocket,
|
|
1675
|
+
'Initialize.initialize': initialize
|
|
443
1676
|
};
|
|
444
1677
|
|
|
445
1678
|
const listen = async argv => {
|
|
@@ -454,3 +1687,36 @@ const main = async () => {
|
|
|
454
1687
|
};
|
|
455
1688
|
|
|
456
1689
|
main();
|
|
1690
|
+
|
|
1691
|
+
const createWebSocketServer = async () => {
|
|
1692
|
+
const _ws = await import('ws');
|
|
1693
|
+
// workaround for jest or node bug
|
|
1694
|
+
const WebSocketServer = _ws.WebSocketServer ? _ws.WebSocketServer :
|
|
1695
|
+
// @ts-ignore
|
|
1696
|
+
_ws.default.WebSocketServer;
|
|
1697
|
+
const webSocketServer = new WebSocketServer({
|
|
1698
|
+
noServer: true
|
|
1699
|
+
|
|
1700
|
+
// TODO not sure if ws compress is working at all
|
|
1701
|
+
// perMessageDeflate: true
|
|
1702
|
+
});
|
|
1703
|
+
return webSocketServer;
|
|
1704
|
+
};
|
|
1705
|
+
const doSocketUpgrade = (webSocketServer, request, socket) => {
|
|
1706
|
+
const {
|
|
1707
|
+
promise,
|
|
1708
|
+
resolve
|
|
1709
|
+
} = Promise.withResolvers();
|
|
1710
|
+
webSocketServer.handleUpgrade(request, socket, Buffer.alloc(0), resolve);
|
|
1711
|
+
return promise;
|
|
1712
|
+
};
|
|
1713
|
+
const handleUpgrade = async (request, socket) => {
|
|
1714
|
+
const webSocketServer = await createWebSocketServer();
|
|
1715
|
+
const webSocket = await doSocketUpgrade(webSocketServer, request, socket);
|
|
1716
|
+
return webSocket;
|
|
1717
|
+
};
|
|
1718
|
+
|
|
1719
|
+
const index = {
|
|
1720
|
+
__proto__: null,
|
|
1721
|
+
handleUpgrade
|
|
1722
|
+
};
|