@lvce-editor/explorer-view 1.6.0 → 1.8.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/explorerViewWorkerMain.js +846 -867
- package/package.json +1 -1
|
@@ -1,747 +1,799 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
1
|
+
const normalizeLine = line => {
|
|
2
|
+
if (line.startsWith('Error: ')) {
|
|
3
|
+
return line.slice('Error: '.length);
|
|
4
|
+
}
|
|
5
|
+
if (line.startsWith('VError: ')) {
|
|
6
|
+
return line.slice('VError: '.length);
|
|
7
|
+
}
|
|
8
|
+
return line;
|
|
8
9
|
};
|
|
9
|
-
const
|
|
10
|
-
|
|
10
|
+
const getCombinedMessage = (error, message) => {
|
|
11
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
12
|
+
if (message) {
|
|
13
|
+
return `${message}: ${stringifiedError}`;
|
|
14
|
+
}
|
|
15
|
+
return stringifiedError;
|
|
11
16
|
};
|
|
12
|
-
const
|
|
13
|
-
|
|
17
|
+
const NewLine$2 = '\n';
|
|
18
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
19
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
14
20
|
};
|
|
15
|
-
const
|
|
16
|
-
|
|
21
|
+
const mergeStacks = (parent, child) => {
|
|
22
|
+
if (!child) {
|
|
23
|
+
return parent;
|
|
24
|
+
}
|
|
25
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
26
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
27
|
+
if (childNewLineIndex === -1) {
|
|
28
|
+
return parent;
|
|
29
|
+
}
|
|
30
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
31
|
+
const childRest = child.slice(childNewLineIndex);
|
|
32
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
33
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
34
|
+
return parentFirstLine + childRest;
|
|
35
|
+
}
|
|
36
|
+
return child;
|
|
17
37
|
};
|
|
18
|
-
|
|
19
|
-
|
|
38
|
+
class VError extends Error {
|
|
39
|
+
constructor(error, message) {
|
|
40
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
41
|
+
super(combinedMessage);
|
|
42
|
+
this.name = 'VError';
|
|
43
|
+
if (error instanceof Error) {
|
|
44
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
45
|
+
}
|
|
46
|
+
if (error.codeFrame) {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
this.codeFrame = error.codeFrame;
|
|
49
|
+
}
|
|
50
|
+
if (error.code) {
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
this.code = error.code;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class AssertionError extends Error {
|
|
58
|
+
constructor(message) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.name = 'AssertionError';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const getType = value => {
|
|
64
|
+
switch (typeof value) {
|
|
65
|
+
case 'number':
|
|
66
|
+
return 'number';
|
|
67
|
+
case 'function':
|
|
68
|
+
return 'function';
|
|
69
|
+
case 'string':
|
|
70
|
+
return 'string';
|
|
71
|
+
case 'object':
|
|
72
|
+
if (value === null) {
|
|
73
|
+
return 'null';
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
return 'array';
|
|
77
|
+
}
|
|
78
|
+
return 'object';
|
|
79
|
+
case 'boolean':
|
|
80
|
+
return 'boolean';
|
|
81
|
+
default:
|
|
82
|
+
return 'unknown';
|
|
83
|
+
}
|
|
20
84
|
};
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
85
|
+
const object = value => {
|
|
86
|
+
const type = getType(value);
|
|
87
|
+
if (type !== 'object') {
|
|
88
|
+
throw new AssertionError('expected value to be of type object');
|
|
89
|
+
}
|
|
24
90
|
};
|
|
25
|
-
const
|
|
26
|
-
|
|
91
|
+
const number = value => {
|
|
92
|
+
const type = getType(value);
|
|
93
|
+
if (type !== 'number') {
|
|
94
|
+
throw new AssertionError('expected value to be of type number');
|
|
95
|
+
}
|
|
27
96
|
};
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} = Promise.withResolvers();
|
|
34
|
-
set(id, resolve);
|
|
35
|
-
return {
|
|
36
|
-
id,
|
|
37
|
-
promise
|
|
38
|
-
};
|
|
97
|
+
const array = value => {
|
|
98
|
+
const type = getType(value);
|
|
99
|
+
if (type !== 'array') {
|
|
100
|
+
throw new AssertionError('expected value to be of type array');
|
|
101
|
+
}
|
|
39
102
|
};
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
103
|
+
const string = value => {
|
|
104
|
+
const type = getType(value);
|
|
105
|
+
if (type !== 'string') {
|
|
106
|
+
throw new AssertionError('expected value to be of type string');
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
111
|
+
if (!value) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (isTransferrable(value)) {
|
|
115
|
+
transferrables.push(value);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (Array.isArray(value)) {
|
|
119
|
+
for (const item of value) {
|
|
120
|
+
walkValue(item, transferrables, isTransferrable);
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (typeof value === 'object') {
|
|
125
|
+
for (const property of Object.values(value)) {
|
|
126
|
+
walkValue(property, transferrables, isTransferrable);
|
|
127
|
+
}
|
|
45
128
|
return;
|
|
46
129
|
}
|
|
47
|
-
fn(response);
|
|
48
|
-
remove$1(id);
|
|
49
130
|
};
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
131
|
+
const isMessagePort = value => {
|
|
132
|
+
return value && value instanceof MessagePort;
|
|
133
|
+
};
|
|
134
|
+
const isMessagePortMain = value => {
|
|
135
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
136
|
+
};
|
|
137
|
+
const isOffscreenCanvas = value => {
|
|
138
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
139
|
+
};
|
|
140
|
+
const isInstanceOf = (value, constructorName) => {
|
|
141
|
+
return value?.constructor?.name === constructorName;
|
|
142
|
+
};
|
|
143
|
+
const isSocket = value => {
|
|
144
|
+
return isInstanceOf(value, 'Socket');
|
|
145
|
+
};
|
|
146
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
147
|
+
const isTransferrable = value => {
|
|
148
|
+
for (const fn of transferrables) {
|
|
149
|
+
if (fn(value)) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
};
|
|
155
|
+
const getTransferrables = value => {
|
|
156
|
+
const transferrables = [];
|
|
157
|
+
walkValue(value, transferrables, isTransferrable);
|
|
158
|
+
return transferrables;
|
|
159
|
+
};
|
|
160
|
+
const attachEvents = that => {
|
|
161
|
+
const handleMessage = (...args) => {
|
|
162
|
+
const data = that.getData(...args);
|
|
163
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
164
|
+
data
|
|
165
|
+
}));
|
|
166
|
+
};
|
|
167
|
+
that.onMessage(handleMessage);
|
|
168
|
+
const handleClose = event => {
|
|
169
|
+
that.dispatchEvent(new Event('close'));
|
|
60
170
|
};
|
|
171
|
+
that.onClose(handleClose);
|
|
172
|
+
};
|
|
173
|
+
class Ipc extends EventTarget {
|
|
174
|
+
constructor(rawIpc) {
|
|
175
|
+
super();
|
|
176
|
+
this._rawIpc = rawIpc;
|
|
177
|
+
attachEvents(this);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
181
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
182
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
183
|
+
const NewLine$1 = '\n';
|
|
184
|
+
const joinLines$1 = lines => {
|
|
185
|
+
return lines.join(NewLine$1);
|
|
186
|
+
};
|
|
187
|
+
const splitLines$1 = lines => {
|
|
188
|
+
return lines.split(NewLine$1);
|
|
189
|
+
};
|
|
190
|
+
const isModuleNotFoundMessage = line => {
|
|
191
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
192
|
+
};
|
|
193
|
+
const getModuleNotFoundError = stderr => {
|
|
194
|
+
const lines = splitLines$1(stderr);
|
|
195
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
196
|
+
const message = lines[messageIndex];
|
|
61
197
|
return {
|
|
62
198
|
message,
|
|
63
|
-
|
|
199
|
+
code: ERR_MODULE_NOT_FOUND
|
|
64
200
|
};
|
|
65
201
|
};
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
202
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
203
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
204
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
205
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
206
|
+
const RE_AT = /^\s+at/;
|
|
207
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
208
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
209
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
210
|
+
};
|
|
211
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
212
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
213
|
+
};
|
|
214
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
215
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
216
|
+
};
|
|
217
|
+
const getMessageCodeBlock = stderr => {
|
|
218
|
+
const lines = splitLines$1(stderr);
|
|
219
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
220
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
221
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
222
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
223
|
+
return relevantMessage;
|
|
224
|
+
};
|
|
225
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
226
|
+
const message = getMessageCodeBlock(stderr);
|
|
227
|
+
return {
|
|
228
|
+
message: `Incompatible native node module: ${message}`,
|
|
229
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
230
|
+
};
|
|
231
|
+
};
|
|
232
|
+
const isModulesSyntaxError = stderr => {
|
|
233
|
+
if (!stderr) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
237
|
+
};
|
|
238
|
+
const getModuleSyntaxError = () => {
|
|
239
|
+
return {
|
|
240
|
+
message: `ES Modules are not supported in electron`,
|
|
241
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
const isModuleNotFoundError = stderr => {
|
|
245
|
+
if (!stderr) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
249
|
+
};
|
|
250
|
+
const isNormalStackLine = line => {
|
|
251
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
252
|
+
};
|
|
253
|
+
const getDetails = lines => {
|
|
254
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
255
|
+
if (index === -1) {
|
|
256
|
+
return {
|
|
257
|
+
actualMessage: joinLines$1(lines),
|
|
258
|
+
rest: []
|
|
259
|
+
};
|
|
70
260
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const SyntaxError$1 = 'SyntaxError';
|
|
76
|
-
const TypeError$1 = 'TypeError';
|
|
77
|
-
const getErrorConstructor = (message, type) => {
|
|
78
|
-
if (type) {
|
|
79
|
-
switch (type) {
|
|
80
|
-
case DomException:
|
|
81
|
-
return DOMException;
|
|
82
|
-
case TypeError$1:
|
|
83
|
-
return TypeError;
|
|
84
|
-
case SyntaxError$1:
|
|
85
|
-
return SyntaxError;
|
|
86
|
-
case ReferenceError$1:
|
|
87
|
-
return ReferenceError;
|
|
88
|
-
default:
|
|
89
|
-
return Error;
|
|
261
|
+
let lastIndex = index - 1;
|
|
262
|
+
while (++lastIndex < lines.length) {
|
|
263
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
264
|
+
break;
|
|
90
265
|
}
|
|
91
266
|
}
|
|
92
|
-
|
|
93
|
-
|
|
267
|
+
return {
|
|
268
|
+
actualMessage: lines[index - 1],
|
|
269
|
+
rest: lines.slice(index, lastIndex)
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
273
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
274
|
+
return getNativeModuleErrorMessage(stderr);
|
|
94
275
|
}
|
|
95
|
-
if (
|
|
96
|
-
return
|
|
276
|
+
if (isModulesSyntaxError(stderr)) {
|
|
277
|
+
return getModuleSyntaxError();
|
|
97
278
|
}
|
|
98
|
-
if (
|
|
99
|
-
return
|
|
279
|
+
if (isModuleNotFoundError(stderr)) {
|
|
280
|
+
return getModuleNotFoundError(stderr);
|
|
100
281
|
}
|
|
101
|
-
|
|
282
|
+
const lines = splitLines$1(stderr);
|
|
283
|
+
const {
|
|
284
|
+
actualMessage,
|
|
285
|
+
rest
|
|
286
|
+
} = getDetails(lines);
|
|
287
|
+
return {
|
|
288
|
+
message: `${actualMessage}`,
|
|
289
|
+
code: '',
|
|
290
|
+
stack: rest
|
|
291
|
+
};
|
|
102
292
|
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
293
|
+
class IpcError extends VError {
|
|
294
|
+
// @ts-ignore
|
|
295
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
296
|
+
if (stdout || stderr) {
|
|
297
|
+
// @ts-ignore
|
|
298
|
+
const {
|
|
299
|
+
message,
|
|
300
|
+
code,
|
|
301
|
+
stack
|
|
302
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
303
|
+
const cause = new Error(message);
|
|
304
|
+
// @ts-ignore
|
|
305
|
+
cause.code = code;
|
|
306
|
+
cause.stack = stack;
|
|
307
|
+
super(cause, betterMessage);
|
|
308
|
+
} else {
|
|
309
|
+
super(betterMessage);
|
|
112
310
|
}
|
|
113
|
-
|
|
311
|
+
// @ts-ignore
|
|
312
|
+
this.name = 'IpcError';
|
|
313
|
+
// @ts-ignore
|
|
314
|
+
this.stdout = stdout;
|
|
315
|
+
// @ts-ignore
|
|
316
|
+
this.stderr = stderr;
|
|
114
317
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
return
|
|
318
|
+
}
|
|
319
|
+
const readyMessage = 'ready';
|
|
320
|
+
const getData$2 = event => {
|
|
321
|
+
return event.data;
|
|
119
322
|
};
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
|
|
323
|
+
const listen$6 = () => {
|
|
324
|
+
// @ts-ignore
|
|
325
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
326
|
+
throw new TypeError('module is not in web worker scope');
|
|
124
327
|
}
|
|
125
|
-
return
|
|
126
|
-
};
|
|
127
|
-
const joinLines$1 = lines => {
|
|
128
|
-
return lines.join(NewLine$3);
|
|
328
|
+
return globalThis;
|
|
129
329
|
};
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
const splitLines$1 = lines => {
|
|
133
|
-
return lines.split(NewLine$3);
|
|
330
|
+
const signal$6 = global => {
|
|
331
|
+
global.postMessage(readyMessage);
|
|
134
332
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return
|
|
333
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
334
|
+
getData(event) {
|
|
335
|
+
return getData$2(event);
|
|
138
336
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const parentStack = getParentStack(error);
|
|
143
|
-
restoredError.stack = parentStack + NewLine$3 + currentStack;
|
|
144
|
-
return restoredError;
|
|
337
|
+
send(message) {
|
|
338
|
+
// @ts-ignore
|
|
339
|
+
this._rawIpc.postMessage(message);
|
|
145
340
|
}
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
|
|
151
|
-
} else if (error.data.stack) {
|
|
152
|
-
restoredError.stack = error.data.stack;
|
|
153
|
-
}
|
|
154
|
-
if (error.data.codeFrame) {
|
|
155
|
-
// @ts-ignore
|
|
156
|
-
restoredError.codeFrame = error.data.codeFrame;
|
|
157
|
-
}
|
|
158
|
-
if (error.data.code) {
|
|
159
|
-
// @ts-ignore
|
|
160
|
-
restoredError.code = error.data.code;
|
|
161
|
-
}
|
|
162
|
-
if (error.data.type) {
|
|
163
|
-
// @ts-ignore
|
|
164
|
-
restoredError.name = error.data.type;
|
|
165
|
-
}
|
|
166
|
-
} else {
|
|
167
|
-
if (error.stack) {
|
|
168
|
-
const lowerStack = restoredError.stack || '';
|
|
169
|
-
// @ts-ignore
|
|
170
|
-
const indexNewLine = getNewLineIndex$2(lowerStack);
|
|
171
|
-
const parentStack = getParentStack(error);
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
174
|
-
}
|
|
175
|
-
if (error.codeFrame) {
|
|
176
|
-
// @ts-ignore
|
|
177
|
-
restoredError.codeFrame = error.codeFrame;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return restoredError;
|
|
341
|
+
sendAndTransfer(message) {
|
|
342
|
+
const transfer = getTransferrables(message);
|
|
343
|
+
// @ts-ignore
|
|
344
|
+
this._rawIpc.postMessage(message, transfer);
|
|
181
345
|
}
|
|
182
|
-
|
|
183
|
-
|
|
346
|
+
dispose() {
|
|
347
|
+
// ignore
|
|
184
348
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const unwrapJsonRpcResult = responseMessage => {
|
|
188
|
-
if ('error' in responseMessage) {
|
|
189
|
-
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
190
|
-
throw restoredError;
|
|
349
|
+
onClose(callback) {
|
|
350
|
+
// ignore
|
|
191
351
|
}
|
|
192
|
-
|
|
193
|
-
|
|
352
|
+
onMessage(callback) {
|
|
353
|
+
this._rawIpc.addEventListener('message', callback);
|
|
194
354
|
}
|
|
195
|
-
|
|
355
|
+
}
|
|
356
|
+
const wrap$d = global => {
|
|
357
|
+
return new IpcChildWithModuleWorker(global);
|
|
196
358
|
};
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
359
|
+
const withResolvers = () => {
|
|
360
|
+
let _resolve;
|
|
361
|
+
const promise = new Promise(resolve => {
|
|
362
|
+
_resolve = resolve;
|
|
363
|
+
});
|
|
364
|
+
return {
|
|
365
|
+
resolve: _resolve,
|
|
366
|
+
promise
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
const waitForFirstMessage = async port => {
|
|
370
|
+
const {
|
|
371
|
+
resolve,
|
|
372
|
+
promise
|
|
373
|
+
} = withResolvers();
|
|
374
|
+
port.addEventListener('message', resolve, {
|
|
375
|
+
once: true
|
|
376
|
+
});
|
|
377
|
+
const event = await promise;
|
|
378
|
+
// @ts-ignore
|
|
379
|
+
return event.data;
|
|
380
|
+
};
|
|
381
|
+
const listen$5 = async () => {
|
|
382
|
+
const parentIpcRaw = listen$6();
|
|
383
|
+
signal$6(parentIpcRaw);
|
|
384
|
+
const parentIpc = wrap$d(parentIpcRaw);
|
|
385
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
386
|
+
if (firstMessage.method !== 'initialize') {
|
|
387
|
+
throw new IpcError('unexpected first message');
|
|
201
388
|
}
|
|
202
|
-
|
|
203
|
-
|
|
389
|
+
const type = firstMessage.params[0];
|
|
390
|
+
if (type === 'message-port') {
|
|
391
|
+
parentIpc.send({
|
|
392
|
+
jsonrpc: '2.0',
|
|
393
|
+
id: firstMessage.id,
|
|
394
|
+
result: null
|
|
395
|
+
});
|
|
396
|
+
parentIpc.dispose();
|
|
397
|
+
const port = firstMessage.params[1];
|
|
398
|
+
return port;
|
|
204
399
|
}
|
|
205
|
-
return
|
|
400
|
+
return globalThis;
|
|
206
401
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
code: MethodNotFound,
|
|
211
|
-
message: error.message,
|
|
212
|
-
data: error.stack
|
|
213
|
-
};
|
|
402
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
403
|
+
constructor(port) {
|
|
404
|
+
super(port);
|
|
214
405
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
406
|
+
getData(event) {
|
|
407
|
+
return getData$2(event);
|
|
408
|
+
}
|
|
409
|
+
send(message) {
|
|
410
|
+
this._rawIpc.postMessage(message);
|
|
411
|
+
}
|
|
412
|
+
sendAndTransfer(message) {
|
|
413
|
+
const transfer = getTransferrables(message);
|
|
414
|
+
this._rawIpc.postMessage(message, transfer);
|
|
415
|
+
}
|
|
416
|
+
dispose() {
|
|
417
|
+
if (this._rawIpc.close) {
|
|
418
|
+
this._rawIpc.close();
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
onClose(callback) {
|
|
422
|
+
// ignore
|
|
423
|
+
}
|
|
424
|
+
onMessage(callback) {
|
|
425
|
+
this._rawIpc.addEventListener('message', callback);
|
|
426
|
+
this._rawIpc.start();
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const wrap$c = port => {
|
|
430
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
233
431
|
};
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
return create$1(message, errorProperty);
|
|
432
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
433
|
+
__proto__: null,
|
|
434
|
+
listen: listen$5,
|
|
435
|
+
wrap: wrap$c
|
|
239
436
|
};
|
|
240
|
-
|
|
437
|
+
|
|
438
|
+
const Two = '2.0';
|
|
439
|
+
const create$4 = (method, params) => {
|
|
241
440
|
return {
|
|
242
441
|
jsonrpc: Two,
|
|
243
|
-
|
|
244
|
-
|
|
442
|
+
method,
|
|
443
|
+
params
|
|
245
444
|
};
|
|
246
445
|
};
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
446
|
+
const callbacks = Object.create(null);
|
|
447
|
+
const set = (id, fn) => {
|
|
448
|
+
callbacks[id] = fn;
|
|
250
449
|
};
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
254
|
-
return getSuccessResponse(message, result);
|
|
255
|
-
} catch (error) {
|
|
256
|
-
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
257
|
-
}
|
|
450
|
+
const get = id => {
|
|
451
|
+
return callbacks[id];
|
|
258
452
|
};
|
|
259
|
-
const
|
|
260
|
-
|
|
453
|
+
const remove$1 = id => {
|
|
454
|
+
delete callbacks[id];
|
|
261
455
|
};
|
|
262
|
-
|
|
263
|
-
|
|
456
|
+
let id = 0;
|
|
457
|
+
const create$3 = () => {
|
|
458
|
+
return ++id;
|
|
264
459
|
};
|
|
265
|
-
const
|
|
266
|
-
|
|
460
|
+
const warn = (...args) => {
|
|
461
|
+
console.warn(...args);
|
|
267
462
|
};
|
|
268
|
-
const
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
ipc: options.ipc,
|
|
276
|
-
message: options.message,
|
|
277
|
-
execute: options.execute,
|
|
278
|
-
resolve: options.resolve || defaultResolve,
|
|
279
|
-
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
280
|
-
logError: options.logError || defaultLogError,
|
|
281
|
-
requiresSocket: options.requiresSocket || defaultRequiresSocket
|
|
282
|
-
};
|
|
283
|
-
}
|
|
463
|
+
const registerPromise = () => {
|
|
464
|
+
const id = create$3();
|
|
465
|
+
const {
|
|
466
|
+
resolve,
|
|
467
|
+
promise
|
|
468
|
+
} = Promise.withResolvers();
|
|
469
|
+
set(id, resolve);
|
|
284
470
|
return {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
execute: args[2],
|
|
288
|
-
resolve: args[3],
|
|
289
|
-
preparePrettyError: args[4],
|
|
290
|
-
logError: args[5],
|
|
291
|
-
requiresSocket: args[6]
|
|
471
|
+
id,
|
|
472
|
+
promise
|
|
292
473
|
};
|
|
293
474
|
};
|
|
294
|
-
const
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
execute,
|
|
300
|
-
resolve,
|
|
301
|
-
preparePrettyError,
|
|
302
|
-
logError,
|
|
303
|
-
requiresSocket
|
|
304
|
-
} = options;
|
|
305
|
-
if ('id' in message) {
|
|
306
|
-
if ('method' in message) {
|
|
307
|
-
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
308
|
-
try {
|
|
309
|
-
ipc.send(response);
|
|
310
|
-
} catch (error) {
|
|
311
|
-
const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
|
|
312
|
-
ipc.send(errorResponse);
|
|
313
|
-
}
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
resolve(message.id, message);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
if ('method' in message) {
|
|
320
|
-
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
475
|
+
const resolve = (id, response) => {
|
|
476
|
+
const fn = get(id);
|
|
477
|
+
if (!fn) {
|
|
478
|
+
console.log(response);
|
|
479
|
+
warn(`callback ${id} may already be disposed`);
|
|
321
480
|
return;
|
|
322
481
|
}
|
|
323
|
-
|
|
482
|
+
fn(response);
|
|
483
|
+
remove$1(id);
|
|
324
484
|
};
|
|
325
|
-
const
|
|
485
|
+
const create$2 = (method, params) => {
|
|
326
486
|
const {
|
|
327
|
-
|
|
487
|
+
id,
|
|
328
488
|
promise
|
|
329
|
-
} =
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
const responseMessage = await promise;
|
|
336
|
-
return unwrapJsonRpcResult(responseMessage);
|
|
337
|
-
};
|
|
338
|
-
const send = (transport, method, ...params) => {
|
|
339
|
-
const message = create$4(method, params);
|
|
340
|
-
transport.send(message);
|
|
341
|
-
};
|
|
342
|
-
const invoke$1 = (ipc, method, ...params) => {
|
|
343
|
-
return invokeHelper(ipc, method, params, false);
|
|
344
|
-
};
|
|
345
|
-
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
346
|
-
return invokeHelper(ipc, method, params, true);
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
const commands = Object.create(null);
|
|
350
|
-
const register = commandMap => {
|
|
351
|
-
Object.assign(commands, commandMap);
|
|
352
|
-
};
|
|
353
|
-
const getCommand = key => {
|
|
354
|
-
return commands[key];
|
|
355
|
-
};
|
|
356
|
-
const execute = (command, ...args) => {
|
|
357
|
-
const fn = getCommand(command);
|
|
358
|
-
if (!fn) {
|
|
359
|
-
throw new Error(`command not found ${command}`);
|
|
360
|
-
}
|
|
361
|
-
return fn(...args);
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
const getData$1 = event => {
|
|
365
|
-
return event.data;
|
|
366
|
-
};
|
|
367
|
-
const attachEvents = that => {
|
|
368
|
-
const handleMessage = (...args) => {
|
|
369
|
-
const data = that.getData(...args);
|
|
370
|
-
that.dispatchEvent(new MessageEvent('message', {
|
|
371
|
-
data
|
|
372
|
-
}));
|
|
489
|
+
} = registerPromise();
|
|
490
|
+
const message = {
|
|
491
|
+
jsonrpc: Two,
|
|
492
|
+
method,
|
|
493
|
+
params,
|
|
494
|
+
id
|
|
373
495
|
};
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
496
|
+
return {
|
|
497
|
+
message,
|
|
498
|
+
promise
|
|
377
499
|
};
|
|
378
|
-
that.onClose(handleClose);
|
|
379
500
|
};
|
|
380
|
-
class
|
|
381
|
-
constructor(
|
|
382
|
-
super();
|
|
383
|
-
this.
|
|
384
|
-
attachEvents(this);
|
|
501
|
+
class JsonRpcError extends Error {
|
|
502
|
+
constructor(message) {
|
|
503
|
+
super(message);
|
|
504
|
+
this.name = 'JsonRpcError';
|
|
385
505
|
}
|
|
386
506
|
}
|
|
387
|
-
const
|
|
388
|
-
const
|
|
389
|
-
|
|
390
|
-
|
|
507
|
+
const NewLine = '\n';
|
|
508
|
+
const DomException = 'DOMException';
|
|
509
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
510
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
511
|
+
const TypeError$1 = 'TypeError';
|
|
512
|
+
const getErrorConstructor = (message, type) => {
|
|
513
|
+
if (type) {
|
|
514
|
+
switch (type) {
|
|
515
|
+
case DomException:
|
|
516
|
+
return DOMException;
|
|
517
|
+
case TypeError$1:
|
|
518
|
+
return TypeError;
|
|
519
|
+
case SyntaxError$1:
|
|
520
|
+
return SyntaxError;
|
|
521
|
+
case ReferenceError$1:
|
|
522
|
+
return ReferenceError;
|
|
523
|
+
default:
|
|
524
|
+
return Error;
|
|
525
|
+
}
|
|
391
526
|
}
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
return;
|
|
527
|
+
if (message.startsWith('TypeError: ')) {
|
|
528
|
+
return TypeError;
|
|
395
529
|
}
|
|
396
|
-
if (
|
|
397
|
-
|
|
398
|
-
walkValue(item, transferrables, isTransferrable);
|
|
399
|
-
}
|
|
400
|
-
return;
|
|
530
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
531
|
+
return SyntaxError;
|
|
401
532
|
}
|
|
402
|
-
if (
|
|
403
|
-
|
|
404
|
-
walkValue(property, transferrables, isTransferrable);
|
|
405
|
-
}
|
|
406
|
-
return;
|
|
533
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
534
|
+
return ReferenceError;
|
|
407
535
|
}
|
|
536
|
+
return Error;
|
|
408
537
|
};
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const isInstanceOf = (value, constructorName) => {
|
|
419
|
-
return value?.constructor?.name === constructorName;
|
|
420
|
-
};
|
|
421
|
-
const isSocket = value => {
|
|
422
|
-
return isInstanceOf(value, 'Socket');
|
|
423
|
-
};
|
|
424
|
-
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
425
|
-
const isTransferrable = value => {
|
|
426
|
-
for (const fn of transferrables) {
|
|
427
|
-
if (fn(value)) {
|
|
428
|
-
return true;
|
|
538
|
+
const constructError = (message, type, name) => {
|
|
539
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
540
|
+
if (ErrorConstructor === DOMException && name) {
|
|
541
|
+
return new ErrorConstructor(message, name);
|
|
542
|
+
}
|
|
543
|
+
if (ErrorConstructor === Error) {
|
|
544
|
+
const error = new Error(message);
|
|
545
|
+
if (name && name !== 'VError') {
|
|
546
|
+
error.name = name;
|
|
429
547
|
}
|
|
548
|
+
return error;
|
|
430
549
|
}
|
|
431
|
-
return
|
|
550
|
+
return new ErrorConstructor(message);
|
|
432
551
|
};
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
walkValue(value, transferrables, isTransferrable);
|
|
436
|
-
return transferrables;
|
|
552
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
553
|
+
return string.indexOf(NewLine, startIndex);
|
|
437
554
|
};
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
if (
|
|
441
|
-
|
|
555
|
+
const getParentStack = error => {
|
|
556
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
557
|
+
if (parentStack.startsWith(' at')) {
|
|
558
|
+
parentStack = error.message + NewLine + parentStack;
|
|
442
559
|
}
|
|
443
|
-
return
|
|
560
|
+
return parentStack;
|
|
444
561
|
};
|
|
445
|
-
const
|
|
446
|
-
|
|
562
|
+
const joinLines = lines => {
|
|
563
|
+
return lines.join(NewLine);
|
|
447
564
|
};
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
565
|
+
const MethodNotFound = -32601;
|
|
566
|
+
const Custom = -32001;
|
|
567
|
+
const splitLines = lines => {
|
|
568
|
+
return lines.split(NewLine);
|
|
569
|
+
};
|
|
570
|
+
const restoreJsonRpcError = error => {
|
|
571
|
+
if (error && error instanceof Error) {
|
|
572
|
+
return error;
|
|
451
573
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
574
|
+
const currentStack = joinLines(splitLines(new Error().stack || '').slice(1));
|
|
575
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
576
|
+
const restoredError = new JsonRpcError(error.message);
|
|
577
|
+
const parentStack = getParentStack(error);
|
|
578
|
+
restoredError.stack = parentStack + NewLine + currentStack;
|
|
579
|
+
return restoredError;
|
|
455
580
|
}
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
|
|
581
|
+
if (error && error.message) {
|
|
582
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
583
|
+
if (error.data) {
|
|
584
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
585
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
|
|
586
|
+
} else if (error.data.stack) {
|
|
587
|
+
restoredError.stack = error.data.stack;
|
|
588
|
+
}
|
|
589
|
+
if (error.data.codeFrame) {
|
|
590
|
+
// @ts-ignore
|
|
591
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
592
|
+
}
|
|
593
|
+
if (error.data.code) {
|
|
594
|
+
// @ts-ignore
|
|
595
|
+
restoredError.code = error.data.code;
|
|
596
|
+
}
|
|
597
|
+
if (error.data.type) {
|
|
598
|
+
// @ts-ignore
|
|
599
|
+
restoredError.name = error.data.type;
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
if (error.stack) {
|
|
603
|
+
const lowerStack = restoredError.stack || '';
|
|
604
|
+
// @ts-ignore
|
|
605
|
+
const indexNewLine = getNewLineIndex(lowerStack);
|
|
606
|
+
const parentStack = getParentStack(error);
|
|
607
|
+
// @ts-ignore
|
|
608
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
609
|
+
}
|
|
610
|
+
if (error.codeFrame) {
|
|
611
|
+
// @ts-ignore
|
|
612
|
+
restoredError.codeFrame = error.codeFrame;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return restoredError;
|
|
460
616
|
}
|
|
461
|
-
|
|
462
|
-
|
|
617
|
+
if (typeof error === 'string') {
|
|
618
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
463
619
|
}
|
|
464
|
-
|
|
465
|
-
|
|
620
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
621
|
+
};
|
|
622
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
623
|
+
if ('error' in responseMessage) {
|
|
624
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
625
|
+
throw restoredError;
|
|
466
626
|
}
|
|
467
|
-
|
|
468
|
-
|
|
627
|
+
if ('result' in responseMessage) {
|
|
628
|
+
return responseMessage.result;
|
|
469
629
|
}
|
|
470
|
-
|
|
471
|
-
const wrap$5 = global => {
|
|
472
|
-
return new IpcChildWithModuleWorker(global);
|
|
473
|
-
};
|
|
474
|
-
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
475
|
-
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
476
|
-
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
477
|
-
const NewLine$1 = '\n';
|
|
478
|
-
const joinLines = lines => {
|
|
479
|
-
return lines.join(NewLine$1);
|
|
480
|
-
};
|
|
481
|
-
const splitLines = lines => {
|
|
482
|
-
return lines.split(NewLine$1);
|
|
483
|
-
};
|
|
484
|
-
const isModuleNotFoundMessage = line => {
|
|
485
|
-
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
486
|
-
};
|
|
487
|
-
const getModuleNotFoundError = stderr => {
|
|
488
|
-
const lines = splitLines(stderr);
|
|
489
|
-
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
490
|
-
const message = lines[messageIndex];
|
|
491
|
-
return {
|
|
492
|
-
message,
|
|
493
|
-
code: ERR_MODULE_NOT_FOUND
|
|
494
|
-
};
|
|
495
|
-
};
|
|
496
|
-
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
497
|
-
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
498
|
-
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
499
|
-
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
500
|
-
const RE_AT = /^\s+at/;
|
|
501
|
-
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
502
|
-
const isUnhelpfulNativeModuleError = stderr => {
|
|
503
|
-
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
504
|
-
};
|
|
505
|
-
const isMessageCodeBlockStartIndex = line => {
|
|
506
|
-
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
507
|
-
};
|
|
508
|
-
const isMessageCodeBlockEndIndex = line => {
|
|
509
|
-
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
510
|
-
};
|
|
511
|
-
const getMessageCodeBlock = stderr => {
|
|
512
|
-
const lines = splitLines(stderr);
|
|
513
|
-
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
514
|
-
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
515
|
-
const relevantLines = lines.slice(startIndex, endIndex);
|
|
516
|
-
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
517
|
-
return relevantMessage;
|
|
518
|
-
};
|
|
519
|
-
const getNativeModuleErrorMessage = stderr => {
|
|
520
|
-
const message = getMessageCodeBlock(stderr);
|
|
521
|
-
return {
|
|
522
|
-
message: `Incompatible native node module: ${message}`,
|
|
523
|
-
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
524
|
-
};
|
|
630
|
+
throw new JsonRpcError('unexpected response message');
|
|
525
631
|
};
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
632
|
+
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
633
|
+
const getErrorType = prettyError => {
|
|
634
|
+
if (prettyError && prettyError.type) {
|
|
635
|
+
return prettyError.type;
|
|
529
636
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
const getModuleSyntaxError = () => {
|
|
533
|
-
return {
|
|
534
|
-
message: `ES Modules are not supported in electron`,
|
|
535
|
-
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
536
|
-
};
|
|
537
|
-
};
|
|
538
|
-
const isModuleNotFoundError = stderr => {
|
|
539
|
-
if (!stderr) {
|
|
540
|
-
return false;
|
|
637
|
+
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
|
|
638
|
+
return prettyError.constructor.name;
|
|
541
639
|
}
|
|
542
|
-
return
|
|
543
|
-
};
|
|
544
|
-
const isNormalStackLine = line => {
|
|
545
|
-
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
640
|
+
return undefined;
|
|
546
641
|
};
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
if (index === -1) {
|
|
642
|
+
const getErrorProperty = (error, prettyError) => {
|
|
643
|
+
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
550
644
|
return {
|
|
551
|
-
|
|
552
|
-
|
|
645
|
+
code: MethodNotFound,
|
|
646
|
+
message: error.message,
|
|
647
|
+
data: error.stack
|
|
553
648
|
};
|
|
554
649
|
}
|
|
555
|
-
let lastIndex = index - 1;
|
|
556
|
-
while (++lastIndex < lines.length) {
|
|
557
|
-
if (!isNormalStackLine(lines[lastIndex])) {
|
|
558
|
-
break;
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
650
|
return {
|
|
562
|
-
|
|
563
|
-
|
|
651
|
+
code: Custom,
|
|
652
|
+
message: prettyError.message,
|
|
653
|
+
data: {
|
|
654
|
+
stack: prettyError.stack,
|
|
655
|
+
codeFrame: prettyError.codeFrame,
|
|
656
|
+
type: getErrorType(prettyError),
|
|
657
|
+
code: prettyError.code,
|
|
658
|
+
name: prettyError.name
|
|
659
|
+
}
|
|
564
660
|
};
|
|
565
661
|
};
|
|
566
|
-
const
|
|
567
|
-
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
568
|
-
return getNativeModuleErrorMessage(stderr);
|
|
569
|
-
}
|
|
570
|
-
if (isModulesSyntaxError(stderr)) {
|
|
571
|
-
return getModuleSyntaxError();
|
|
572
|
-
}
|
|
573
|
-
if (isModuleNotFoundError(stderr)) {
|
|
574
|
-
return getModuleNotFoundError(stderr);
|
|
575
|
-
}
|
|
576
|
-
const lines = splitLines(stderr);
|
|
577
|
-
const {
|
|
578
|
-
actualMessage,
|
|
579
|
-
rest
|
|
580
|
-
} = getDetails(lines);
|
|
662
|
+
const create$1 = (message, error) => {
|
|
581
663
|
return {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
664
|
+
jsonrpc: Two,
|
|
665
|
+
id: message.id,
|
|
666
|
+
error
|
|
585
667
|
};
|
|
586
668
|
};
|
|
587
|
-
const
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return line.slice('VError: '.length);
|
|
593
|
-
}
|
|
594
|
-
return line;
|
|
595
|
-
};
|
|
596
|
-
const getCombinedMessage$1 = (error, message) => {
|
|
597
|
-
const stringifiedError = normalizeLine$1(`${error}`);
|
|
598
|
-
if (message) {
|
|
599
|
-
return `${message}: ${stringifiedError}`;
|
|
600
|
-
}
|
|
601
|
-
return stringifiedError;
|
|
602
|
-
};
|
|
603
|
-
const NewLine$2 = '\n';
|
|
604
|
-
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
605
|
-
return string.indexOf(NewLine$2, startIndex);
|
|
669
|
+
const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
670
|
+
const prettyError = preparePrettyError(error);
|
|
671
|
+
logError(error, prettyError);
|
|
672
|
+
const errorProperty = getErrorProperty(error, prettyError);
|
|
673
|
+
return create$1(message, errorProperty);
|
|
606
674
|
};
|
|
607
|
-
const
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
if (childNewLineIndex === -1) {
|
|
614
|
-
return parent;
|
|
615
|
-
}
|
|
616
|
-
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
617
|
-
const childRest = child.slice(childNewLineIndex);
|
|
618
|
-
const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
|
|
619
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
620
|
-
return parentFirstLine + childRest;
|
|
621
|
-
}
|
|
622
|
-
return child;
|
|
675
|
+
const create$5 = (message, result) => {
|
|
676
|
+
return {
|
|
677
|
+
jsonrpc: Two,
|
|
678
|
+
id: message.id,
|
|
679
|
+
result: result ?? null
|
|
680
|
+
};
|
|
623
681
|
};
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
this.codeFrame = error.codeFrame;
|
|
635
|
-
}
|
|
636
|
-
if (error.code) {
|
|
637
|
-
// @ts-ignore
|
|
638
|
-
this.code = error.code;
|
|
639
|
-
}
|
|
682
|
+
const getSuccessResponse = (message, result) => {
|
|
683
|
+
const resultProperty = result ?? null;
|
|
684
|
+
return create$5(message, resultProperty);
|
|
685
|
+
};
|
|
686
|
+
const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
687
|
+
try {
|
|
688
|
+
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
689
|
+
return getSuccessResponse(message, result);
|
|
690
|
+
} catch (error) {
|
|
691
|
+
return getErrorResponse(message, error, preparePrettyError, logError);
|
|
640
692
|
}
|
|
641
693
|
};
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
694
|
+
const defaultPreparePrettyError = error => {
|
|
695
|
+
return error;
|
|
696
|
+
};
|
|
697
|
+
const defaultLogError = () => {
|
|
698
|
+
// ignore
|
|
699
|
+
};
|
|
700
|
+
const defaultRequiresSocket = () => {
|
|
701
|
+
return false;
|
|
702
|
+
};
|
|
703
|
+
const defaultResolve = resolve;
|
|
704
|
+
|
|
705
|
+
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
706
|
+
const normalizeParams = args => {
|
|
707
|
+
if (args.length === 1) {
|
|
708
|
+
const options = args[0];
|
|
709
|
+
return {
|
|
710
|
+
ipc: options.ipc,
|
|
711
|
+
message: options.message,
|
|
712
|
+
execute: options.execute,
|
|
713
|
+
resolve: options.resolve || defaultResolve,
|
|
714
|
+
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
715
|
+
logError: options.logError || defaultLogError,
|
|
716
|
+
requiresSocket: options.requiresSocket || defaultRequiresSocket
|
|
717
|
+
};
|
|
666
718
|
}
|
|
667
|
-
}
|
|
668
|
-
const withResolvers = () => {
|
|
669
|
-
let _resolve;
|
|
670
|
-
const promise = new Promise(resolve => {
|
|
671
|
-
_resolve = resolve;
|
|
672
|
-
});
|
|
673
719
|
return {
|
|
674
|
-
|
|
675
|
-
|
|
720
|
+
ipc: args[0],
|
|
721
|
+
message: args[1],
|
|
722
|
+
execute: args[2],
|
|
723
|
+
resolve: args[3],
|
|
724
|
+
preparePrettyError: args[4],
|
|
725
|
+
logError: args[5],
|
|
726
|
+
requiresSocket: args[6]
|
|
676
727
|
};
|
|
677
728
|
};
|
|
678
|
-
const
|
|
729
|
+
const handleJsonRpcMessage = async (...args) => {
|
|
730
|
+
const options = normalizeParams(args);
|
|
679
731
|
const {
|
|
732
|
+
message,
|
|
733
|
+
ipc,
|
|
734
|
+
execute,
|
|
680
735
|
resolve,
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
if (firstMessage.method !== 'initialize') {
|
|
696
|
-
throw new IpcError('unexpected first message');
|
|
697
|
-
}
|
|
698
|
-
const type = firstMessage.params[0];
|
|
699
|
-
if (type === 'message-port') {
|
|
700
|
-
parentIpc.send({
|
|
701
|
-
jsonrpc: '2.0',
|
|
702
|
-
id: firstMessage.id,
|
|
703
|
-
result: null
|
|
704
|
-
});
|
|
705
|
-
parentIpc.dispose();
|
|
706
|
-
const port = firstMessage.params[1];
|
|
707
|
-
return port;
|
|
708
|
-
}
|
|
709
|
-
return globalThis;
|
|
710
|
-
};
|
|
711
|
-
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
712
|
-
constructor(port) {
|
|
713
|
-
super(port);
|
|
714
|
-
}
|
|
715
|
-
getData(event) {
|
|
716
|
-
return getData$1(event);
|
|
717
|
-
}
|
|
718
|
-
send(message) {
|
|
719
|
-
this._rawIpc.postMessage(message);
|
|
720
|
-
}
|
|
721
|
-
sendAndTransfer(message) {
|
|
722
|
-
const transfer = getTransferrables(message);
|
|
723
|
-
this._rawIpc.postMessage(message, transfer);
|
|
724
|
-
}
|
|
725
|
-
dispose() {
|
|
726
|
-
if (this._rawIpc.close) {
|
|
727
|
-
this._rawIpc.close();
|
|
736
|
+
preparePrettyError,
|
|
737
|
+
logError,
|
|
738
|
+
requiresSocket
|
|
739
|
+
} = options;
|
|
740
|
+
if ('id' in message) {
|
|
741
|
+
if ('method' in message) {
|
|
742
|
+
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
743
|
+
try {
|
|
744
|
+
ipc.send(response);
|
|
745
|
+
} catch (error) {
|
|
746
|
+
const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
|
|
747
|
+
ipc.send(errorResponse);
|
|
748
|
+
}
|
|
749
|
+
return;
|
|
728
750
|
}
|
|
751
|
+
resolve(message.id, message);
|
|
752
|
+
return;
|
|
729
753
|
}
|
|
730
|
-
|
|
731
|
-
|
|
754
|
+
if ('method' in message) {
|
|
755
|
+
await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
756
|
+
return;
|
|
732
757
|
}
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
758
|
+
throw new JsonRpcError('unexpected message');
|
|
759
|
+
};
|
|
760
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
761
|
+
const {
|
|
762
|
+
message,
|
|
763
|
+
promise
|
|
764
|
+
} = create$2(method, params);
|
|
765
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
766
|
+
ipc.sendAndTransfer(message);
|
|
767
|
+
} else {
|
|
768
|
+
ipc.send(message);
|
|
736
769
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
770
|
+
const responseMessage = await promise;
|
|
771
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
740
772
|
};
|
|
741
|
-
const
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
773
|
+
const send = (transport, method, ...params) => {
|
|
774
|
+
const message = create$4(method, params);
|
|
775
|
+
transport.send(message);
|
|
776
|
+
};
|
|
777
|
+
const invoke$1 = (ipc, method, ...params) => {
|
|
778
|
+
return invokeHelper(ipc, method, params, false);
|
|
779
|
+
};
|
|
780
|
+
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
781
|
+
return invokeHelper(ipc, method, params, true);
|
|
782
|
+
};
|
|
783
|
+
|
|
784
|
+
const commands = Object.create(null);
|
|
785
|
+
const register = commandMap => {
|
|
786
|
+
Object.assign(commands, commandMap);
|
|
787
|
+
};
|
|
788
|
+
const getCommand = key => {
|
|
789
|
+
return commands[key];
|
|
790
|
+
};
|
|
791
|
+
const execute = (command, ...args) => {
|
|
792
|
+
const fn = getCommand(command);
|
|
793
|
+
if (!fn) {
|
|
794
|
+
throw new Error(`command not found ${command}`);
|
|
795
|
+
}
|
|
796
|
+
return fn(...args);
|
|
745
797
|
};
|
|
746
798
|
|
|
747
799
|
const createRpc = ipc => {
|
|
@@ -771,16 +823,22 @@ const logError = () => {
|
|
|
771
823
|
// handled by renderer worker
|
|
772
824
|
};
|
|
773
825
|
const handleMessage = event => {
|
|
774
|
-
|
|
826
|
+
const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
|
|
827
|
+
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, actualRequiresSocket);
|
|
775
828
|
};
|
|
776
829
|
const handleIpc = ipc => {
|
|
777
|
-
|
|
830
|
+
if ('addEventListener' in ipc) {
|
|
831
|
+
ipc.addEventListener('message', handleMessage);
|
|
832
|
+
} else if ('on' in ipc) {
|
|
833
|
+
// deprecated
|
|
834
|
+
ipc.on('message', handleMessage);
|
|
835
|
+
}
|
|
778
836
|
};
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
837
|
+
const listen$1 = async (module, options) => {
|
|
838
|
+
const rawIpc = await module.listen(options);
|
|
839
|
+
if (module.signal) {
|
|
840
|
+
module.signal(rawIpc);
|
|
841
|
+
}
|
|
784
842
|
const ipc = module.wrap(rawIpc);
|
|
785
843
|
return ipc;
|
|
786
844
|
};
|
|
@@ -789,7 +847,7 @@ const create = async ({
|
|
|
789
847
|
}) => {
|
|
790
848
|
// TODO create a commandMap per rpc instance
|
|
791
849
|
register(commandMap);
|
|
792
|
-
const ipc = await listen$1();
|
|
850
|
+
const ipc = await listen$1(IpcChildWithModuleWorkerAndMessagePort$1);
|
|
793
851
|
handleIpc(ipc);
|
|
794
852
|
const rpc = createRpc(ipc);
|
|
795
853
|
return rpc;
|
|
@@ -839,7 +897,7 @@ const compareDirent = (direntA, direntB) => {
|
|
|
839
897
|
return compareDirentType(direntA, direntB) || compareDirentName(direntA, direntB);
|
|
840
898
|
};
|
|
841
899
|
|
|
842
|
-
const getFileIcon = ({
|
|
900
|
+
const getFileIcon$1 = ({
|
|
843
901
|
name
|
|
844
902
|
}) => {
|
|
845
903
|
return '';
|
|
@@ -862,7 +920,7 @@ const computeExplorerRenamedDirent = (dirents, index, newName) => {
|
|
|
862
920
|
...oldDirent,
|
|
863
921
|
name: newName,
|
|
864
922
|
path: oldDirent.path.slice(0, -oldDirent.name.length) + newName,
|
|
865
|
-
icon: getFileIcon({
|
|
923
|
+
icon: getFileIcon$1({
|
|
866
924
|
name: newName
|
|
867
925
|
})
|
|
868
926
|
};
|
|
@@ -1204,72 +1262,19 @@ const copyPath$1 = async state => {
|
|
|
1204
1262
|
const writeText = async text => {
|
|
1205
1263
|
await invoke('ClipBoard.writeText', /* text */text);
|
|
1206
1264
|
};
|
|
1207
|
-
const readNativeFiles = async () => {
|
|
1208
|
-
return invoke('ClipBoard.readNativeFiles');
|
|
1209
|
-
};
|
|
1210
|
-
const writeNativeFiles = async (type, files) => {
|
|
1211
|
-
return invoke('ClipBoard.writeNativeFiles', type, files);
|
|
1212
|
-
};
|
|
1213
|
-
|
|
1214
|
-
const copyRelativePath$1 = async state => {
|
|
1215
|
-
const dirent = getFocusedDirent$1(state);
|
|
1216
|
-
const relativePath = dirent.path.slice(1);
|
|
1217
|
-
// TODO handle error
|
|
1218
|
-
await writeText(relativePath);
|
|
1219
|
-
return state;
|
|
1220
|
-
};
|
|
1221
|
-
|
|
1222
|
-
class AssertionError extends Error {
|
|
1223
|
-
constructor(message) {
|
|
1224
|
-
super(message);
|
|
1225
|
-
this.name = 'AssertionError';
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
const getType = value => {
|
|
1229
|
-
switch (typeof value) {
|
|
1230
|
-
case 'number':
|
|
1231
|
-
return 'number';
|
|
1232
|
-
case 'function':
|
|
1233
|
-
return 'function';
|
|
1234
|
-
case 'string':
|
|
1235
|
-
return 'string';
|
|
1236
|
-
case 'object':
|
|
1237
|
-
if (value === null) {
|
|
1238
|
-
return 'null';
|
|
1239
|
-
}
|
|
1240
|
-
if (Array.isArray(value)) {
|
|
1241
|
-
return 'array';
|
|
1242
|
-
}
|
|
1243
|
-
return 'object';
|
|
1244
|
-
case 'boolean':
|
|
1245
|
-
return 'boolean';
|
|
1246
|
-
default:
|
|
1247
|
-
return 'unknown';
|
|
1248
|
-
}
|
|
1249
|
-
};
|
|
1250
|
-
const object = value => {
|
|
1251
|
-
const type = getType(value);
|
|
1252
|
-
if (type !== 'object') {
|
|
1253
|
-
throw new AssertionError('expected value to be of type object');
|
|
1254
|
-
}
|
|
1255
|
-
};
|
|
1256
|
-
const number = value => {
|
|
1257
|
-
const type = getType(value);
|
|
1258
|
-
if (type !== 'number') {
|
|
1259
|
-
throw new AssertionError('expected value to be of type number');
|
|
1260
|
-
}
|
|
1265
|
+
const readNativeFiles = async () => {
|
|
1266
|
+
return invoke('ClipBoard.readNativeFiles');
|
|
1261
1267
|
};
|
|
1262
|
-
const
|
|
1263
|
-
|
|
1264
|
-
if (type !== 'array') {
|
|
1265
|
-
throw new AssertionError('expected value to be of type array');
|
|
1266
|
-
}
|
|
1268
|
+
const writeNativeFiles = async (type, files) => {
|
|
1269
|
+
return invoke('ClipBoard.writeNativeFiles', type, files);
|
|
1267
1270
|
};
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1271
|
+
|
|
1272
|
+
const copyRelativePath$1 = async state => {
|
|
1273
|
+
const dirent = getFocusedDirent$1(state);
|
|
1274
|
+
const relativePath = dirent.path.slice(1);
|
|
1275
|
+
// TODO handle error
|
|
1276
|
+
await writeText(relativePath);
|
|
1277
|
+
return state;
|
|
1273
1278
|
};
|
|
1274
1279
|
|
|
1275
1280
|
const isSymbolicLink = dirent => {
|
|
@@ -2171,7 +2176,7 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
|
|
|
2171
2176
|
...item,
|
|
2172
2177
|
isFocused: i === focusedIndex,
|
|
2173
2178
|
isEditing: true,
|
|
2174
|
-
icon: getFileIcon({
|
|
2179
|
+
icon: getFileIcon$1({
|
|
2175
2180
|
name: editingValue
|
|
2176
2181
|
})
|
|
2177
2182
|
});
|
|
@@ -2213,36 +2218,27 @@ const handleBlur = state => {
|
|
|
2213
2218
|
};
|
|
2214
2219
|
};
|
|
2215
2220
|
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
// TODO rename dirents to items, then can use virtual list component directly
|
|
2226
|
-
|
|
2227
|
-
// TODO support multiselection and removing multiple dirents
|
|
2228
|
-
|
|
2229
|
-
// TODO use posInSet and setSize properties to compute more effectively
|
|
2230
|
-
|
|
2231
|
-
// TODO much shared logic with newFolder
|
|
2232
|
-
|
|
2233
|
-
const handleClickFile$1 = async (state, dirent, index, keepFocus = false) => {
|
|
2234
|
-
// await Command.execute(/* Main.openAbsolutePath */ 'Main.openUri', /* absolutePath */ dirent.path, /* focus */ !keepFocus)
|
|
2235
|
-
return {
|
|
2236
|
-
...state,
|
|
2237
|
-
focusedIndex: index,
|
|
2238
|
-
focused: keepFocus
|
|
2239
|
-
};
|
|
2221
|
+
const getFileIcon = dirent => {
|
|
2222
|
+
if (dirent.type === File) {
|
|
2223
|
+
return invoke('IconTheme.getFileIcon', {
|
|
2224
|
+
name: dirent.name
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
return invoke('IconTheme.getFolderIcon', {
|
|
2228
|
+
name: dirent.name
|
|
2229
|
+
});
|
|
2240
2230
|
};
|
|
2241
|
-
const
|
|
2231
|
+
const getFileIcons = async dirents => {
|
|
2232
|
+
const promises = dirents.map(getFileIcon);
|
|
2233
|
+
const icons = await Promise.all(promises);
|
|
2234
|
+
return icons;
|
|
2235
|
+
};
|
|
2236
|
+
|
|
2237
|
+
const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
2242
2238
|
dirent.type = DirectoryExpanding;
|
|
2243
2239
|
// TODO handle error
|
|
2244
2240
|
const dirents = await getChildDirents(state.pathSeparator, dirent);
|
|
2245
|
-
const state2 =
|
|
2241
|
+
const state2 = state;
|
|
2246
2242
|
if (!state2) {
|
|
2247
2243
|
return state;
|
|
2248
2244
|
}
|
|
@@ -2263,24 +2259,19 @@ const handleClickDirectory$1 = async (state, dirent, index, keepFocus) => {
|
|
|
2263
2259
|
} = state2;
|
|
2264
2260
|
// TODO when focused index has changed while expanding, don't update it
|
|
2265
2261
|
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
2262
|
+
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2263
|
+
const icons = await getFileIcons(parts);
|
|
2266
2264
|
return {
|
|
2267
2265
|
...state,
|
|
2268
2266
|
items: newDirents,
|
|
2267
|
+
icons,
|
|
2269
2268
|
focusedIndex: newIndex,
|
|
2270
2269
|
focused: keepFocus,
|
|
2271
2270
|
maxLineY
|
|
2272
2271
|
};
|
|
2273
2272
|
};
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
dirent.icon = getIcon();
|
|
2277
|
-
return {
|
|
2278
|
-
...state,
|
|
2279
|
-
focusedIndex: index,
|
|
2280
|
-
focused: keepFocus
|
|
2281
|
-
};
|
|
2282
|
-
};
|
|
2283
|
-
const handleClickDirectoryExpanded$1 = (state, dirent, index, keepFocus) => {
|
|
2273
|
+
|
|
2274
|
+
const handleClickDirectoryExpanded$1 = async (state, dirent, index, keepFocus) => {
|
|
2284
2275
|
const {
|
|
2285
2276
|
minLineY,
|
|
2286
2277
|
maxLineY,
|
|
@@ -2299,9 +2290,12 @@ const handleClickDirectoryExpanded$1 = (state, dirent, index, keepFocus) => {
|
|
|
2299
2290
|
const newMaxLineY = Math.min(maxLineY, newTotal);
|
|
2300
2291
|
const newMinLineY = newMaxLineY - visibleItems;
|
|
2301
2292
|
const deltaY = newMinLineY * itemHeight;
|
|
2293
|
+
const parts = newDirents.slice(minLineY, maxLineY);
|
|
2294
|
+
const icons = await getFileIcons(parts);
|
|
2302
2295
|
return {
|
|
2303
2296
|
...state,
|
|
2304
2297
|
items: newDirents,
|
|
2298
|
+
icons,
|
|
2305
2299
|
focusedIndex: index,
|
|
2306
2300
|
focused: keepFocus,
|
|
2307
2301
|
minLineY: newMinLineY,
|
|
@@ -2309,13 +2303,36 @@ const handleClickDirectoryExpanded$1 = (state, dirent, index, keepFocus) => {
|
|
|
2309
2303
|
deltaY
|
|
2310
2304
|
};
|
|
2311
2305
|
}
|
|
2306
|
+
const parts = newDirents.slice(state.minLineY, state.maxLineY);
|
|
2307
|
+
const icons = await getFileIcons(parts);
|
|
2312
2308
|
return {
|
|
2313
2309
|
...state,
|
|
2314
2310
|
items: newDirents,
|
|
2311
|
+
icons,
|
|
2312
|
+
focusedIndex: index,
|
|
2313
|
+
focused: keepFocus
|
|
2314
|
+
};
|
|
2315
|
+
};
|
|
2316
|
+
|
|
2317
|
+
const handleClickDirectoryExpanding = (state, dirent, index, keepFocus) => {
|
|
2318
|
+
dirent.type = Directory;
|
|
2319
|
+
dirent.icon = getIcon();
|
|
2320
|
+
return {
|
|
2321
|
+
...state,
|
|
2322
|
+
focusedIndex: index,
|
|
2323
|
+
focused: keepFocus
|
|
2324
|
+
};
|
|
2325
|
+
};
|
|
2326
|
+
|
|
2327
|
+
const handleClickFile$1 = async (state, dirent, index, keepFocus = false) => {
|
|
2328
|
+
// await Command.execute(/* Main.openAbsolutePath */ 'Main.openUri', /* absolutePath */ dirent.path, /* focus */ !keepFocus)
|
|
2329
|
+
return {
|
|
2330
|
+
...state,
|
|
2315
2331
|
focusedIndex: index,
|
|
2316
2332
|
focused: keepFocus
|
|
2317
2333
|
};
|
|
2318
2334
|
};
|
|
2335
|
+
|
|
2319
2336
|
const handleClickSymLink$1 = async (state, dirent, index) => {
|
|
2320
2337
|
const realPath = await getRealPath(dirent.path);
|
|
2321
2338
|
const type = await stat(realPath);
|
|
@@ -2326,6 +2343,24 @@ const handleClickSymLink$1 = async (state, dirent, index) => {
|
|
|
2326
2343
|
throw new Error(`unsupported file type ${type}`);
|
|
2327
2344
|
}
|
|
2328
2345
|
};
|
|
2346
|
+
|
|
2347
|
+
// TODO viewlet should only have create and refresh functions
|
|
2348
|
+
// every thing else can be in a separate module <viewlet>.lazy.js
|
|
2349
|
+
// and <viewlet>.ipc.js
|
|
2350
|
+
|
|
2351
|
+
// viewlet: creating | refreshing | done | disposed
|
|
2352
|
+
// TODO recycle viewlets (maybe)
|
|
2353
|
+
|
|
2354
|
+
// TODO instead of root string, there should be a root dirent
|
|
2355
|
+
|
|
2356
|
+
// TODO rename dirents to items, then can use virtual list component directly
|
|
2357
|
+
|
|
2358
|
+
// TODO support multiselection and removing multiple dirents
|
|
2359
|
+
|
|
2360
|
+
// TODO use posInSet and setSize properties to compute more effectively
|
|
2361
|
+
|
|
2362
|
+
// TODO much shared logic with newFolder
|
|
2363
|
+
|
|
2329
2364
|
const getClickFn = direntType => {
|
|
2330
2365
|
switch (direntType) {
|
|
2331
2366
|
case File:
|
|
@@ -2333,7 +2368,7 @@ const getClickFn = direntType => {
|
|
|
2333
2368
|
return handleClickFile$1;
|
|
2334
2369
|
case Directory:
|
|
2335
2370
|
case SymLinkFolder:
|
|
2336
|
-
return handleClickDirectory
|
|
2371
|
+
return handleClickDirectory;
|
|
2337
2372
|
case DirectoryExpanding:
|
|
2338
2373
|
return handleClickDirectoryExpanding;
|
|
2339
2374
|
case DirectoryExpanded:
|
|
@@ -2367,40 +2402,6 @@ const getIndexFromPosition = (state, eventX, eventY) => {
|
|
|
2367
2402
|
return index;
|
|
2368
2403
|
};
|
|
2369
2404
|
|
|
2370
|
-
const handleClickDirectory = async (state, dirent, index, keepFocus) => {
|
|
2371
|
-
dirent.type = DirectoryExpanding;
|
|
2372
|
-
// TODO handle error
|
|
2373
|
-
const dirents = await getChildDirents(state.pathSeparator, dirent);
|
|
2374
|
-
const state2 = state;
|
|
2375
|
-
if (!state2) {
|
|
2376
|
-
return state;
|
|
2377
|
-
}
|
|
2378
|
-
// TODO use Viewlet.getState here and check if it exists
|
|
2379
|
-
const newIndex = state2.items.indexOf(dirent);
|
|
2380
|
-
// TODO if viewlet is disposed or root has changed, return
|
|
2381
|
-
if (newIndex === -1) {
|
|
2382
|
-
return state;
|
|
2383
|
-
}
|
|
2384
|
-
const newDirents = [...state2.items];
|
|
2385
|
-
newDirents.splice(newIndex + 1, 0, ...dirents);
|
|
2386
|
-
dirent.type = DirectoryExpanded;
|
|
2387
|
-
dirent.icon = getIcon();
|
|
2388
|
-
const {
|
|
2389
|
-
height,
|
|
2390
|
-
itemHeight,
|
|
2391
|
-
minLineY
|
|
2392
|
-
} = state2;
|
|
2393
|
-
// TODO when focused index has changed while expanding, don't update it
|
|
2394
|
-
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
2395
|
-
return {
|
|
2396
|
-
...state,
|
|
2397
|
-
items: newDirents,
|
|
2398
|
-
focusedIndex: newIndex,
|
|
2399
|
-
focused: keepFocus,
|
|
2400
|
-
maxLineY
|
|
2401
|
-
};
|
|
2402
|
-
};
|
|
2403
|
-
|
|
2404
2405
|
const getParentStartIndex = (dirents, index) => {
|
|
2405
2406
|
const dirent = dirents[index];
|
|
2406
2407
|
let startIndex = index - 1;
|
|
@@ -2422,23 +2423,6 @@ const LeftClick = 0;
|
|
|
2422
2423
|
|
|
2423
2424
|
// TODO instead of root string, there should be a root dirent
|
|
2424
2425
|
|
|
2425
|
-
const updateIcon = dirent => {
|
|
2426
|
-
return {
|
|
2427
|
-
...dirent,
|
|
2428
|
-
icon: getIcon()
|
|
2429
|
-
};
|
|
2430
|
-
};
|
|
2431
|
-
const updateIcons = state => {
|
|
2432
|
-
const newDirents = state.items.map(updateIcon);
|
|
2433
|
-
return {
|
|
2434
|
-
...state,
|
|
2435
|
-
items: newDirents
|
|
2436
|
-
};
|
|
2437
|
-
};
|
|
2438
|
-
const handleIconThemeChange = state => {
|
|
2439
|
-
return updateIcons(state);
|
|
2440
|
-
};
|
|
2441
|
-
|
|
2442
2426
|
// TODO rename dirents to items, then can use virtual list component directly
|
|
2443
2427
|
const setDeltaY$1 = (state, deltaY) => {
|
|
2444
2428
|
const {
|
|
@@ -2844,62 +2828,6 @@ const handleDropIndex = (state, index, files) => {
|
|
|
2844
2828
|
}
|
|
2845
2829
|
};
|
|
2846
2830
|
|
|
2847
|
-
const normalizeLine = line => {
|
|
2848
|
-
if (line.startsWith('Error: ')) {
|
|
2849
|
-
return line.slice('Error: '.length);
|
|
2850
|
-
}
|
|
2851
|
-
if (line.startsWith('VError: ')) {
|
|
2852
|
-
return line.slice('VError: '.length);
|
|
2853
|
-
}
|
|
2854
|
-
return line;
|
|
2855
|
-
};
|
|
2856
|
-
const getCombinedMessage = (error, message) => {
|
|
2857
|
-
const stringifiedError = normalizeLine(`${error}`);
|
|
2858
|
-
if (message) {
|
|
2859
|
-
return `${message}: ${stringifiedError}`;
|
|
2860
|
-
}
|
|
2861
|
-
return stringifiedError;
|
|
2862
|
-
};
|
|
2863
|
-
const NewLine = '\n';
|
|
2864
|
-
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
2865
|
-
return string.indexOf(NewLine, startIndex);
|
|
2866
|
-
};
|
|
2867
|
-
const mergeStacks = (parent, child) => {
|
|
2868
|
-
if (!child) {
|
|
2869
|
-
return parent;
|
|
2870
|
-
}
|
|
2871
|
-
const parentNewLineIndex = getNewLineIndex(parent);
|
|
2872
|
-
const childNewLineIndex = getNewLineIndex(child);
|
|
2873
|
-
if (childNewLineIndex === -1) {
|
|
2874
|
-
return parent;
|
|
2875
|
-
}
|
|
2876
|
-
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
2877
|
-
const childRest = child.slice(childNewLineIndex);
|
|
2878
|
-
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
2879
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
2880
|
-
return parentFirstLine + childRest;
|
|
2881
|
-
}
|
|
2882
|
-
return child;
|
|
2883
|
-
};
|
|
2884
|
-
class VError extends Error {
|
|
2885
|
-
constructor(error, message) {
|
|
2886
|
-
const combinedMessage = getCombinedMessage(error, message);
|
|
2887
|
-
super(combinedMessage);
|
|
2888
|
-
this.name = 'VError';
|
|
2889
|
-
if (error instanceof Error) {
|
|
2890
|
-
this.stack = mergeStacks(this.stack, error.stack);
|
|
2891
|
-
}
|
|
2892
|
-
if (error.codeFrame) {
|
|
2893
|
-
// @ts-ignore
|
|
2894
|
-
this.codeFrame = error.codeFrame;
|
|
2895
|
-
}
|
|
2896
|
-
if (error.code) {
|
|
2897
|
-
// @ts-ignore
|
|
2898
|
-
this.code = error.code;
|
|
2899
|
-
}
|
|
2900
|
-
}
|
|
2901
|
-
}
|
|
2902
|
-
|
|
2903
2831
|
const handleDrop = async (state, x, y, files) => {
|
|
2904
2832
|
try {
|
|
2905
2833
|
const index = getIndexFromPosition(state, x, y);
|
|
@@ -2914,6 +2842,25 @@ const handleDrop = async (state, x, y, files) => {
|
|
|
2914
2842
|
}
|
|
2915
2843
|
};
|
|
2916
2844
|
|
|
2845
|
+
const updateIcon = dirent => {
|
|
2846
|
+
return {
|
|
2847
|
+
...dirent,
|
|
2848
|
+
icon: getIcon()
|
|
2849
|
+
};
|
|
2850
|
+
};
|
|
2851
|
+
|
|
2852
|
+
const updateIcons = state => {
|
|
2853
|
+
const newDirents = state.items.map(updateIcon);
|
|
2854
|
+
return {
|
|
2855
|
+
...state,
|
|
2856
|
+
items: newDirents
|
|
2857
|
+
};
|
|
2858
|
+
};
|
|
2859
|
+
|
|
2860
|
+
const handleIconThemeChange = state => {
|
|
2861
|
+
return updateIcons(state);
|
|
2862
|
+
};
|
|
2863
|
+
|
|
2917
2864
|
const getTopLevelDirents = (root, pathSeparator, excluded) => {
|
|
2918
2865
|
if (!root) {
|
|
2919
2866
|
return [];
|
|
@@ -2985,8 +2932,7 @@ const None = 'none';
|
|
|
2985
2932
|
const Copy = 'copy';
|
|
2986
2933
|
const Cut = 'cut';
|
|
2987
2934
|
|
|
2988
|
-
const
|
|
2989
|
-
const nativeFiles = await readNativeFiles();
|
|
2935
|
+
const getPasteHandler = type => {
|
|
2990
2936
|
// TODO detect cut/paste event, not sure if that is possible
|
|
2991
2937
|
// TODO check that pasted folder is not a parent folder of opened folder
|
|
2992
2938
|
// TODO support pasting multiple paths
|
|
@@ -2999,18 +2945,36 @@ const handlePaste = async state => {
|
|
|
2999
2945
|
// TODO but what if a file is currently selected? Then maybe the parent folder
|
|
3000
2946
|
// TODO but will it work if the folder is a symlink?
|
|
3001
2947
|
// TODO handle error gracefully when copy fails
|
|
3002
|
-
switch (
|
|
2948
|
+
switch (type) {
|
|
3003
2949
|
case None:
|
|
3004
|
-
return handlePasteNone
|
|
2950
|
+
return handlePasteNone;
|
|
3005
2951
|
case Copy:
|
|
3006
|
-
return handlePasteCopy
|
|
2952
|
+
return handlePasteCopy;
|
|
3007
2953
|
case Cut:
|
|
3008
|
-
return handlePasteCut
|
|
2954
|
+
return handlePasteCut;
|
|
3009
2955
|
default:
|
|
3010
|
-
throw new Error(`unexpected native paste type: ${
|
|
2956
|
+
throw new Error(`unexpected native paste type: ${type}`);
|
|
3011
2957
|
}
|
|
3012
2958
|
};
|
|
3013
2959
|
|
|
2960
|
+
const handlePaste = async state => {
|
|
2961
|
+
const nativeFiles = await readNativeFiles();
|
|
2962
|
+
// TODO detect cut/paste event, not sure if that is possible
|
|
2963
|
+
// TODO check that pasted folder is not a parent folder of opened folder
|
|
2964
|
+
// TODO support pasting multiple paths
|
|
2965
|
+
// TODO what happens when pasting multiple paths, but some of them error?
|
|
2966
|
+
// how many error messages should be shown? Should the operation be undone?
|
|
2967
|
+
// TODO what if it is a large folder and takes a long time to copy? Should show progress
|
|
2968
|
+
// TODO what if there is a permission error? Probably should show a modal to ask for permission
|
|
2969
|
+
// TODO if error is EEXISTS, just rename the copy (e.g. file-copy-1.txt, file-copy-2.txt)
|
|
2970
|
+
// TODO actual target should be selected folder
|
|
2971
|
+
// TODO but what if a file is currently selected? Then maybe the parent folder
|
|
2972
|
+
// TODO but will it work if the folder is a symlink?
|
|
2973
|
+
// TODO handle error gracefully when copy fails
|
|
2974
|
+
const fn = getPasteHandler(nativeFiles.type);
|
|
2975
|
+
return fn(state, nativeFiles);
|
|
2976
|
+
};
|
|
2977
|
+
|
|
3014
2978
|
const handlePointerDown = (state, button, x, y) => {
|
|
3015
2979
|
const index = getIndexFromPosition(state, x, y);
|
|
3016
2980
|
if (button === LeftClick && index === -1) {
|
|
@@ -3042,15 +3006,15 @@ const handleUpload = async (state, dirents) => {
|
|
|
3042
3006
|
}
|
|
3043
3007
|
};
|
|
3044
3008
|
|
|
3009
|
+
const getWorkspacePath = () => {
|
|
3010
|
+
return invoke('Workspace.getPath');
|
|
3011
|
+
};
|
|
3012
|
+
|
|
3045
3013
|
const EmptyString = '';
|
|
3046
3014
|
|
|
3047
3015
|
const Fulfilled = 'fulfilled';
|
|
3048
3016
|
const Rejected = 'rejected';
|
|
3049
3017
|
|
|
3050
|
-
const getWorkspacePath = () => {
|
|
3051
|
-
return invoke('Workspace.getPath');
|
|
3052
|
-
};
|
|
3053
|
-
|
|
3054
3018
|
// TODO viewlet should only have create and refresh functions
|
|
3055
3019
|
// every thing else can be in a separate module <viewlet>.lazy.js
|
|
3056
3020
|
// and <viewlet>.ipc.js
|
|
@@ -3184,10 +3148,12 @@ const loadContent = async (state, savedState) => {
|
|
|
3184
3148
|
deltaY = savedState.deltaY;
|
|
3185
3149
|
}
|
|
3186
3150
|
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, restoredDirents.length);
|
|
3151
|
+
const icons = await getFileIcons(restoredDirents);
|
|
3187
3152
|
return {
|
|
3188
3153
|
...state,
|
|
3189
3154
|
root,
|
|
3190
3155
|
items: restoredDirents,
|
|
3156
|
+
icons,
|
|
3191
3157
|
minLineY,
|
|
3192
3158
|
deltaY,
|
|
3193
3159
|
maxLineY,
|
|
@@ -3196,6 +3162,16 @@ const loadContent = async (state, savedState) => {
|
|
|
3196
3162
|
};
|
|
3197
3163
|
};
|
|
3198
3164
|
|
|
3165
|
+
const handleWorkspaceChange = async state => {
|
|
3166
|
+
const newRoot = await getWorkspacePath();
|
|
3167
|
+
const state1 = {
|
|
3168
|
+
...state,
|
|
3169
|
+
root: newRoot
|
|
3170
|
+
};
|
|
3171
|
+
const newState = await loadContent(state1, undefined);
|
|
3172
|
+
return newState;
|
|
3173
|
+
};
|
|
3174
|
+
|
|
3199
3175
|
const ExplorerEditBox = FocusExplorerEditBox;
|
|
3200
3176
|
|
|
3201
3177
|
const setFocus = key => {
|
|
@@ -3215,7 +3191,7 @@ const newDirent = async (state, editingType) => {
|
|
|
3215
3191
|
if (dirent.type === Directory) {
|
|
3216
3192
|
// TODO handle error
|
|
3217
3193
|
// @ts-ignore
|
|
3218
|
-
await
|
|
3194
|
+
await handleClickDirectory(state, dirent);
|
|
3219
3195
|
}
|
|
3220
3196
|
}
|
|
3221
3197
|
return {
|
|
@@ -3377,6 +3353,7 @@ const renderActions = state => {
|
|
|
3377
3353
|
const getSavedRoot = (savedState, workspacePath) => {
|
|
3378
3354
|
return workspacePath;
|
|
3379
3355
|
};
|
|
3356
|
+
|
|
3380
3357
|
const restoreState = savedState => {
|
|
3381
3358
|
if (!savedState) {
|
|
3382
3359
|
return {
|
|
@@ -3674,7 +3651,7 @@ const setDeltaY = (state, deltaY) => {
|
|
|
3674
3651
|
};
|
|
3675
3652
|
|
|
3676
3653
|
const updateEditingValue = (state, value) => {
|
|
3677
|
-
const editingIcon = getFileIcon({
|
|
3654
|
+
const editingIcon = getFileIcon$1({
|
|
3678
3655
|
name: value
|
|
3679
3656
|
});
|
|
3680
3657
|
return {
|
|
@@ -3717,6 +3694,7 @@ const commandMap = {
|
|
|
3717
3694
|
'Explorer.handlePointerDown': handlePointerDown,
|
|
3718
3695
|
'Explorer.handleUpload': handleUpload,
|
|
3719
3696
|
'Explorer.handleWheel': handleWheel,
|
|
3697
|
+
'Explorer.handleWorkspaceChange': handleWorkspaceChange,
|
|
3720
3698
|
'Explorer.loadContent': loadContent,
|
|
3721
3699
|
'Explorer.newFile': newFile,
|
|
3722
3700
|
'Explorer.newFolder': newFolder,
|
|
@@ -3728,7 +3706,8 @@ const commandMap = {
|
|
|
3728
3706
|
'Explorer.revealItem': revealItem,
|
|
3729
3707
|
'Explorer.saveState': saveState,
|
|
3730
3708
|
'Explorer.setDeltaY': setDeltaY,
|
|
3731
|
-
'Explorer.updateEditingValue': updateEditingValue
|
|
3709
|
+
'Explorer.updateEditingValue': updateEditingValue,
|
|
3710
|
+
'Explorer.updateIcons': updateIcons
|
|
3732
3711
|
};
|
|
3733
3712
|
|
|
3734
3713
|
const listen = async () => {
|