@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.
@@ -1,747 +1,799 @@
1
- const Two = '2.0';
2
- const create$4 = (method, params) => {
3
- return {
4
- jsonrpc: Two,
5
- method,
6
- params
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 state$1 = {
10
- callbacks: Object.create(null)
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 set = (id, fn) => {
13
- state$1.callbacks[id] = fn;
17
+ const NewLine$2 = '\n';
18
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
19
+ return string.indexOf(NewLine$2, startIndex);
14
20
  };
15
- const get = id => {
16
- return state$1.callbacks[id];
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
- const remove$1 = id => {
19
- delete state$1.callbacks[id];
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
- let id = 0;
22
- const create$3 = () => {
23
- return ++id;
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 warn = (...args) => {
26
- console.warn(...args);
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 registerPromise = () => {
29
- const id = create$3();
30
- const {
31
- resolve,
32
- promise
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 resolve = (id, response) => {
41
- const fn = get(id);
42
- if (!fn) {
43
- console.log(response);
44
- warn(`callback ${id} may already be disposed`);
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 create$2 = (method, params) => {
51
- const {
52
- id,
53
- promise
54
- } = registerPromise();
55
- const message = {
56
- jsonrpc: Two,
57
- method,
58
- params,
59
- id
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
- promise
199
+ code: ERR_MODULE_NOT_FOUND
64
200
  };
65
201
  };
66
- class JsonRpcError extends Error {
67
- constructor(message) {
68
- super(message);
69
- this.name = 'JsonRpcError';
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
- const NewLine$3 = '\n';
73
- const DomException = 'DOMException';
74
- const ReferenceError$1 = 'ReferenceError';
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
- if (message.startsWith('TypeError: ')) {
93
- return TypeError;
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 (message.startsWith('SyntaxError: ')) {
96
- return SyntaxError;
276
+ if (isModulesSyntaxError(stderr)) {
277
+ return getModuleSyntaxError();
97
278
  }
98
- if (message.startsWith('ReferenceError: ')) {
99
- return ReferenceError;
279
+ if (isModuleNotFoundError(stderr)) {
280
+ return getModuleNotFoundError(stderr);
100
281
  }
101
- return Error;
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
- const constructError = (message, type, name) => {
104
- const ErrorConstructor = getErrorConstructor(message, type);
105
- if (ErrorConstructor === DOMException && name) {
106
- return new ErrorConstructor(message, name);
107
- }
108
- if (ErrorConstructor === Error) {
109
- const error = new Error(message);
110
- if (name && name !== 'VError') {
111
- error.name = name;
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
- return error;
311
+ // @ts-ignore
312
+ this.name = 'IpcError';
313
+ // @ts-ignore
314
+ this.stdout = stdout;
315
+ // @ts-ignore
316
+ this.stderr = stderr;
114
317
  }
115
- return new ErrorConstructor(message);
116
- };
117
- const getNewLineIndex$2 = (string, startIndex = undefined) => {
118
- return string.indexOf(NewLine$3, startIndex);
318
+ }
319
+ const readyMessage = 'ready';
320
+ const getData$2 = event => {
321
+ return event.data;
119
322
  };
120
- const getParentStack = error => {
121
- let parentStack = error.stack || error.data || error.message || '';
122
- if (parentStack.startsWith(' at')) {
123
- parentStack = error.message + NewLine$3 + parentStack;
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 parentStack;
126
- };
127
- const joinLines$1 = lines => {
128
- return lines.join(NewLine$3);
328
+ return globalThis;
129
329
  };
130
- const MethodNotFound = -32601;
131
- const Custom = -32001;
132
- const splitLines$1 = lines => {
133
- return lines.split(NewLine$3);
330
+ const signal$6 = global => {
331
+ global.postMessage(readyMessage);
134
332
  };
135
- const restoreJsonRpcError = error => {
136
- if (error && error instanceof Error) {
137
- return error;
333
+ class IpcChildWithModuleWorker extends Ipc {
334
+ getData(event) {
335
+ return getData$2(event);
138
336
  }
139
- const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(1));
140
- if (error && error.code && error.code === MethodNotFound) {
141
- const restoredError = new JsonRpcError(error.message);
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
- if (error && error.message) {
147
- const restoredError = constructError(error.message, error.type, error.name);
148
- if (error.data) {
149
- if (error.data.stack && error.data.type && error.message) {
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
- if (typeof error === 'string') {
183
- return new Error(`JsonRpc Error: ${error}`);
346
+ dispose() {
347
+ // ignore
184
348
  }
185
- return new Error(`JsonRpc Error: ${error}`);
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
- if ('result' in responseMessage) {
193
- return responseMessage.result;
352
+ onMessage(callback) {
353
+ this._rawIpc.addEventListener('message', callback);
194
354
  }
195
- throw new JsonRpcError('unexpected response message');
355
+ }
356
+ const wrap$d = global => {
357
+ return new IpcChildWithModuleWorker(global);
196
358
  };
197
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
198
- const getErrorType = prettyError => {
199
- if (prettyError && prettyError.type) {
200
- return prettyError.type;
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
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
203
- return prettyError.constructor.name;
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 undefined;
400
+ return globalThis;
206
401
  };
207
- const getErrorProperty = (error, prettyError) => {
208
- if (error && error.code === E_COMMAND_NOT_FOUND) {
209
- return {
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
- return {
216
- code: Custom,
217
- message: prettyError.message,
218
- data: {
219
- stack: prettyError.stack,
220
- codeFrame: prettyError.codeFrame,
221
- type: getErrorType(prettyError),
222
- code: prettyError.code,
223
- name: prettyError.name
224
- }
225
- };
226
- };
227
- const create$1 = (message, error) => {
228
- return {
229
- jsonrpc: Two,
230
- id: message.id,
231
- error
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 getErrorResponse = (message, error, preparePrettyError, logError) => {
235
- const prettyError = preparePrettyError(error);
236
- logError(error, prettyError);
237
- const errorProperty = getErrorProperty(error, prettyError);
238
- return create$1(message, errorProperty);
432
+ const IpcChildWithModuleWorkerAndMessagePort$1 = {
433
+ __proto__: null,
434
+ listen: listen$5,
435
+ wrap: wrap$c
239
436
  };
240
- const create$5 = (message, result) => {
437
+
438
+ const Two = '2.0';
439
+ const create$4 = (method, params) => {
241
440
  return {
242
441
  jsonrpc: Two,
243
- id: message.id,
244
- result: result ?? null
442
+ method,
443
+ params
245
444
  };
246
445
  };
247
- const getSuccessResponse = (message, result) => {
248
- const resultProperty = result ?? null;
249
- return create$5(message, resultProperty);
446
+ const callbacks = Object.create(null);
447
+ const set = (id, fn) => {
448
+ callbacks[id] = fn;
250
449
  };
251
- const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
252
- try {
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 defaultPreparePrettyError = error => {
260
- return error;
453
+ const remove$1 = id => {
454
+ delete callbacks[id];
261
455
  };
262
- const defaultLogError = () => {
263
- // ignore
456
+ let id = 0;
457
+ const create$3 = () => {
458
+ return ++id;
264
459
  };
265
- const defaultRequiresSocket = () => {
266
- return false;
460
+ const warn = (...args) => {
461
+ console.warn(...args);
267
462
  };
268
- const defaultResolve = resolve;
269
-
270
- // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
271
- const normalizeParams = args => {
272
- if (args.length === 1) {
273
- const options = args[0];
274
- return {
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
- ipc: args[0],
286
- message: args[1],
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 handleJsonRpcMessage = async (...args) => {
295
- const options = normalizeParams(args);
296
- const {
297
- message,
298
- ipc,
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
- throw new JsonRpcError('unexpected message');
482
+ fn(response);
483
+ remove$1(id);
324
484
  };
325
- const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
485
+ const create$2 = (method, params) => {
326
486
  const {
327
- message,
487
+ id,
328
488
  promise
329
- } = create$2(method, params);
330
- if (useSendAndTransfer && ipc.sendAndTransfer) {
331
- ipc.sendAndTransfer(message);
332
- } else {
333
- ipc.send(message);
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
- that.onMessage(handleMessage);
375
- const handleClose = event => {
376
- that.dispatchEvent(new Event('close'));
496
+ return {
497
+ message,
498
+ promise
377
499
  };
378
- that.onClose(handleClose);
379
500
  };
380
- class Ipc extends EventTarget {
381
- constructor(rawIpc) {
382
- super();
383
- this._rawIpc = rawIpc;
384
- attachEvents(this);
501
+ class JsonRpcError extends Error {
502
+ constructor(message) {
503
+ super(message);
504
+ this.name = 'JsonRpcError';
385
505
  }
386
506
  }
387
- const readyMessage = 'ready';
388
- const walkValue = (value, transferrables, isTransferrable) => {
389
- if (!value) {
390
- return;
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 (isTransferrable(value)) {
393
- transferrables.push(value);
394
- return;
527
+ if (message.startsWith('TypeError: ')) {
528
+ return TypeError;
395
529
  }
396
- if (Array.isArray(value)) {
397
- for (const item of value) {
398
- walkValue(item, transferrables, isTransferrable);
399
- }
400
- return;
530
+ if (message.startsWith('SyntaxError: ')) {
531
+ return SyntaxError;
401
532
  }
402
- if (typeof value === 'object') {
403
- for (const property of Object.values(value)) {
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 isMessagePort = value => {
410
- return value && value instanceof MessagePort;
411
- };
412
- const isMessagePortMain = value => {
413
- return value && value.constructor && value.constructor.name === 'MessagePortMain';
414
- };
415
- const isOffscreenCanvas = value => {
416
- return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
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 false;
550
+ return new ErrorConstructor(message);
432
551
  };
433
- const getTransferrables = value => {
434
- const transferrables = [];
435
- walkValue(value, transferrables, isTransferrable);
436
- return transferrables;
552
+ const getNewLineIndex = (string, startIndex = undefined) => {
553
+ return string.indexOf(NewLine, startIndex);
437
554
  };
438
- const listen$2 = () => {
439
- // @ts-ignore
440
- if (typeof WorkerGlobalScope === 'undefined') {
441
- throw new TypeError('module is not in web worker scope');
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 globalThis;
560
+ return parentStack;
444
561
  };
445
- const signal$2 = global => {
446
- global.postMessage(readyMessage);
562
+ const joinLines = lines => {
563
+ return lines.join(NewLine);
447
564
  };
448
- class IpcChildWithModuleWorker extends Ipc {
449
- getData(event) {
450
- return getData$1(event);
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
- send(message) {
453
- // @ts-ignore
454
- this._rawIpc.postMessage(message);
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
- sendAndTransfer(message) {
457
- const transfer = getTransferrables(message);
458
- // @ts-ignore
459
- this._rawIpc.postMessage(message, transfer);
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
- dispose() {
462
- // ignore
617
+ if (typeof error === 'string') {
618
+ return new Error(`JsonRpc Error: ${error}`);
463
619
  }
464
- onClose(callback) {
465
- // ignore
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
- onMessage(callback) {
468
- this._rawIpc.addEventListener('message', callback);
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 isModulesSyntaxError = stderr => {
527
- if (!stderr) {
528
- return false;
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
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
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 stderr.includes('ERR_MODULE_NOT_FOUND');
543
- };
544
- const isNormalStackLine = line => {
545
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
640
+ return undefined;
546
641
  };
547
- const getDetails = lines => {
548
- const index = lines.findIndex(isNormalStackLine);
549
- if (index === -1) {
642
+ const getErrorProperty = (error, prettyError) => {
643
+ if (error && error.code === E_COMMAND_NOT_FOUND) {
550
644
  return {
551
- actualMessage: joinLines(lines),
552
- rest: []
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
- actualMessage: lines[index - 1],
563
- rest: lines.slice(index, lastIndex)
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 getHelpfulChildProcessError = (stdout, stderr) => {
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
- message: `${actualMessage}`,
583
- code: '',
584
- stack: rest
664
+ jsonrpc: Two,
665
+ id: message.id,
666
+ error
585
667
  };
586
668
  };
587
- const normalizeLine$1 = line => {
588
- if (line.startsWith('Error: ')) {
589
- return line.slice('Error: '.length);
590
- }
591
- if (line.startsWith('VError: ')) {
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 mergeStacks$1 = (parent, child) => {
608
- if (!child) {
609
- return parent;
610
- }
611
- const parentNewLineIndex = getNewLineIndex$1(parent);
612
- const childNewLineIndex = getNewLineIndex$1(child);
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
- let VError$1 = class VError extends Error {
625
- constructor(error, message) {
626
- const combinedMessage = getCombinedMessage$1(error, message);
627
- super(combinedMessage);
628
- this.name = 'VError';
629
- if (error instanceof Error) {
630
- this.stack = mergeStacks$1(this.stack, error.stack);
631
- }
632
- if (error.codeFrame) {
633
- // @ts-ignore
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
- class IpcError extends VError$1 {
643
- // @ts-ignore
644
- constructor(betterMessage, stdout = '', stderr = '') {
645
- if (stdout || stderr) {
646
- // @ts-ignore
647
- const {
648
- message,
649
- code,
650
- stack
651
- } = getHelpfulChildProcessError(stdout, stderr);
652
- const cause = new Error(message);
653
- // @ts-ignore
654
- cause.code = code;
655
- cause.stack = stack;
656
- super(cause, betterMessage);
657
- } else {
658
- super(betterMessage);
659
- }
660
- // @ts-ignore
661
- this.name = 'IpcError';
662
- // @ts-ignore
663
- this.stdout = stdout;
664
- // @ts-ignore
665
- this.stderr = stderr;
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
- resolve: _resolve,
675
- promise
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 waitForFirstMessage = async port => {
729
+ const handleJsonRpcMessage = async (...args) => {
730
+ const options = normalizeParams(args);
679
731
  const {
732
+ message,
733
+ ipc,
734
+ execute,
680
735
  resolve,
681
- promise
682
- } = withResolvers();
683
- port.addEventListener('message', resolve, {
684
- once: true
685
- });
686
- const event = await promise;
687
- // @ts-ignore
688
- return event.data;
689
- };
690
- const listen$1$1 = async () => {
691
- const parentIpcRaw = listen$2();
692
- signal$2(parentIpcRaw);
693
- const parentIpc = wrap$5(parentIpcRaw);
694
- const firstMessage = await waitForFirstMessage(parentIpc);
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
- onClose(callback) {
731
- // ignore
754
+ if ('method' in message) {
755
+ await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
756
+ return;
732
757
  }
733
- onMessage(callback) {
734
- this._rawIpc.addEventListener('message', callback);
735
- this._rawIpc.start();
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
- const wrap$4 = port => {
739
- return new IpcChildWithModuleWorkerAndMessagePort(port);
770
+ const responseMessage = await promise;
771
+ return unwrapJsonRpcResult(responseMessage);
740
772
  };
741
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
742
- __proto__: null,
743
- listen: listen$1$1,
744
- wrap: wrap$4
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
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
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
- ipc.addEventListener('message', handleMessage);
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
- // @ts-ignore
781
- const listen$1 = async () => {
782
- const module = IpcChildWithModuleWorkerAndMessagePort$1;
783
- const rawIpc = await module.listen();
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 array = value => {
1263
- const type = getType(value);
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
- const string = value => {
1269
- const type = getType(value);
1270
- if (type !== 'string') {
1271
- throw new AssertionError('expected value to be of type string');
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
- // TODO viewlet should only have create and refresh functions
2217
- // every thing else can be in a separate module <viewlet>.lazy.js
2218
- // and <viewlet>.ipc.js
2219
-
2220
- // viewlet: creating | refreshing | done | disposed
2221
- // TODO recycle viewlets (maybe)
2222
-
2223
- // TODO instead of root string, there should be a root dirent
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 handleClickDirectory$1 = async (state, dirent, index, keepFocus) => {
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
- const handleClickDirectoryExpanding = (state, dirent, index, keepFocus) => {
2275
- dirent.type = Directory;
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$1;
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 handlePaste = async state => {
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 (nativeFiles.type) {
2948
+ switch (type) {
3003
2949
  case None:
3004
- return handlePasteNone(state);
2950
+ return handlePasteNone;
3005
2951
  case Copy:
3006
- return handlePasteCopy(state, nativeFiles);
2952
+ return handlePasteCopy;
3007
2953
  case Cut:
3008
- return handlePasteCut(state, nativeFiles);
2954
+ return handlePasteCut;
3009
2955
  default:
3010
- throw new Error(`unexpected native paste type: ${nativeFiles.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 undefined(state, dirent, focusedIndex);
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 () => {