@lvce-editor/extension-detail-view 2.2.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,59 @@
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;
9
+ };
10
+ const getCombinedMessage = (error, message) => {
11
+ const stringifiedError = normalizeLine(`${error}`);
12
+ if (message) {
13
+ return `${message}: ${stringifiedError}`;
14
+ }
15
+ return stringifiedError;
16
+ };
17
+ const NewLine$2 = '\n';
18
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
19
+ return string.indexOf(NewLine$2, startIndex);
20
+ };
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;
37
+ };
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
+
1
57
  class AssertionError extends Error {
2
58
  constructor(message) {
3
59
  super(message);
@@ -39,754 +95,697 @@ const string = value => {
39
95
  }
40
96
  };
41
97
 
42
- const Two = '2.0';
43
- const create$4 = (method, params) => {
44
- return {
45
- jsonrpc: Two,
46
- method,
47
- params
48
- };
49
- };
50
- const state$1 = {
51
- callbacks: Object.create(null)
52
- };
53
- const set = (id, fn) => {
54
- state$1.callbacks[id] = fn;
98
+ const isMessagePort = value => {
99
+ return value && value instanceof MessagePort;
55
100
  };
56
- const get = id => {
57
- return state$1.callbacks[id];
101
+ const isMessagePortMain = value => {
102
+ return value && value.constructor && value.constructor.name === 'MessagePortMain';
58
103
  };
59
- const remove = id => {
60
- delete state$1.callbacks[id];
104
+ const isOffscreenCanvas = value => {
105
+ return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
61
106
  };
62
- let id = 0;
63
- const create$3 = () => {
64
- return ++id;
107
+ const isInstanceOf = (value, constructorName) => {
108
+ return value?.constructor?.name === constructorName;
65
109
  };
66
- const warn = (...args) => {
67
- console.warn(...args);
110
+ const isSocket = value => {
111
+ return isInstanceOf(value, 'Socket');
68
112
  };
69
- const registerPromise = () => {
70
- const id = create$3();
71
- const {
72
- resolve,
73
- promise
74
- } = Promise.withResolvers();
75
- set(id, resolve);
76
- return {
77
- id,
78
- promise
79
- };
113
+ const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
114
+ const isTransferrable = value => {
115
+ for (const fn of transferrables) {
116
+ if (fn(value)) {
117
+ return true;
118
+ }
119
+ }
120
+ return false;
80
121
  };
81
- const resolve = (id, response) => {
82
- const fn = get(id);
83
- if (!fn) {
84
- console.log(response);
85
- warn(`callback ${id} may already be disposed`);
122
+ const walkValue = (value, transferrables, isTransferrable) => {
123
+ if (!value) {
124
+ return;
125
+ }
126
+ if (isTransferrable(value)) {
127
+ transferrables.push(value);
128
+ return;
129
+ }
130
+ if (Array.isArray(value)) {
131
+ for (const item of value) {
132
+ walkValue(item, transferrables, isTransferrable);
133
+ }
134
+ return;
135
+ }
136
+ if (typeof value === 'object') {
137
+ for (const property of Object.values(value)) {
138
+ walkValue(property, transferrables, isTransferrable);
139
+ }
86
140
  return;
87
141
  }
88
- fn(response);
89
- remove(id);
90
142
  };
91
- const create$2 = (method, params) => {
92
- const {
93
- id,
94
- promise
95
- } = registerPromise();
96
- const message = {
97
- jsonrpc: Two,
98
- method,
99
- params,
100
- id
143
+ const getTransferrables = value => {
144
+ const transferrables = [];
145
+ walkValue(value, transferrables, isTransferrable);
146
+ return transferrables;
147
+ };
148
+ const attachEvents = that => {
149
+ const handleMessage = (...args) => {
150
+ const data = that.getData(...args);
151
+ that.dispatchEvent(new MessageEvent('message', {
152
+ data
153
+ }));
101
154
  };
102
- return {
103
- message,
104
- promise
155
+ that.onMessage(handleMessage);
156
+ const handleClose = event => {
157
+ that.dispatchEvent(new Event('close'));
105
158
  };
159
+ that.onClose(handleClose);
106
160
  };
107
- class JsonRpcError extends Error {
108
- constructor(message) {
109
- super(message);
110
- this.name = 'JsonRpcError';
161
+ class Ipc extends EventTarget {
162
+ constructor(rawIpc) {
163
+ super();
164
+ this._rawIpc = rawIpc;
165
+ attachEvents(this);
111
166
  }
112
167
  }
113
- const NewLine$2 = '\n';
114
- const DomException = 'DOMException';
115
- const ReferenceError$1 = 'ReferenceError';
116
- const SyntaxError$1 = 'SyntaxError';
117
- const TypeError$1 = 'TypeError';
118
- const getErrorConstructor = (message, type) => {
119
- if (type) {
120
- switch (type) {
121
- case DomException:
122
- return DOMException;
123
- case TypeError$1:
124
- return TypeError;
125
- case SyntaxError$1:
126
- return SyntaxError;
127
- case ReferenceError$1:
128
- return ReferenceError;
129
- default:
130
- return Error;
131
- }
132
- }
133
- if (message.startsWith('TypeError: ')) {
134
- return TypeError;
135
- }
136
- if (message.startsWith('SyntaxError: ')) {
137
- return SyntaxError;
138
- }
139
- if (message.startsWith('ReferenceError: ')) {
140
- return ReferenceError;
141
- }
142
- return Error;
168
+ const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
169
+ const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
170
+ const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
171
+ const NewLine$1 = '\n';
172
+ const joinLines$1 = lines => {
173
+ return lines.join(NewLine$1);
143
174
  };
144
- const constructError = (message, type, name) => {
145
- const ErrorConstructor = getErrorConstructor(message, type);
146
- if (ErrorConstructor === DOMException && name) {
147
- return new ErrorConstructor(message, name);
175
+ const RE_AT = /^\s+at/;
176
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
177
+ const isNormalStackLine = line => {
178
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
179
+ };
180
+ const getDetails = lines => {
181
+ const index = lines.findIndex(isNormalStackLine);
182
+ if (index === -1) {
183
+ return {
184
+ actualMessage: joinLines$1(lines),
185
+ rest: []
186
+ };
148
187
  }
149
- if (ErrorConstructor === Error) {
150
- const error = new Error(message);
151
- if (name && name !== 'VError') {
152
- error.name = name;
188
+ let lastIndex = index - 1;
189
+ while (++lastIndex < lines.length) {
190
+ if (!isNormalStackLine(lines[lastIndex])) {
191
+ break;
153
192
  }
154
- return error;
155
193
  }
156
- return new ErrorConstructor(message);
194
+ return {
195
+ actualMessage: lines[index - 1],
196
+ rest: lines.slice(index, lastIndex)
197
+ };
157
198
  };
158
- const getNewLineIndex$1 = (string, startIndex = undefined) => {
159
- return string.indexOf(NewLine$2, startIndex);
199
+ const splitLines$1 = lines => {
200
+ return lines.split(NewLine$1);
160
201
  };
161
- const getParentStack = error => {
162
- let parentStack = error.stack || error.data || error.message || '';
163
- if (parentStack.startsWith(' at')) {
164
- parentStack = error.message + NewLine$2 + parentStack;
165
- }
166
- return parentStack;
202
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
203
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
204
+ const isMessageCodeBlockStartIndex = line => {
205
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
167
206
  };
168
- const joinLines$1 = lines => {
169
- return lines.join(NewLine$2);
207
+ const isMessageCodeBlockEndIndex = line => {
208
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
170
209
  };
171
- const MethodNotFound = -32601;
172
- const Custom = -32001;
173
- const splitLines$1 = lines => {
174
- return lines.split(NewLine$2);
210
+ const getMessageCodeBlock = stderr => {
211
+ const lines = splitLines$1(stderr);
212
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
213
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
214
+ const relevantLines = lines.slice(startIndex, endIndex);
215
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
216
+ return relevantMessage;
175
217
  };
176
- const restoreJsonRpcError = error => {
177
- if (error && error instanceof Error) {
178
- return error;
179
- }
180
- const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(1));
181
- if (error && error.code && error.code === MethodNotFound) {
182
- const restoredError = new JsonRpcError(error.message);
183
- const parentStack = getParentStack(error);
184
- restoredError.stack = parentStack + NewLine$2 + currentStack;
185
- return restoredError;
186
- }
187
- if (error && error.message) {
188
- const restoredError = constructError(error.message, error.type, error.name);
189
- if (error.data) {
190
- if (error.data.stack && error.data.type && error.message) {
191
- restoredError.stack = error.data.type + ': ' + error.message + NewLine$2 + error.data.stack + NewLine$2 + currentStack;
192
- } else if (error.data.stack) {
193
- restoredError.stack = error.data.stack;
194
- }
195
- if (error.data.codeFrame) {
196
- // @ts-ignore
197
- restoredError.codeFrame = error.data.codeFrame;
198
- }
199
- if (error.data.code) {
200
- // @ts-ignore
201
- restoredError.code = error.data.code;
202
- }
203
- if (error.data.type) {
204
- // @ts-ignore
205
- restoredError.name = error.data.type;
206
- }
207
- } else {
208
- if (error.stack) {
209
- const lowerStack = restoredError.stack || '';
210
- // @ts-ignore
211
- const indexNewLine = getNewLineIndex$1(lowerStack);
212
- const parentStack = getParentStack(error);
213
- // @ts-ignore
214
- restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
215
- }
216
- if (error.codeFrame) {
217
- // @ts-ignore
218
- restoredError.codeFrame = error.codeFrame;
219
- }
220
- }
221
- return restoredError;
222
- }
223
- if (typeof error === 'string') {
224
- return new Error(`JsonRpc Error: ${error}`);
225
- }
226
- return new Error(`JsonRpc Error: ${error}`);
218
+ const isModuleNotFoundMessage = line => {
219
+ return line.includes('[ERR_MODULE_NOT_FOUND]');
227
220
  };
228
- const unwrapJsonRpcResult = responseMessage => {
229
- if ('error' in responseMessage) {
230
- const restoredError = restoreJsonRpcError(responseMessage.error);
231
- throw restoredError;
232
- }
233
- if ('result' in responseMessage) {
234
- return responseMessage.result;
235
- }
236
- throw new JsonRpcError('unexpected response message');
221
+ const getModuleNotFoundError = stderr => {
222
+ const lines = splitLines$1(stderr);
223
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
224
+ const message = lines[messageIndex];
225
+ return {
226
+ message,
227
+ code: ERR_MODULE_NOT_FOUND
228
+ };
237
229
  };
238
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
239
- const getErrorType = prettyError => {
240
- if (prettyError && prettyError.type) {
241
- return prettyError.type;
242
- }
243
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
244
- return prettyError.constructor.name;
230
+ const isModuleNotFoundError = stderr => {
231
+ if (!stderr) {
232
+ return false;
245
233
  }
246
- return undefined;
234
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
247
235
  };
248
- const getErrorProperty = (error, prettyError) => {
249
- if (error && error.code === E_COMMAND_NOT_FOUND) {
250
- return {
251
- code: MethodNotFound,
252
- message: error.message,
253
- data: error.stack
254
- };
236
+ const isModulesSyntaxError = stderr => {
237
+ if (!stderr) {
238
+ return false;
255
239
  }
240
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
241
+ };
242
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
243
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
244
+ const isUnhelpfulNativeModuleError = stderr => {
245
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
246
+ };
247
+ const getNativeModuleErrorMessage = stderr => {
248
+ const message = getMessageCodeBlock(stderr);
256
249
  return {
257
- code: Custom,
258
- message: prettyError.message,
259
- data: {
260
- stack: prettyError.stack,
261
- codeFrame: prettyError.codeFrame,
262
- type: getErrorType(prettyError),
263
- code: prettyError.code,
264
- name: prettyError.name
265
- }
250
+ message: `Incompatible native node module: ${message}`,
251
+ code: E_INCOMPATIBLE_NATIVE_MODULE
266
252
  };
267
253
  };
268
- const create$1 = (message, error) => {
254
+ const getModuleSyntaxError = () => {
269
255
  return {
270
- jsonrpc: Two,
271
- id: message.id,
272
- error
256
+ message: `ES Modules are not supported in electron`,
257
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
273
258
  };
274
259
  };
275
- const getErrorResponse = (message, error, preparePrettyError, logError) => {
276
- const prettyError = preparePrettyError(error);
277
- logError(error, prettyError);
278
- const errorProperty = getErrorProperty(error, prettyError);
279
- return create$1(message, errorProperty);
280
- };
281
- const create$5 = (message, result) => {
260
+ const getHelpfulChildProcessError = (stdout, stderr) => {
261
+ if (isUnhelpfulNativeModuleError(stderr)) {
262
+ return getNativeModuleErrorMessage(stderr);
263
+ }
264
+ if (isModulesSyntaxError(stderr)) {
265
+ return getModuleSyntaxError();
266
+ }
267
+ if (isModuleNotFoundError(stderr)) {
268
+ return getModuleNotFoundError(stderr);
269
+ }
270
+ const lines = splitLines$1(stderr);
271
+ const {
272
+ actualMessage,
273
+ rest
274
+ } = getDetails(lines);
282
275
  return {
283
- jsonrpc: Two,
284
- id: message.id,
285
- result: result ?? null
276
+ message: actualMessage,
277
+ code: '',
278
+ stack: rest
286
279
  };
287
280
  };
288
- const getSuccessResponse = (message, result) => {
289
- const resultProperty = result ?? null;
290
- return create$5(message, resultProperty);
291
- };
292
- const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
293
- try {
294
- const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
295
- return getSuccessResponse(message, result);
296
- } catch (error) {
297
- return getErrorResponse(message, error, preparePrettyError, logError);
281
+ class IpcError extends VError {
282
+ // @ts-ignore
283
+ constructor(betterMessage, stdout = '', stderr = '') {
284
+ if (stdout || stderr) {
285
+ // @ts-ignore
286
+ const {
287
+ message,
288
+ code,
289
+ stack
290
+ } = getHelpfulChildProcessError(stdout, stderr);
291
+ const cause = new Error(message);
292
+ // @ts-ignore
293
+ cause.code = code;
294
+ cause.stack = stack;
295
+ super(cause, betterMessage);
296
+ } else {
297
+ super(betterMessage);
298
+ }
299
+ // @ts-ignore
300
+ this.name = 'IpcError';
301
+ // @ts-ignore
302
+ this.stdout = stdout;
303
+ // @ts-ignore
304
+ this.stderr = stderr;
298
305
  }
306
+ }
307
+ const readyMessage = 'ready';
308
+ const getData$2 = event => {
309
+ return event.data;
299
310
  };
300
- const defaultPreparePrettyError = error => {
301
- return error;
302
- };
303
- const defaultLogError = () => {
304
- // ignore
311
+ const listen$7 = () => {
312
+ // @ts-ignore
313
+ if (typeof WorkerGlobalScope === 'undefined') {
314
+ throw new TypeError('module is not in web worker scope');
315
+ }
316
+ return globalThis;
305
317
  };
306
- const defaultRequiresSocket = () => {
307
- return false;
318
+ const signal$8 = global => {
319
+ global.postMessage(readyMessage);
308
320
  };
309
- const defaultResolve = resolve;
310
-
311
- // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
312
- const normalizeParams = args => {
313
- if (args.length === 1) {
314
- const options = args[0];
315
- return {
316
- ipc: options.ipc,
317
- message: options.message,
318
- execute: options.execute,
319
- resolve: options.resolve || defaultResolve,
320
- preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
321
- logError: options.logError || defaultLogError,
322
- requiresSocket: options.requiresSocket || defaultRequiresSocket
323
- };
321
+ class IpcChildWithModuleWorker extends Ipc {
322
+ getData(event) {
323
+ return getData$2(event);
324
+ }
325
+ send(message) {
326
+ // @ts-ignore
327
+ this._rawIpc.postMessage(message);
328
+ }
329
+ sendAndTransfer(message) {
330
+ const transfer = getTransferrables(message);
331
+ // @ts-ignore
332
+ this._rawIpc.postMessage(message, transfer);
333
+ }
334
+ dispose() {
335
+ // ignore
336
+ }
337
+ onClose(callback) {
338
+ // ignore
339
+ }
340
+ onMessage(callback) {
341
+ this._rawIpc.addEventListener('message', callback);
324
342
  }
343
+ }
344
+ const wrap$f = global => {
345
+ return new IpcChildWithModuleWorker(global);
346
+ };
347
+ const withResolvers = () => {
348
+ let _resolve;
349
+ const promise = new Promise(resolve => {
350
+ _resolve = resolve;
351
+ });
325
352
  return {
326
- ipc: args[0],
327
- message: args[1],
328
- execute: args[2],
329
- resolve: args[3],
330
- preparePrettyError: args[4],
331
- logError: args[5],
332
- requiresSocket: args[6]
353
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
354
+ resolve: _resolve,
355
+ promise
333
356
  };
334
357
  };
335
- const handleJsonRpcMessage = async (...args) => {
336
- const options = normalizeParams(args);
358
+ const waitForFirstMessage = async port => {
337
359
  const {
338
- message,
339
- ipc,
340
- execute,
341
360
  resolve,
342
- preparePrettyError,
343
- logError,
344
- requiresSocket
345
- } = options;
346
- if ('id' in message) {
347
- if ('method' in message) {
348
- const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
349
- try {
350
- ipc.send(response);
351
- } catch (error) {
352
- const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
353
- ipc.send(errorResponse);
354
- }
355
- return;
361
+ promise
362
+ } = withResolvers();
363
+ port.addEventListener('message', resolve, {
364
+ once: true
365
+ });
366
+ const event = await promise;
367
+ // @ts-ignore
368
+ return event.data;
369
+ };
370
+ const listen$6 = async () => {
371
+ const parentIpcRaw = listen$7();
372
+ signal$8(parentIpcRaw);
373
+ const parentIpc = wrap$f(parentIpcRaw);
374
+ const firstMessage = await waitForFirstMessage(parentIpc);
375
+ if (firstMessage.method !== 'initialize') {
376
+ throw new IpcError('unexpected first message');
377
+ }
378
+ const type = firstMessage.params[0];
379
+ if (type === 'message-port') {
380
+ parentIpc.send({
381
+ jsonrpc: '2.0',
382
+ id: firstMessage.id,
383
+ result: null
384
+ });
385
+ parentIpc.dispose();
386
+ const port = firstMessage.params[1];
387
+ return port;
388
+ }
389
+ return globalThis;
390
+ };
391
+ class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
392
+ getData(event) {
393
+ return getData$2(event);
394
+ }
395
+ send(message) {
396
+ this._rawIpc.postMessage(message);
397
+ }
398
+ sendAndTransfer(message) {
399
+ const transfer = getTransferrables(message);
400
+ this._rawIpc.postMessage(message, transfer);
401
+ }
402
+ dispose() {
403
+ if (this._rawIpc.close) {
404
+ this._rawIpc.close();
356
405
  }
357
- resolve(message.id, message);
358
- return;
359
406
  }
360
- if ('method' in message) {
361
- await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
362
- return;
407
+ onClose(callback) {
408
+ // ignore
363
409
  }
364
- throw new JsonRpcError('unexpected message');
365
- };
366
- const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
367
- const {
368
- message,
369
- promise
370
- } = create$2(method, params);
371
- if (useSendAndTransfer && ipc.sendAndTransfer) {
372
- ipc.sendAndTransfer(message);
373
- } else {
374
- ipc.send(message);
410
+ onMessage(callback) {
411
+ this._rawIpc.addEventListener('message', callback);
412
+ this._rawIpc.start();
375
413
  }
376
- const responseMessage = await promise;
377
- return unwrapJsonRpcResult(responseMessage);
414
+ }
415
+ const wrap$e = port => {
416
+ return new IpcChildWithModuleWorkerAndMessagePort(port);
378
417
  };
379
- const send = (transport, method, ...params) => {
380
- const message = create$4(method, params);
381
- transport.send(message);
418
+ const IpcChildWithModuleWorkerAndMessagePort$1 = {
419
+ __proto__: null,
420
+ listen: listen$6,
421
+ wrap: wrap$e
382
422
  };
383
- const invoke$1 = (ipc, method, ...params) => {
384
- return invokeHelper(ipc, method, params, false);
423
+
424
+ const Two = '2.0';
425
+ const create$4 = (method, params) => {
426
+ return {
427
+ jsonrpc: Two,
428
+ method,
429
+ params
430
+ };
385
431
  };
386
- const invokeAndTransfer = (ipc, method, ...params) => {
387
- return invokeHelper(ipc, method, params, true);
432
+ const callbacks = Object.create(null);
433
+ const set$1 = (id, fn) => {
434
+ callbacks[id] = fn;
388
435
  };
389
-
390
- const commands = Object.create(null);
391
- const register = commandMap => {
392
- Object.assign(commands, commandMap);
436
+ const get$1 = id => {
437
+ return callbacks[id];
393
438
  };
394
- const getCommand = key => {
395
- return commands[key];
439
+ const remove = id => {
440
+ delete callbacks[id];
396
441
  };
397
- const execute = (command, ...args) => {
398
- const fn = getCommand(command);
399
- if (!fn) {
400
- throw new Error(`command not found ${command}`);
401
- }
402
- return fn(...args);
442
+ let id = 0;
443
+ const create$3 = () => {
444
+ return ++id;
403
445
  };
404
-
405
- const getData$1 = event => {
406
- return event.data;
446
+ const registerPromise = () => {
447
+ const id = create$3();
448
+ const {
449
+ resolve,
450
+ promise
451
+ } = Promise.withResolvers();
452
+ set$1(id, resolve);
453
+ return {
454
+ id,
455
+ promise
456
+ };
407
457
  };
408
- const attachEvents = that => {
409
- const handleMessage = (...args) => {
410
- const data = that.getData(...args);
411
- that.dispatchEvent(new MessageEvent('message', {
412
- data
413
- }));
458
+ const create$2 = (method, params) => {
459
+ const {
460
+ id,
461
+ promise
462
+ } = registerPromise();
463
+ const message = {
464
+ jsonrpc: Two,
465
+ method,
466
+ params,
467
+ id
414
468
  };
415
- that.onMessage(handleMessage);
416
- const handleClose = event => {
417
- that.dispatchEvent(new Event('close'));
469
+ return {
470
+ message,
471
+ promise
418
472
  };
419
- that.onClose(handleClose);
420
473
  };
421
- class Ipc extends EventTarget {
422
- constructor(rawIpc) {
423
- super();
424
- this._rawIpc = rawIpc;
425
- attachEvents(this);
474
+ class JsonRpcError extends Error {
475
+ constructor(message) {
476
+ super(message);
477
+ this.name = 'JsonRpcError';
426
478
  }
427
479
  }
428
- const readyMessage = 'ready';
429
- const walkValue = (value, transferrables, isTransferrable) => {
430
- if (!value) {
431
- return;
480
+ const NewLine = '\n';
481
+ const DomException = 'DOMException';
482
+ const ReferenceError$1 = 'ReferenceError';
483
+ const SyntaxError$1 = 'SyntaxError';
484
+ const TypeError$1 = 'TypeError';
485
+ const getErrorConstructor = (message, type) => {
486
+ if (type) {
487
+ switch (type) {
488
+ case DomException:
489
+ return DOMException;
490
+ case TypeError$1:
491
+ return TypeError;
492
+ case SyntaxError$1:
493
+ return SyntaxError;
494
+ case ReferenceError$1:
495
+ return ReferenceError;
496
+ default:
497
+ return Error;
498
+ }
432
499
  }
433
- if (isTransferrable(value)) {
434
- transferrables.push(value);
435
- return;
500
+ if (message.startsWith('TypeError: ')) {
501
+ return TypeError;
436
502
  }
437
- if (Array.isArray(value)) {
438
- for (const item of value) {
439
- walkValue(item, transferrables, isTransferrable);
440
- }
441
- return;
503
+ if (message.startsWith('SyntaxError: ')) {
504
+ return SyntaxError;
442
505
  }
443
- if (typeof value === 'object') {
444
- for (const property of Object.values(value)) {
445
- walkValue(property, transferrables, isTransferrable);
446
- }
447
- return;
506
+ if (message.startsWith('ReferenceError: ')) {
507
+ return ReferenceError;
448
508
  }
509
+ return Error;
449
510
  };
450
- const isMessagePort = value => {
451
- return value && value instanceof MessagePort;
452
- };
453
- const isMessagePortMain = value => {
454
- return value && value.constructor && value.constructor.name === 'MessagePortMain';
455
- };
456
- const isOffscreenCanvas = value => {
457
- return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
458
- };
459
- const isInstanceOf = (value, constructorName) => {
460
- return value?.constructor?.name === constructorName;
461
- };
462
- const isSocket = value => {
463
- return isInstanceOf(value, 'Socket');
464
- };
465
- const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
466
- const isTransferrable = value => {
467
- for (const fn of transferrables) {
468
- if (fn(value)) {
469
- return true;
511
+ const constructError = (message, type, name) => {
512
+ const ErrorConstructor = getErrorConstructor(message, type);
513
+ if (ErrorConstructor === DOMException && name) {
514
+ return new ErrorConstructor(message, name);
515
+ }
516
+ if (ErrorConstructor === Error) {
517
+ const error = new Error(message);
518
+ if (name && name !== 'VError') {
519
+ error.name = name;
470
520
  }
521
+ return error;
471
522
  }
472
- return false;
523
+ return new ErrorConstructor(message);
473
524
  };
474
- const getTransferrables = value => {
475
- const transferrables = [];
476
- walkValue(value, transferrables, isTransferrable);
477
- return transferrables;
525
+ const getNewLineIndex = (string, startIndex = undefined) => {
526
+ return string.indexOf(NewLine, startIndex);
478
527
  };
479
- const listen$2 = () => {
480
- // @ts-ignore
481
- if (typeof WorkerGlobalScope === 'undefined') {
482
- throw new TypeError('module is not in web worker scope');
528
+ const getParentStack = error => {
529
+ let parentStack = error.stack || error.data || error.message || '';
530
+ if (parentStack.startsWith(' at')) {
531
+ parentStack = error.message + NewLine + parentStack;
483
532
  }
484
- return globalThis;
533
+ return parentStack;
485
534
  };
486
- const signal$2 = global => {
487
- global.postMessage(readyMessage);
535
+ const joinLines = lines => {
536
+ return lines.join(NewLine);
488
537
  };
489
- class IpcChildWithModuleWorker extends Ipc {
490
- getData(event) {
491
- return getData$1(event);
492
- }
493
- send(message) {
494
- // @ts-ignore
495
- this._rawIpc.postMessage(message);
496
- }
497
- sendAndTransfer(message) {
498
- const transfer = getTransferrables(message);
499
- // @ts-ignore
500
- this._rawIpc.postMessage(message, transfer);
538
+ const MethodNotFound = -32601;
539
+ const Custom = -32001;
540
+ const splitLines = lines => {
541
+ return lines.split(NewLine);
542
+ };
543
+ const restoreJsonRpcError = error => {
544
+ if (error && error instanceof Error) {
545
+ return error;
501
546
  }
502
- dispose() {
503
- // ignore
547
+ const currentStack = joinLines(splitLines(new Error().stack || '').slice(1));
548
+ if (error && error.code && error.code === MethodNotFound) {
549
+ const restoredError = new JsonRpcError(error.message);
550
+ const parentStack = getParentStack(error);
551
+ restoredError.stack = parentStack + NewLine + currentStack;
552
+ return restoredError;
504
553
  }
505
- onClose(callback) {
506
- // ignore
554
+ if (error && error.message) {
555
+ const restoredError = constructError(error.message, error.type, error.name);
556
+ if (error.data) {
557
+ if (error.data.stack && error.data.type && error.message) {
558
+ restoredError.stack = error.data.type + ': ' + error.message + NewLine + error.data.stack + NewLine + currentStack;
559
+ } else if (error.data.stack) {
560
+ restoredError.stack = error.data.stack;
561
+ }
562
+ if (error.data.codeFrame) {
563
+ // @ts-ignore
564
+ restoredError.codeFrame = error.data.codeFrame;
565
+ }
566
+ if (error.data.code) {
567
+ // @ts-ignore
568
+ restoredError.code = error.data.code;
569
+ }
570
+ if (error.data.type) {
571
+ // @ts-ignore
572
+ restoredError.name = error.data.type;
573
+ }
574
+ } else {
575
+ if (error.stack) {
576
+ const lowerStack = restoredError.stack || '';
577
+ // @ts-ignore
578
+ const indexNewLine = getNewLineIndex(lowerStack);
579
+ const parentStack = getParentStack(error);
580
+ // @ts-ignore
581
+ restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
582
+ }
583
+ if (error.codeFrame) {
584
+ // @ts-ignore
585
+ restoredError.codeFrame = error.codeFrame;
586
+ }
587
+ }
588
+ return restoredError;
507
589
  }
508
- onMessage(callback) {
509
- this._rawIpc.addEventListener('message', callback);
590
+ if (typeof error === 'string') {
591
+ return new Error(`JsonRpc Error: ${error}`);
510
592
  }
511
- }
512
- const wrap$5 = global => {
513
- return new IpcChildWithModuleWorker(global);
514
- };
515
- const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
516
- const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
517
- const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
518
- const NewLine$1 = '\n';
519
- const joinLines = lines => {
520
- return lines.join(NewLine$1);
521
- };
522
- const splitLines = lines => {
523
- return lines.split(NewLine$1);
524
- };
525
- const isModuleNotFoundMessage = line => {
526
- return line.includes('[ERR_MODULE_NOT_FOUND]');
527
- };
528
- const getModuleNotFoundError = stderr => {
529
- const lines = splitLines(stderr);
530
- const messageIndex = lines.findIndex(isModuleNotFoundMessage);
531
- const message = lines[messageIndex];
532
- return {
533
- message,
534
- code: ERR_MODULE_NOT_FOUND
535
- };
536
- };
537
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
538
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
539
- const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
540
- const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
541
- const RE_AT = /^\s+at/;
542
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
543
- const isUnhelpfulNativeModuleError = stderr => {
544
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
545
- };
546
- const isMessageCodeBlockStartIndex = line => {
547
- return RE_MESSAGE_CODE_BLOCK_START.test(line);
548
- };
549
- const isMessageCodeBlockEndIndex = line => {
550
- return RE_MESSAGE_CODE_BLOCK_END.test(line);
551
- };
552
- const getMessageCodeBlock = stderr => {
553
- const lines = splitLines(stderr);
554
- const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
555
- const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
556
- const relevantLines = lines.slice(startIndex, endIndex);
557
- const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
558
- return relevantMessage;
559
- };
560
- const getNativeModuleErrorMessage = stderr => {
561
- const message = getMessageCodeBlock(stderr);
562
- return {
563
- message: `Incompatible native node module: ${message}`,
564
- code: E_INCOMPATIBLE_NATIVE_MODULE
565
- };
593
+ return new Error(`JsonRpc Error: ${error}`);
566
594
  };
567
- const isModulesSyntaxError = stderr => {
568
- if (!stderr) {
569
- return false;
595
+ const unwrapJsonRpcResult = responseMessage => {
596
+ if ('error' in responseMessage) {
597
+ const restoredError = restoreJsonRpcError(responseMessage.error);
598
+ throw restoredError;
570
599
  }
571
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
600
+ if ('result' in responseMessage) {
601
+ return responseMessage.result;
602
+ }
603
+ throw new JsonRpcError('unexpected response message');
572
604
  };
573
- const getModuleSyntaxError = () => {
574
- return {
575
- message: `ES Modules are not supported in electron`,
576
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
577
- };
605
+ const warn = (...args) => {
606
+ console.warn(...args);
578
607
  };
579
- const isModuleNotFoundError = stderr => {
580
- if (!stderr) {
581
- return false;
608
+ const resolve = (id, response) => {
609
+ const fn = get$1(id);
610
+ if (!fn) {
611
+ console.log(response);
612
+ warn(`callback ${id} may already be disposed`);
613
+ return;
582
614
  }
583
- return stderr.includes('ERR_MODULE_NOT_FOUND');
615
+ fn(response);
616
+ remove(id);
584
617
  };
585
- const isNormalStackLine = line => {
586
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
618
+ const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
619
+ const getErrorType = prettyError => {
620
+ if (prettyError && prettyError.type) {
621
+ return prettyError.type;
622
+ }
623
+ if (prettyError && prettyError.constructor && prettyError.constructor.name) {
624
+ return prettyError.constructor.name;
625
+ }
626
+ return undefined;
587
627
  };
588
- const getDetails = lines => {
589
- const index = lines.findIndex(isNormalStackLine);
590
- if (index === -1) {
628
+ const getErrorProperty = (error, prettyError) => {
629
+ if (error && error.code === E_COMMAND_NOT_FOUND) {
591
630
  return {
592
- actualMessage: joinLines(lines),
593
- rest: []
631
+ code: MethodNotFound,
632
+ message: error.message,
633
+ data: error.stack
594
634
  };
595
635
  }
596
- let lastIndex = index - 1;
597
- while (++lastIndex < lines.length) {
598
- if (!isNormalStackLine(lines[lastIndex])) {
599
- break;
636
+ return {
637
+ code: Custom,
638
+ message: prettyError.message,
639
+ data: {
640
+ stack: prettyError.stack,
641
+ codeFrame: prettyError.codeFrame,
642
+ type: getErrorType(prettyError),
643
+ code: prettyError.code,
644
+ name: prettyError.name
600
645
  }
601
- }
646
+ };
647
+ };
648
+ const create$1 = (message, error) => {
602
649
  return {
603
- actualMessage: lines[index - 1],
604
- rest: lines.slice(index, lastIndex)
650
+ jsonrpc: Two,
651
+ id: message.id,
652
+ error
605
653
  };
606
654
  };
607
- const getHelpfulChildProcessError = (stdout, stderr) => {
608
- if (isUnhelpfulNativeModuleError(stderr)) {
609
- return getNativeModuleErrorMessage(stderr);
610
- }
611
- if (isModulesSyntaxError(stderr)) {
612
- return getModuleSyntaxError();
613
- }
614
- if (isModuleNotFoundError(stderr)) {
615
- return getModuleNotFoundError(stderr);
616
- }
617
- const lines = splitLines(stderr);
618
- const {
619
- actualMessage,
620
- rest
621
- } = getDetails(lines);
655
+ const getErrorResponse = (message, error, preparePrettyError, logError) => {
656
+ const prettyError = preparePrettyError(error);
657
+ logError(error, prettyError);
658
+ const errorProperty = getErrorProperty(error, prettyError);
659
+ return create$1(message, errorProperty);
660
+ };
661
+ const create$5 = (message, result) => {
622
662
  return {
623
- message: `${actualMessage}`,
624
- code: '',
625
- stack: rest
663
+ jsonrpc: Two,
664
+ id: message.id,
665
+ result: result ?? null
626
666
  };
627
667
  };
628
- const normalizeLine = line => {
629
- if (line.startsWith('Error: ')) {
630
- return line.slice('Error: '.length);
631
- }
632
- if (line.startsWith('VError: ')) {
633
- return line.slice('VError: '.length);
634
- }
635
- return line;
668
+ const getSuccessResponse = (message, result) => {
669
+ const resultProperty = result ?? null;
670
+ return create$5(message, resultProperty);
636
671
  };
637
- const getCombinedMessage = (error, message) => {
638
- const stringifiedError = normalizeLine(`${error}`);
639
- if (message) {
640
- return `${message}: ${stringifiedError}`;
672
+ const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
673
+ try {
674
+ const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
675
+ return getSuccessResponse(message, result);
676
+ } catch (error) {
677
+ return getErrorResponse(message, error, preparePrettyError, logError);
641
678
  }
642
- return stringifiedError;
643
679
  };
644
- const NewLine = '\n';
645
- const getNewLineIndex = (string, startIndex = undefined) => {
646
- return string.indexOf(NewLine, startIndex);
680
+ const defaultPreparePrettyError = error => {
681
+ return error;
647
682
  };
648
- const mergeStacks = (parent, child) => {
649
- if (!child) {
650
- return parent;
651
- }
652
- const parentNewLineIndex = getNewLineIndex(parent);
653
- const childNewLineIndex = getNewLineIndex(child);
654
- if (childNewLineIndex === -1) {
655
- return parent;
656
- }
657
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
658
- const childRest = child.slice(childNewLineIndex);
659
- const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
660
- if (parentFirstLine.includes(childFirstLine)) {
661
- return parentFirstLine + childRest;
662
- }
663
- return child;
683
+ const defaultLogError = () => {
684
+ // ignore
664
685
  };
665
- class VError extends Error {
666
- constructor(error, message) {
667
- const combinedMessage = getCombinedMessage(error, message);
668
- super(combinedMessage);
669
- this.name = 'VError';
670
- if (error instanceof Error) {
671
- this.stack = mergeStacks(this.stack, error.stack);
672
- }
673
- if (error.codeFrame) {
674
- // @ts-ignore
675
- this.codeFrame = error.codeFrame;
676
- }
677
- if (error.code) {
678
- // @ts-ignore
679
- this.code = error.code;
680
- }
681
- }
682
- }
683
- class IpcError extends VError {
684
- // @ts-ignore
685
- constructor(betterMessage, stdout = '', stderr = '') {
686
- if (stdout || stderr) {
687
- // @ts-ignore
688
- const {
689
- message,
690
- code,
691
- stack
692
- } = getHelpfulChildProcessError(stdout, stderr);
693
- const cause = new Error(message);
694
- // @ts-ignore
695
- cause.code = code;
696
- cause.stack = stack;
697
- super(cause, betterMessage);
698
- } else {
699
- super(betterMessage);
700
- }
701
- // @ts-ignore
702
- this.name = 'IpcError';
703
- // @ts-ignore
704
- this.stdout = stdout;
705
- // @ts-ignore
706
- this.stderr = stderr;
686
+ const defaultRequiresSocket = () => {
687
+ return false;
688
+ };
689
+ const defaultResolve = resolve;
690
+
691
+ // TODO maybe remove this in v6 or v7, only accept options object to simplify the code
692
+ const normalizeParams = args => {
693
+ if (args.length === 1) {
694
+ const options = args[0];
695
+ return {
696
+ ipc: options.ipc,
697
+ message: options.message,
698
+ execute: options.execute,
699
+ resolve: options.resolve || defaultResolve,
700
+ preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
701
+ logError: options.logError || defaultLogError,
702
+ requiresSocket: options.requiresSocket || defaultRequiresSocket
703
+ };
707
704
  }
708
- }
709
- const withResolvers = () => {
710
- let _resolve;
711
- const promise = new Promise(resolve => {
712
- _resolve = resolve;
713
- });
714
705
  return {
715
- resolve: _resolve,
716
- promise
706
+ ipc: args[0],
707
+ message: args[1],
708
+ execute: args[2],
709
+ resolve: args[3],
710
+ preparePrettyError: args[4],
711
+ logError: args[5],
712
+ requiresSocket: args[6]
717
713
  };
718
714
  };
719
- const waitForFirstMessage = async port => {
715
+ const handleJsonRpcMessage = async (...args) => {
716
+ const options = normalizeParams(args);
720
717
  const {
718
+ message,
719
+ ipc,
720
+ execute,
721
721
  resolve,
722
- promise
723
- } = withResolvers();
724
- port.addEventListener('message', resolve, {
725
- once: true
726
- });
727
- const event = await promise;
728
- // @ts-ignore
729
- return event.data;
730
- };
731
- const listen$1$1 = async () => {
732
- const parentIpcRaw = listen$2();
733
- signal$2(parentIpcRaw);
734
- const parentIpc = wrap$5(parentIpcRaw);
735
- const firstMessage = await waitForFirstMessage(parentIpc);
736
- if (firstMessage.method !== 'initialize') {
737
- throw new IpcError('unexpected first message');
738
- }
739
- const type = firstMessage.params[0];
740
- if (type === 'message-port') {
741
- parentIpc.send({
742
- jsonrpc: '2.0',
743
- id: firstMessage.id,
744
- result: null
745
- });
746
- parentIpc.dispose();
747
- const port = firstMessage.params[1];
748
- return port;
749
- }
750
- return globalThis;
751
- };
752
- class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
753
- constructor(port) {
754
- super(port);
755
- }
756
- getData(event) {
757
- return getData$1(event);
758
- }
759
- send(message) {
760
- this._rawIpc.postMessage(message);
761
- }
762
- sendAndTransfer(message) {
763
- const transfer = getTransferrables(message);
764
- this._rawIpc.postMessage(message, transfer);
765
- }
766
- dispose() {
767
- if (this._rawIpc.close) {
768
- this._rawIpc.close();
722
+ preparePrettyError,
723
+ logError,
724
+ requiresSocket
725
+ } = options;
726
+ if ('id' in message) {
727
+ if ('method' in message) {
728
+ const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
729
+ try {
730
+ ipc.send(response);
731
+ } catch (error) {
732
+ const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
733
+ ipc.send(errorResponse);
734
+ }
735
+ return;
769
736
  }
737
+ resolve(message.id, message);
738
+ return;
770
739
  }
771
- onClose(callback) {
772
- // ignore
740
+ if ('method' in message) {
741
+ await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
742
+ return;
773
743
  }
774
- onMessage(callback) {
775
- this._rawIpc.addEventListener('message', callback);
776
- this._rawIpc.start();
744
+ throw new JsonRpcError('unexpected message');
745
+ };
746
+ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
747
+ const {
748
+ message,
749
+ promise
750
+ } = create$2(method, params);
751
+ if (useSendAndTransfer && ipc.sendAndTransfer) {
752
+ ipc.sendAndTransfer(message);
753
+ } else {
754
+ ipc.send(message);
777
755
  }
778
- }
779
- const wrap$4 = port => {
780
- return new IpcChildWithModuleWorkerAndMessagePort(port);
756
+ const responseMessage = await promise;
757
+ return unwrapJsonRpcResult(responseMessage);
781
758
  };
782
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
783
- __proto__: null,
784
- listen: listen$1$1,
785
- wrap: wrap$4
759
+ const send = (transport, method, ...params) => {
760
+ const message = create$4(method, params);
761
+ transport.send(message);
762
+ };
763
+ const invoke$1 = (ipc, method, ...params) => {
764
+ return invokeHelper(ipc, method, params, false);
765
+ };
766
+ const invokeAndTransfer = (ipc, method, ...params) => {
767
+ return invokeHelper(ipc, method, params, true);
768
+ };
769
+
770
+ const commands = Object.create(null);
771
+ const register = commandMap => {
772
+ Object.assign(commands, commandMap);
773
+ };
774
+ const getCommand = key => {
775
+ return commands[key];
776
+ };
777
+ const execute = (command, ...args) => {
778
+ const fn = getCommand(command);
779
+ if (!fn) {
780
+ throw new Error(`command not found ${command}`);
781
+ }
782
+ return fn(...args);
786
783
  };
787
784
 
788
785
  const createRpc = ipc => {
789
786
  const rpc = {
787
+ // @ts-ignore
788
+ ipc,
790
789
  /**
791
790
  * @deprecated
792
791
  */
@@ -812,7 +811,9 @@ const logError = () => {
812
811
  // handled by renderer worker
813
812
  };
814
813
  const handleMessage = event => {
815
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
814
+ const actualRequiresSocket = event?.target?.requiresSocket || requiresSocket;
815
+ const actualExecute = event?.target?.execute || execute;
816
+ return handleJsonRpcMessage(event.target, event.data, actualExecute, resolve, preparePrettyError, logError, actualRequiresSocket);
816
817
  };
817
818
  const handleIpc = ipc => {
818
819
  if ('addEventListener' in ipc) {
@@ -845,8 +846,6 @@ const WebWorkerRpcClient = {
845
846
  create
846
847
  };
847
848
 
848
- const Document = 'document';
849
-
850
849
  const ExtensionDetail = 'ExtensionDetail';
851
850
  const ExtensionDetailDescription = 'ExtensionDetailDescription';
852
851
  const ExtensionDetailHeader = 'ExtensionDetailHeader';
@@ -856,182 +855,145 @@ const ExtensionDetailName = 'ExtensionDetailName';
856
855
  const Markdown = 'Markdown';
857
856
  const Viewlet = 'Viewlet';
858
857
 
859
- const HandleReadmeContextMenu = 'handleReadmeContextMenu';
860
-
861
- const Div$1 = 4;
862
- const H1$1 = 5;
863
- const Span$1 = 8;
864
- const Text$1 = 12;
865
- const Img$1 = 17;
866
- const H2$1 = 22;
867
- const H3$1 = 23;
868
- const H4$1 = 24;
869
- const H5$1 = 25;
870
- const Article$1 = 27;
871
- const Aside$1 = 28;
872
- const Footer$1 = 29;
873
- const Header$1 = 30;
874
- const Nav$1 = 40;
875
- const Section$1 = 41;
876
- const Search$1 = 42;
877
- const Dd$1 = 43;
878
- const Dl$1 = 44;
879
- const Figcaption$1 = 45;
880
- const Figure$1 = 46;
881
- const Hr$1 = 47;
882
- const Li$1 = 48;
883
- const Ol$1 = 49;
884
- const P$1 = 50;
885
- const Pre$1 = 51;
886
- const A$1 = 53;
887
- const Abbr$1 = 54;
888
- const Br$1 = 55;
889
- const Cite$1 = 56;
890
- const Data$1 = 57;
891
- const Time$1 = 58;
892
- const Tfoot$1 = 59;
893
-
894
- const text = data => {
895
- return {
896
- type: Text$1,
897
- text: data,
898
- childCount: 0
899
- };
900
- };
858
+ const Document = 'document';
859
+ const TabList = 'tablist';
860
+ const Tab = 'tab';
901
861
 
902
- const getExtensionDetailHeaderVirtualDom = extensionDetail => {
903
- const {
904
- name,
905
- iconSrc,
906
- description
907
- } = extensionDetail;
908
- const dom = [{
909
- type: Div$1,
910
- className: ExtensionDetailHeader,
911
- childCount: 2
912
- }, {
913
- type: Img$1,
914
- className: ExtensionDetailIcon,
915
- alt: '',
916
- draggable: false,
917
- childCount: 0,
918
- src: iconSrc
919
- }, {
920
- type: Div$1,
921
- className: ExtensionDetailHeaderDetails,
922
- childCount: 2
923
- }, {
924
- type: Div$1,
925
- className: ExtensionDetailName,
926
- childCount: 1
927
- }, text(name), {
928
- type: Div$1,
929
- className: ExtensionDetailDescription,
930
- childCount: 1
931
- }, text(description)];
932
- return dom;
933
- };
862
+ const HandleReadmeContextMenu = 'handleReadmeContextMenu';
934
863
 
935
864
  const allowedMarkdownAttributes = ['src', 'id', 'className', 'title', 'alt', 'href', 'target', 'rel'];
936
865
 
937
- const Div = 'div';
938
- const H1 = 'h1';
939
- const H2 = 'h2';
940
- const H3 = 'h3';
941
- const H4 = 'h4';
942
- const H5 = 'h5';
943
- const Img = 'img';
944
- const Span = 'span';
945
- const Article = 'article';
946
- const Aside = 'aside';
947
- const Footer = 'footer';
948
- const Header = 'header';
949
- const Nav = 'nav';
950
- const Section = 'section';
951
- const Search = 'search';
952
- const Dd = 'dd';
953
- const Dl = 'dl';
954
- const Figcaption = 'figcaption';
955
- const Figure = 'figure';
956
- const Hr = 'hr';
957
- const Li = 'li';
958
- const Ol = 'ol';
959
- const P = 'p';
960
- const Pre = 'pre';
961
- const A = 'a';
962
- const Abbr = 'abbr';
963
- const Br = 'br';
964
- const Cite = 'cite';
965
- const Data = 'data';
966
- const Time = 'time';
967
- const Tfoot = 'tfoot';
866
+ const Div$1 = 'div';
867
+ const H1$1 = 'h1';
868
+ const H2$1 = 'h2';
869
+ const H3$1 = 'h3';
870
+ const H4$1 = 'h4';
871
+ const H5$1 = 'h5';
872
+ const Img$1 = 'img';
873
+ const Span$1 = 'span';
874
+ const Article$1 = 'article';
875
+ const Aside$1 = 'aside';
876
+ const Footer$1 = 'footer';
877
+ const Header$1 = 'header';
878
+ const Nav$1 = 'nav';
879
+ const Section$1 = 'section';
880
+ const Search$1 = 'search';
881
+ const Dd$1 = 'dd';
882
+ const Dl$1 = 'dl';
883
+ const Figcaption$1 = 'figcaption';
884
+ const Figure$1 = 'figure';
885
+ const Hr$1 = 'hr';
886
+ const Li$1 = 'li';
887
+ const Ol$1 = 'ol';
888
+ const P$1 = 'p';
889
+ const Pre$1 = 'pre';
890
+ const A$1 = 'a';
891
+ const Abbr$1 = 'abbr';
892
+ const Br$1 = 'br';
893
+ const Cite$1 = 'cite';
894
+ const Data$1 = 'data';
895
+ const Time$1 = 'time';
896
+ const Tfoot$1 = 'tfoot';
897
+
898
+ const Div = 4;
899
+ const H1 = 5;
900
+ const Span = 8;
901
+ const Text$1 = 12;
902
+ const Img = 17;
903
+ const H2 = 22;
904
+ const H3 = 23;
905
+ const H4 = 24;
906
+ const H5 = 25;
907
+ const Article = 27;
908
+ const Aside = 28;
909
+ const Footer = 29;
910
+ const Header = 30;
911
+ const Nav = 40;
912
+ const Section = 41;
913
+ const Search = 42;
914
+ const Dd = 43;
915
+ const Dl = 44;
916
+ const Figcaption = 45;
917
+ const Figure = 46;
918
+ const Hr = 47;
919
+ const Li = 48;
920
+ const Ol = 49;
921
+ const P = 50;
922
+ const Pre = 51;
923
+ const A = 53;
924
+ const Abbr = 54;
925
+ const Br = 55;
926
+ const Cite = 56;
927
+ const Data = 57;
928
+ const Time = 58;
929
+ const Tfoot = 59;
968
930
 
969
931
  const getVirtualDomTag = text => {
970
932
  switch (text) {
971
- case H1:
972
- return H1$1;
973
- case H2:
974
- return H2$1;
975
- case H3:
976
- return H3$1;
977
- case H4:
978
- return H4$1;
979
- case H5:
980
- return H5$1;
981
- case Div:
982
- return Div$1;
983
- case Article:
984
- return Article$1;
985
- case Aside:
986
- return Aside$1;
987
- case Footer:
988
- return Footer$1;
989
- case Header:
990
- return Header$1;
991
- case Nav:
992
- return Nav$1;
993
- case Section:
994
- return Section$1;
995
- case Search:
996
- return Search$1;
997
- case Dd:
998
- return Dd$1;
999
- case Dl:
1000
- return Dl$1;
1001
- case Figcaption:
1002
- return Figcaption$1;
1003
- case Figure:
1004
- return Figure$1;
1005
- case Hr:
1006
- return Hr$1;
1007
- case Li:
1008
- return Li$1;
1009
- case Ol:
1010
- return Ol$1;
1011
- case P:
1012
- return P$1;
1013
- case Pre:
1014
- return Pre$1;
1015
- case A:
1016
- return A$1;
1017
- case Abbr:
1018
- return Abbr$1;
1019
- case Br:
1020
- return Br$1;
1021
- case Cite:
1022
- return Cite$1;
1023
- case Data:
1024
- return Data$1;
1025
- case Time:
1026
- return Time$1;
1027
- case Tfoot:
1028
- return Tfoot$1;
1029
- case Img:
1030
- return Img$1;
1031
- case Span:
1032
- return Span$1;
933
+ case H1$1:
934
+ return H1;
935
+ case H2$1:
936
+ return H2;
937
+ case H3$1:
938
+ return H3;
939
+ case H4$1:
940
+ return H4;
941
+ case H5$1:
942
+ return H5;
943
+ case Div$1:
944
+ return Div;
945
+ case Article$1:
946
+ return Article;
947
+ case Aside$1:
948
+ return Aside;
949
+ case Footer$1:
950
+ return Footer;
951
+ case Header$1:
952
+ return Header;
953
+ case Nav$1:
954
+ return Nav;
955
+ case Section$1:
956
+ return Section;
957
+ case Search$1:
958
+ return Search;
959
+ case Dd$1:
960
+ return Dd;
961
+ case Dl$1:
962
+ return Dl;
963
+ case Figcaption$1:
964
+ return Figcaption;
965
+ case Figure$1:
966
+ return Figure;
967
+ case Hr$1:
968
+ return Hr;
969
+ case Li$1:
970
+ return Li;
971
+ case Ol$1:
972
+ return Ol;
973
+ case P$1:
974
+ return P;
975
+ case Pre$1:
976
+ return Pre;
977
+ case A$1:
978
+ return A;
979
+ case Abbr$1:
980
+ return Abbr;
981
+ case Br$1:
982
+ return Br;
983
+ case Cite$1:
984
+ return Cite;
985
+ case Data$1:
986
+ return Data;
987
+ case Time$1:
988
+ return Time;
989
+ case Tfoot$1:
990
+ return Tfoot;
991
+ case Img$1:
992
+ return Img;
993
+ case Span$1:
994
+ return Span;
1033
995
  default:
1034
- return Div$1;
996
+ return Div;
1035
997
  }
1036
998
  };
1037
999
 
@@ -1060,7 +1022,7 @@ const CommentStart = 21;
1060
1022
 
1061
1023
  const isSelfClosingTag = tag => {
1062
1024
  switch (tag) {
1063
- case Img:
1025
+ case Img$1:
1064
1026
  return true;
1065
1027
  default:
1066
1028
  return false;
@@ -1325,6 +1287,14 @@ const tokenizeHtml = text => {
1325
1287
  return tokens;
1326
1288
  };
1327
1289
 
1290
+ const text = data => {
1291
+ return {
1292
+ type: Text$1,
1293
+ text: data,
1294
+ childCount: 0
1295
+ };
1296
+ };
1297
+
1328
1298
  const parseHtml = (html, allowedAttributes) => {
1329
1299
  string(html);
1330
1300
  array(allowedAttributes);
@@ -1394,6 +1364,75 @@ const getVirtualDomChildCount = markdownDom => {
1394
1364
  return stack.length;
1395
1365
  };
1396
1366
 
1367
+ const getExtensionDetailContentVirtualDom = sanitizedReadmeHtml => {
1368
+ const markdownDom = getMarkdownVirtualDom(sanitizedReadmeHtml);
1369
+ const childCount = getVirtualDomChildCount(markdownDom);
1370
+ const dom = [{
1371
+ type: Div,
1372
+ className: Markdown,
1373
+ role: Document,
1374
+ onContextMenu: HandleReadmeContextMenu,
1375
+ childCount
1376
+ }, ...markdownDom];
1377
+ return dom;
1378
+ };
1379
+
1380
+ const getExtensionDetailHeaderVirtualDom = extensionDetail => {
1381
+ const {
1382
+ name,
1383
+ iconSrc,
1384
+ description
1385
+ } = extensionDetail;
1386
+ const dom = [{
1387
+ type: Div,
1388
+ className: ExtensionDetailHeader,
1389
+ childCount: 2
1390
+ }, {
1391
+ type: Img,
1392
+ className: ExtensionDetailIcon,
1393
+ alt: '',
1394
+ draggable: false,
1395
+ childCount: 0,
1396
+ src: iconSrc
1397
+ }, {
1398
+ type: Div,
1399
+ className: ExtensionDetailHeaderDetails,
1400
+ childCount: 2
1401
+ }, {
1402
+ type: Div,
1403
+ className: ExtensionDetailName,
1404
+ childCount: 1
1405
+ }, text(name), {
1406
+ type: Div,
1407
+ className: ExtensionDetailDescription,
1408
+ childCount: 1
1409
+ }, text(description)];
1410
+ return dom;
1411
+ };
1412
+
1413
+ const getTabVirtualDom = tab => {
1414
+ const {
1415
+ label,
1416
+ selected
1417
+ } = tab;
1418
+ const className = selected ? 'ExtensionDetailTab ExtensionDetailTabSelected' : 'ExtensionDetailTab';
1419
+ return [{
1420
+ type: Div,
1421
+ role: Tab,
1422
+ className,
1423
+ childCount: 1
1424
+ }, text(label)];
1425
+ };
1426
+
1427
+ const getTabsVirtualDom = tabs => {
1428
+ return [{
1429
+ type: Div,
1430
+ className: 'ExtensionDetailTabs',
1431
+ childCount: tabs.length,
1432
+ role: TabList
1433
+ }, ...tabs.flatMap(getTabVirtualDom)];
1434
+ };
1435
+
1397
1436
  const joinBySpace = (...items) => {
1398
1437
  return items.join(' ');
1399
1438
  };
@@ -1403,19 +1442,21 @@ const mergeClassNames = (...classNames) => {
1403
1442
  };
1404
1443
 
1405
1444
  const getExtensionDetailVirtualDom = (extensionDetail, sanitizedReadmeHtml) => {
1406
- const markdownDom = getMarkdownVirtualDom(sanitizedReadmeHtml);
1407
- const childCount = getVirtualDomChildCount(markdownDom);
1445
+ const tabs = [{
1446
+ label: 'Details',
1447
+ selected: true
1448
+ }, {
1449
+ label: 'Features',
1450
+ selected: false
1451
+ }, {
1452
+ label: 'Changelog',
1453
+ selected: false
1454
+ }];
1408
1455
  const dom = [{
1409
- type: Div$1,
1456
+ type: Div,
1410
1457
  className: mergeClassNames(Viewlet, ExtensionDetail),
1411
- childCount: childCount + 1
1412
- }, ...getExtensionDetailHeaderVirtualDom(extensionDetail), {
1413
- type: Div$1,
1414
- className: Markdown,
1415
- role: Document,
1416
- onContextMenu: HandleReadmeContextMenu,
1417
- childCount
1418
- }, ...markdownDom];
1458
+ childCount: 3
1459
+ }, ...getExtensionDetailHeaderVirtualDom(extensionDetail), ...getTabsVirtualDom(tabs), ...getExtensionDetailContentVirtualDom(sanitizedReadmeHtml)];
1419
1460
  return dom;
1420
1461
  };
1421
1462
 
@@ -1431,23 +1472,22 @@ const i18nString = (key, placeholders = emptyObject) => {
1431
1472
  return key.replaceAll(RE_PLACEHOLDER, replacer);
1432
1473
  };
1433
1474
 
1434
- const UiStrings = {
1435
- Copy: 'Copy',
1436
- OpenInNewTab: 'Open in New Tab',
1437
- OpenImageInNewTab: 'Open Image in New Tab',
1438
- SaveImageAs: 'Save Image as'
1439
- };
1475
+ const Copy = 'Copy';
1476
+ const OpenInNewTab = 'Open in New Tab';
1477
+ const OpenImageInNewTab = 'Open Image in New Tab';
1478
+ const SaveImageAs = 'Save Image as';
1479
+
1440
1480
  const copy = () => {
1441
- return i18nString(UiStrings.Copy);
1481
+ return i18nString(Copy);
1442
1482
  };
1443
1483
  const openInNewTab = () => {
1444
- return i18nString(UiStrings.OpenInNewTab);
1484
+ return i18nString(OpenInNewTab);
1445
1485
  };
1446
1486
  const openImageInNewTab = () => {
1447
- return i18nString(UiStrings.OpenImageInNewTab);
1487
+ return i18nString(OpenImageInNewTab);
1448
1488
  };
1449
1489
  const saveImageAs = () => {
1450
- return i18nString(UiStrings.SaveImageAs);
1490
+ return i18nString(SaveImageAs);
1451
1491
  };
1452
1492
 
1453
1493
  const None = 0;
@@ -1562,17 +1602,20 @@ const getDescription = extension => {
1562
1602
  return extension.description;
1563
1603
  };
1564
1604
 
1565
- const state = {
1566
- rpc: undefined
1605
+ const RendererWorker = 1;
1606
+
1607
+ const rpcs = Object.create(null);
1608
+ const set = (id, rpc) => {
1609
+ rpcs[id] = rpc;
1610
+ };
1611
+ const get = id => {
1612
+ return rpcs[id];
1567
1613
  };
1614
+
1568
1615
  const invoke = (method, ...params) => {
1569
- const rpc = state.rpc;
1570
- // @ts-ignore
1616
+ const rpc = get(RendererWorker);
1571
1617
  return rpc.invoke(method, ...params);
1572
1618
  };
1573
- const setRpc = rpc => {
1574
- state.rpc = rpc;
1575
- };
1576
1619
 
1577
1620
  const getAllExtensions = async platform => {
1578
1621
  if (platform === Web) {
@@ -1648,8 +1691,8 @@ const loadReadmeContent = async path => {
1648
1691
  };
1649
1692
 
1650
1693
  /**
1651
- * marked v15.0.3 - a markdown parser
1652
- * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)
1694
+ * marked v15.0.6 - a markdown parser
1695
+ * Copyright (c) 2011-2025, Christopher Jeffrey. (MIT Licensed)
1653
1696
  * https://github.com/markedjs/marked
1654
1697
  */
1655
1698
 
@@ -1855,18 +1898,25 @@ const _punctuation = /[\p{P}\p{S}]/u;
1855
1898
  const _punctuationOrSpace = /[\s\p{P}\p{S}]/u;
1856
1899
  const _notPunctuationOrSpace = /[^\s\p{P}\p{S}]/u;
1857
1900
  const punctuation = edit(/^((?![*_])punctSpace)/, 'u').replace(/punctSpace/g, _punctuationOrSpace).getRegex();
1901
+ // GFM allows ~ inside strong and em for strikethrough
1902
+ const _punctuationGfmStrongEm = /(?!~)[\p{P}\p{S}]/u;
1903
+ const _punctuationOrSpaceGfmStrongEm = /(?!~)[\s\p{P}\p{S}]/u;
1904
+ const _notPunctuationOrSpaceGfmStrongEm = /(?:[^\s\p{P}\p{S}]|~)/u;
1858
1905
  // sequences em should skip over [title](link), `code`, <html>
1859
1906
  const blockSkip = /\[[^[\]]*?\]\((?:\\.|[^\\\(\)]|\((?:\\.|[^\\\(\)])*\))*\)|`[^`]*?`|<[^<>]*?>/g;
1860
- const emStrongLDelim = edit(/^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/, 'u').replace(/punct/g, _punctuation).getRegex();
1861
- const emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
1907
+ const emStrongLDelimCore = /^(?:\*+(?:((?!\*)punct)|[^\s*]))|^_+(?:((?!_)punct)|([^\s_]))/;
1908
+ const emStrongLDelim = edit(emStrongLDelimCore, 'u').replace(/punct/g, _punctuation).getRegex();
1909
+ const emStrongLDelimGfm = edit(emStrongLDelimCore, 'u').replace(/punct/g, _punctuationGfmStrongEm).getRegex();
1910
+ const emStrongRDelimAstCore = '^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)' // Skip orphan inside strong
1862
1911
  + '|[^*]+(?=[^*])' // Consume to delim
1863
1912
  + '|(?!\\*)punct(\\*+)(?=[\\s]|$)' // (1) #*** can only be a Right Delimiter
1864
1913
  + '|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)' // (2) a***#, a*** can only be a Right Delimiter
1865
1914
  + '|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)' // (3) #***a, ***a can only be Left Delimiter
1866
1915
  + '|[\\s](\\*+)(?!\\*)(?=punct)' // (4) ***# can only be Left Delimiter
1867
1916
  + '|(?!\\*)punct(\\*+)(?!\\*)(?=punct)' // (5) #***# can be either Left or Right Delimiter
1868
- + '|notPunctSpace(\\*+)(?=notPunctSpace)', 'gu') // (6) a***a can be either Left or Right Delimiter
1869
- .replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
1917
+ + '|notPunctSpace(\\*+)(?=notPunctSpace)'; // (6) a***a can be either Left or Right Delimiter
1918
+ const emStrongRDelimAst = edit(emStrongRDelimAstCore, 'gu').replace(/notPunctSpace/g, _notPunctuationOrSpace).replace(/punctSpace/g, _punctuationOrSpace).replace(/punct/g, _punctuation).getRegex();
1919
+ const emStrongRDelimAstGfm = edit(emStrongRDelimAstCore, 'gu').replace(/notPunctSpace/g, _notPunctuationOrSpaceGfmStrongEm).replace(/punctSpace/g, _punctuationOrSpaceGfmStrongEm).replace(/punct/g, _punctuationGfmStrongEm).getRegex();
1870
1920
  // (6) Not allowed for _
1871
1921
  const emStrongRDelimUnd = edit('^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)' // Skip orphan inside strong
1872
1922
  + '|[^_]+(?=[^_])' // Consume to delim
@@ -1928,7 +1978,8 @@ const inlinePedantic = {
1928
1978
  */
1929
1979
  const inlineGfm = {
1930
1980
  ...inlineNormal,
1931
- escape: edit(escape$1).replace('])', '~|])').getRegex(),
1981
+ emStrongRDelimAst: emStrongRDelimAstGfm,
1982
+ emStrongLDelim: emStrongLDelimGfm,
1932
1983
  url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, 'i').replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),
1933
1984
  _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
1934
1985
  del: /^(~~?)(?=[^\s~])((?:\\.|[^\\])*?(?:\\.|[^\s~\\]))\1(?=[^~]|$)/,
@@ -2044,9 +2095,7 @@ function rtrim(str, c, invert) {
2044
2095
  // Step left until we fail to match the invert condition.
2045
2096
  while (suffLen < l) {
2046
2097
  const currChar = str.charAt(l - suffLen - 1);
2047
- if (currChar === c && !invert) {
2048
- suffLen++;
2049
- } else if (currChar !== c && invert) {
2098
+ if (currChar === c && true) {
2050
2099
  suffLen++;
2051
2100
  } else {
2052
2101
  break;
@@ -2424,6 +2473,9 @@ class _Tokenizer {
2424
2473
  if (lastItem) {
2425
2474
  lastItem.raw = lastItem.raw.trimEnd();
2426
2475
  lastItem.text = lastItem.text.trimEnd();
2476
+ } else {
2477
+ // not a list since there were no items
2478
+ return;
2427
2479
  }
2428
2480
  list.raw = list.raw.trimEnd();
2429
2481
  // Item child tokens handled here at end because we needed to have the final item to trim it first
@@ -4156,19 +4208,24 @@ const loadContent = async (state, platform) => {
4156
4208
  };
4157
4209
  };
4158
4210
 
4211
+ const terminate = () => {
4212
+ globalThis.close();
4213
+ };
4214
+
4159
4215
  const commandMap = {
4160
- 'RenderMarkdown.renderMarkdown': renderMarkdown,
4161
- 'HandleIconError.handleIconError': handleIconError,
4162
- 'ExtensionDetail.loadContent': loadContent,
4163
4216
  'ExtensionDetail.getMenuEntries': getMenuEntries,
4164
- 'ExtensionDetail.getVirtualDom': getExtensionDetailVirtualDom
4217
+ 'ExtensionDetail.getVirtualDom': getExtensionDetailVirtualDom,
4218
+ 'ExtensionDetail.loadContent': loadContent,
4219
+ 'ExtensionDetail.terminate': terminate,
4220
+ 'HandleIconError.handleIconError': handleIconError,
4221
+ 'RenderMarkdown.renderMarkdown': renderMarkdown
4165
4222
  };
4166
4223
 
4167
4224
  const listen = async () => {
4168
4225
  const rpc = await WebWorkerRpcClient.create({
4169
4226
  commandMap: commandMap
4170
4227
  });
4171
- setRpc(rpc);
4228
+ set(RendererWorker, rpc);
4172
4229
  };
4173
4230
 
4174
4231
  const main = async () => {