@lvce-editor/about-view 1.7.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. package/dist/aboutWorkerMain.js +1252 -1103
  2. package/package.json +1 -1
@@ -1,1295 +1,1444 @@
1
- const commands = Object.create(null);
2
- const registerCommand = (key, fn) => {
3
- commands[key] = fn;
1
+ const Two = '2.0';
2
+ const create$4 = (method, params) => {
3
+ return {
4
+ jsonrpc: Two,
5
+ method,
6
+ params
7
+ };
4
8
  };
5
- const register = commandMap => {
6
- for (const [key, value] of Object.entries(commandMap)) {
7
- registerCommand(key, value);
8
- }
9
+ const state = {
10
+ callbacks: Object.create(null)
9
11
  };
10
- const getCommand = key => {
11
- return commands[key];
12
+ const set = (id, fn) => {
13
+ state.callbacks[id] = fn;
12
14
  };
13
- const execute = (command, ...args) => {
14
- const fn = getCommand(command);
15
- if (!fn) {
16
- throw new Error(`command not found ${command}`);
17
- }
18
- return fn(...args);
15
+ const get = id => {
16
+ return state.callbacks[id];
19
17
  };
20
-
21
- const None = 0;
22
- const Ok = 1;
23
- const Copy = 2;
24
-
25
- const getNextFocus = focusId => {
26
- switch (focusId) {
27
- case Ok:
28
- return Copy;
29
- case Copy:
30
- return Ok;
31
- default:
32
- return None;
33
- }
18
+ const remove = id => {
19
+ delete state.callbacks[id];
34
20
  };
35
-
36
- const focusNext = state => {
21
+ let id = 0;
22
+ const create$3 = () => {
23
+ return ++id;
24
+ };
25
+ const warn = (...args) => {
26
+ console.warn(...args);
27
+ };
28
+ const registerPromise = () => {
29
+ const id = create$3();
37
30
  const {
38
- focusId
39
- } = state;
31
+ resolve,
32
+ promise
33
+ } = Promise.withResolvers();
34
+ set(id, resolve);
40
35
  return {
41
- ...state,
42
- focusId: getNextFocus(focusId)
36
+ id,
37
+ promise
43
38
  };
44
39
  };
45
-
46
- const getPreviousFocus = focusId => {
47
- switch (focusId) {
48
- case Ok:
49
- return Copy;
50
- case Copy:
51
- return Ok;
52
- default:
53
- return None;
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`);
45
+ return;
54
46
  }
47
+ fn(response);
48
+ remove(id);
55
49
  };
56
-
57
- const focusPrevious = state => {
50
+ const create$2 = (method, params) => {
58
51
  const {
59
- focusId
60
- } = state;
52
+ id,
53
+ promise
54
+ } = registerPromise();
55
+ const message = {
56
+ jsonrpc: Two,
57
+ method,
58
+ params,
59
+ id
60
+ };
61
61
  return {
62
- ...state,
63
- focusId: getPreviousFocus(focusId)
62
+ message,
63
+ promise
64
64
  };
65
65
  };
66
-
67
- const emptyObject = {};
68
- const RE_PLACEHOLDER = /{(PH\d+)}/g;
69
- const i18nString = (key, placeholders = emptyObject) => {
70
- if (placeholders === emptyObject) {
71
- return key;
66
+ class JsonRpcError extends Error {
67
+ constructor(message) {
68
+ super(message);
69
+ this.name = 'JsonRpcError';
72
70
  }
73
- const replacer = (match, rest) => {
74
- // @ts-ignore
75
- return placeholders[rest];
76
- };
77
- return key.replaceAll(RE_PLACEHOLDER, replacer);
78
- };
79
-
80
- // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
81
-
82
- /**
83
- * @enum {string}
84
- */
85
- const UiStrings$1 = {
86
- OneSecondAgo: '1 second ago',
87
- SomeSecondsAgo: '{PH1} seconds ago',
88
- OneMinuteAgo: '1 minute ago',
89
- SomeMinutesAgo: '{PH1} minutes ago',
90
- OneHourAgo: '1 hour ago',
91
- SomeHoursAgo: '{PH1} hours ago',
92
- OneDayAgo: '1 day ago',
93
- SomeDaysAgo: '{PH1} days ago',
94
- OneWeekAgo: '1 week ago',
95
- SomeWeeksAgo: '{PH1} weeks ago',
96
- OneMonthAgo: '1 month ago',
97
- SomeMonthsAgo: '{PH1} months ago',
98
- OneYearAgo: '1 year ago',
99
- SomeYearsAgo: '{PH1} years ago',
100
- InOneSecond: 'in 1 second',
101
- InSomeSeconds: 'in {PH1} seconds',
102
- InOneMinute: 'in 1 minute',
103
- InSomeMinutes: 'in {PH1} minutes',
104
- InOneHour: 'in 1 hour',
105
- InSomeHours: 'in {PH1} hours',
106
- InOneDay: 'in 1 day',
107
- InSomeDays: 'in {PH1} days',
108
- InOneWeek: 'in 1 week',
109
- InSomeWeeks: 'in {PH1} weeks',
110
- InOneMonth: 'in 1 month',
111
- InSomeMonths: 'in {PH1} months',
112
- InOneYear: 'in 1 year',
113
- InSomeYears: 'in {PH1} years'
114
- };
115
- const oneSecondAgo = () => {
116
- return i18nString(UiStrings$1.OneSecondAgo);
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;
90
+ }
91
+ }
92
+ if (message.startsWith('TypeError: ')) {
93
+ return TypeError;
94
+ }
95
+ if (message.startsWith('SyntaxError: ')) {
96
+ return SyntaxError;
97
+ }
98
+ if (message.startsWith('ReferenceError: ')) {
99
+ return ReferenceError;
100
+ }
101
+ return Error;
117
102
  };
118
- const someSecondsAgo = seconds => {
119
- return i18nString(UiStrings$1.SomeSecondsAgo, {
120
- PH1: seconds
121
- });
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;
112
+ }
113
+ return error;
114
+ }
115
+ return new ErrorConstructor(message);
122
116
  };
123
- const oneMinuteAgo = () => {
124
- return i18nString(UiStrings$1.OneMinuteAgo);
117
+ const getNewLineIndex$1 = (string, startIndex = undefined) => {
118
+ return string.indexOf(NewLine$3, startIndex);
125
119
  };
126
- const someMinutesAgo = minutes => {
127
- return i18nString(UiStrings$1.SomeMinutesAgo, {
128
- PH1: minutes
129
- });
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;
124
+ }
125
+ return parentStack;
130
126
  };
131
- const oneHourAgo = () => {
132
- return i18nString(UiStrings$1.OneHourAgo);
127
+ const joinLines$2 = lines => {
128
+ return lines.join(NewLine$3);
133
129
  };
134
- const someHoursAgo = hours => {
135
- return i18nString(UiStrings$1.SomeHoursAgo, {
136
- PH1: hours
137
- });
130
+ const MethodNotFound = -32601;
131
+ const Custom = -32001;
132
+ const splitLines$1 = lines => {
133
+ return lines.split(NewLine$3);
134
+ };
135
+ const restoreJsonRpcError = error => {
136
+ if (error && error instanceof Error) {
137
+ return error;
138
+ }
139
+ const currentStack = joinLines$2(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;
145
+ }
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$1(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;
181
+ }
182
+ if (typeof error === 'string') {
183
+ return new Error(`JsonRpc Error: ${error}`);
184
+ }
185
+ return new Error(`JsonRpc Error: ${error}`);
138
186
  };
139
- const oneDayAgo = () => {
140
- return i18nString(UiStrings$1.OneDayAgo);
187
+ const unwrapJsonRpcResult = responseMessage => {
188
+ if ('error' in responseMessage) {
189
+ const restoredError = restoreJsonRpcError(responseMessage.error);
190
+ throw restoredError;
191
+ }
192
+ if ('result' in responseMessage) {
193
+ return responseMessage.result;
194
+ }
195
+ throw new JsonRpcError('unexpected response message');
141
196
  };
142
- const someDaysAgo = days => {
143
- return i18nString(UiStrings$1.SomeDaysAgo, {
144
- PH1: days
145
- });
197
+ const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
198
+ const getErrorType = prettyError => {
199
+ if (prettyError && prettyError.type) {
200
+ return prettyError.type;
201
+ }
202
+ if (prettyError && prettyError.constructor && prettyError.constructor.name) {
203
+ return prettyError.constructor.name;
204
+ }
205
+ return undefined;
146
206
  };
147
- const oneWeekAgo = () => {
148
- return i18nString(UiStrings$1.OneWeekAgo);
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
+ };
214
+ }
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
+ };
149
226
  };
150
- const someWeeksAgo = weeks => {
151
- return i18nString(UiStrings$1.SomeWeeksAgo, {
152
- PH1: weeks
153
- });
227
+ const create$1$1 = (message, error) => {
228
+ return {
229
+ jsonrpc: Two,
230
+ id: message.id,
231
+ error
232
+ };
154
233
  };
155
- const oneMonthAgo = () => {
156
- return i18nString(UiStrings$1.OneMonthAgo);
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$1(message, errorProperty);
157
239
  };
158
- const someMonthsAgo = months => {
159
- return i18nString(UiStrings$1.SomeMonthsAgo, {
160
- PH1: months
161
- });
240
+ const create = (message, result) => {
241
+ return {
242
+ jsonrpc: Two,
243
+ id: message.id,
244
+ result: result ?? null
245
+ };
162
246
  };
163
- const oneYearAgo = () => {
164
- return i18nString(UiStrings$1.OneYearAgo);
247
+ const getSuccessResponse = (message, result) => {
248
+ const resultProperty = result ?? null;
249
+ return create(message, resultProperty);
165
250
  };
166
- const someYearsAgo = years => {
167
- return i18nString(UiStrings$1.SomeYearsAgo, {
168
- PH1: years
169
- });
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
+ }
170
258
  };
171
- const inOneSecond = () => {
172
- return i18nString(UiStrings$1.InOneSecond);
259
+ const defaultPreparePrettyError = error => {
260
+ return error;
173
261
  };
174
- const inSomeSeconds = seconds => {
175
- return i18nString(UiStrings$1.InSomeSeconds, {
176
- PH1: seconds
177
- });
262
+ const defaultLogError = () => {
263
+ // ignore
178
264
  };
179
- const inOneMinute = () => {
180
- return i18nString(UiStrings$1.InOneMinute);
265
+ const defaultRequiresSocket = () => {
266
+ return false;
181
267
  };
182
- const inSomeMinutes = minutes => {
183
- return i18nString(UiStrings$1.InSomeMinutes, {
184
- PH1: minutes
185
- });
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
+ }
284
+ 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]
292
+ };
186
293
  };
187
- const inOneHour = () => {
188
- return i18nString(UiStrings$1.InOneHour);
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);
321
+ return;
322
+ }
323
+ throw new JsonRpcError('unexpected message');
189
324
  };
190
- const inSomeHours = hours => {
191
- return i18nString(UiStrings$1.InSomeHours, {
192
- PH1: hours
193
- });
325
+ const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
326
+ const {
327
+ message,
328
+ 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);
194
337
  };
195
- const inOneDay = () => {
196
- return i18nString(UiStrings$1.InOneDay);
338
+ const send = (transport, method, ...params) => {
339
+ const message = create$4(method, params);
340
+ transport.send(message);
197
341
  };
198
- const inSomeDays = days => {
199
- return i18nString(UiStrings$1.InSomeDays, {
200
- PH1: days
201
- });
342
+ const invoke = (ipc, method, ...params) => {
343
+ return invokeHelper(ipc, method, params, false);
202
344
  };
203
- const inOneWeek = () => {
204
- return i18nString(UiStrings$1.InOneWeek);
345
+ const invokeAndTransfer = (ipc, method, ...params) => {
346
+ return invokeHelper(ipc, method, params, true);
205
347
  };
206
- const inSomeWeeks = weeks => {
207
- return i18nString(UiStrings$1.InSomeWeeks, {
208
- PH1: weeks
209
- });
348
+
349
+ const commands = Object.create(null);
350
+ const register = commandMap => {
351
+ Object.assign(commands, commandMap);
210
352
  };
211
- const inOneMonth = () => {
212
- return i18nString(UiStrings$1.InOneMonth);
353
+ const getCommand = key => {
354
+ return commands[key];
213
355
  };
214
- const inSomeMonths = months => {
215
- return i18nString(UiStrings$1.InSomeMonths, {
216
- PH1: months
217
- });
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);
218
362
  };
219
- const inOneYear = () => {
220
- return i18nString(UiStrings$1.InOneYear);
363
+
364
+ const getData$1 = event => {
365
+ return event.data;
221
366
  };
222
- const inSomeYears = years => {
223
- return i18nString(UiStrings$1.InSomeYears, {
224
- PH1: years
225
- });
367
+ const attachEvents = that => {
368
+ const handleMessage = (...args) => {
369
+ const data = that.getData(...args);
370
+ that.dispatchEvent(new MessageEvent('message', {
371
+ data
372
+ }));
373
+ };
374
+ that.onMessage(handleMessage);
375
+ const handleClose = event => {
376
+ that.dispatchEvent(new Event('close'));
377
+ };
378
+ that.onClose(handleClose);
226
379
  };
227
-
228
- const minute = 60;
229
- const hour = minute * 60;
230
- const day = hour * 24;
231
- const week = day * 7;
232
- const month = day * 30;
233
- const year = day * 365;
234
-
235
- // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
236
- const formatDateFuture = seconds => {
237
- if (seconds < minute) {
238
- if (seconds === 1) {
239
- return inOneSecond();
240
- }
241
- return inSomeSeconds(seconds);
380
+ class Ipc extends EventTarget {
381
+ constructor(rawIpc) {
382
+ super();
383
+ this._rawIpc = rawIpc;
384
+ attachEvents(this);
242
385
  }
243
- if (seconds < hour) {
244
- const minutes = Math.floor(seconds / minute);
245
- if (minutes === 1) {
246
- return inOneMinute();
247
- }
248
- return inSomeMinutes(minutes);
386
+ }
387
+ const readyMessage = 'ready';
388
+ const walkValue = (value, transferrables, isTransferrable) => {
389
+ if (!value) {
390
+ return;
249
391
  }
250
- if (seconds < day) {
251
- const days = Math.floor(seconds / hour);
252
- if (days === 1) {
253
- return inOneHour();
254
- }
255
- return inSomeHours(days);
392
+ if (isTransferrable(value)) {
393
+ transferrables.push(value);
394
+ return;
256
395
  }
257
- if (seconds < week) {
258
- const days = Math.floor(seconds / day);
259
- if (days === 1) {
260
- return inOneDay();
396
+ if (Array.isArray(value)) {
397
+ for (const item of value) {
398
+ walkValue(item, transferrables, isTransferrable);
261
399
  }
262
- return inSomeDays(days);
400
+ return;
263
401
  }
264
- if (seconds < month) {
265
- const weeks = Math.floor(seconds / week);
266
- if (weeks === 1) {
267
- return inOneWeek();
402
+ if (typeof value === 'object') {
403
+ for (const property of Object.values(value)) {
404
+ walkValue(property, transferrables, isTransferrable);
268
405
  }
269
- return inSomeWeeks(weeks);
406
+ return;
270
407
  }
271
- if (seconds < year) {
272
- const months = Math.floor(seconds / month);
273
- if (months === 1) {
274
- return inOneMonth();
408
+ };
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;
275
429
  }
276
- return inSomeMonths(months);
277
- }
278
- const years = Math.floor(seconds / year);
279
- if (years === 1) {
280
- return inOneYear();
281
430
  }
282
- return inSomeYears(years);
431
+ return false;
283
432
  };
284
-
285
- // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
286
- const formatDatePast = seconds => {
287
- if (seconds < minute) {
288
- if (seconds === 1) {
289
- return oneSecondAgo();
290
- }
291
- return someSecondsAgo(seconds);
433
+ const getTransferrables = value => {
434
+ const transferrables = [];
435
+ walkValue(value, transferrables, isTransferrable);
436
+ return transferrables;
437
+ };
438
+ const listen$2 = () => {
439
+ // @ts-ignore
440
+ if (typeof WorkerGlobalScope === 'undefined') {
441
+ throw new TypeError('module is not in web worker scope');
292
442
  }
293
- if (seconds < hour) {
294
- const minutes = Math.floor(seconds / minute);
295
- if (minutes === 1) {
296
- return oneMinuteAgo();
297
- }
298
- return someMinutesAgo(minutes);
443
+ return globalThis;
444
+ };
445
+ const signal$2 = global => {
446
+ global.postMessage(readyMessage);
447
+ };
448
+ class IpcChildWithModuleWorker extends Ipc {
449
+ getData(event) {
450
+ return getData$1(event);
299
451
  }
300
- if (seconds < day) {
301
- const days = Math.floor(seconds / hour);
302
- if (days === 1) {
303
- return oneHourAgo();
304
- }
305
- return someHoursAgo(days);
452
+ send(message) {
453
+ // @ts-ignore
454
+ this._rawIpc.postMessage(message);
306
455
  }
307
- if (seconds < week) {
308
- const days = Math.floor(seconds / day);
309
- if (days === 1) {
310
- return oneDayAgo();
311
- }
312
- return someDaysAgo(days);
456
+ sendAndTransfer(message) {
457
+ const transfer = getTransferrables(message);
458
+ // @ts-ignore
459
+ this._rawIpc.postMessage(message, transfer);
313
460
  }
314
- if (seconds < month) {
315
- const weeks = Math.floor(seconds / week);
316
- if (weeks === 1) {
317
- return oneWeekAgo();
318
- }
319
- return someWeeksAgo(weeks);
461
+ dispose() {
462
+ // ignore
320
463
  }
321
- if (seconds < year) {
322
- const months = Math.floor(seconds / month);
323
- if (months === 1) {
324
- return oneMonthAgo();
325
- }
326
- return someMonthsAgo(months);
464
+ onClose(callback) {
465
+ // ignore
327
466
  }
328
- const years = Math.floor(seconds / year);
329
- if (years === 1) {
330
- return oneYearAgo();
467
+ onMessage(callback) {
468
+ this._rawIpc.addEventListener('message', callback);
331
469
  }
332
- return someYearsAgo(years);
333
- };
334
-
335
- // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
336
- const formatDate = (date, now) => {
337
- const difference = now - date;
338
- const seconds = Math.round(difference / 1000);
339
- if (seconds >= 0) {
340
- return formatDatePast(seconds);
341
- }
342
- return formatDateFuture(-seconds);
343
- };
344
-
345
- const formatAboutDate = (isoDate, now) => {
346
- if (!isoDate) {
347
- return 'unknown';
348
- }
349
- const date = new Date(isoDate).getTime();
350
- if (isNaN(date)) {
351
- return `Invalid Date: ${isoDate}`;
352
- }
353
- const ago = formatDate(date, now);
354
- return `${isoDate} (${ago})`;
470
+ }
471
+ const wrap$5 = global => {
472
+ return new IpcChildWithModuleWorker(global);
355
473
  };
356
-
357
- const NewLine$2 = '\n';
358
-
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';
359
478
  const joinLines$1 = lines => {
360
- return lines.join(NewLine$2);
361
- };
362
-
363
- const version = '0.0.0-dev';
364
- const commit = 'unknown commit';
365
- const date = '';
366
- const getElectronVersion = () => {
367
- return '';
479
+ return lines.join(NewLine$1);
368
480
  };
369
- const getNodeVersion = () => {
370
- return '';
481
+ const splitLines = lines => {
482
+ return lines.split(NewLine$1);
371
483
  };
372
- const getChromeVersion = () => {
373
- return '';
484
+ const isModuleNotFoundMessage = line => {
485
+ return line.includes('[ERR_MODULE_NOT_FOUND]');
374
486
  };
375
- const getVersion = () => {
376
- return version;
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
+ };
377
495
  };
378
- const getCommit = () => {
379
- return commit;
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);
380
504
  };
381
- const getV8Version = () => {
382
- return '';
505
+ const isMessageCodeBlockStartIndex = line => {
506
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
383
507
  };
384
- const getDate = () => {
385
- return date;
508
+ const isMessageCodeBlockEndIndex = line => {
509
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
386
510
  };
387
- const productNameLong = 'Lvce Editor - OSS';
388
-
389
- const getDetailString = async () => {
390
- const [electronVersion, nodeVersion, chromeVersion, version, commit, v8Version, date] = await Promise.all([getElectronVersion(), getNodeVersion(), getChromeVersion(), getVersion(), getCommit(), getV8Version(), getDate()]);
391
- const now = Date.now();
392
- const formattedDate = formatAboutDate(date, now);
393
- const lines = [`Version: ${version}`, `Commit: ${commit}`, `Date: ${formattedDate}`, `Electron: ${electronVersion}`, `Chromium: ${chromeVersion}`, `Node: ${nodeVersion}`, `V8: ${v8Version}`];
394
- return joinLines$1(lines);
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;
395
518
  };
396
-
397
- const getBrowser = () => {
398
- return `${navigator.userAgent}`;
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
+ };
399
525
  };
400
-
401
- const getDetailStringWeb = () => {
402
- const version$1 = version;
403
- const commit$1 = commit;
404
- const date$1 = date;
405
- const now = Date.now();
406
- const formattedDate = formatAboutDate(date$1, now);
407
- const browser = getBrowser();
408
- const lines = [`Version: ${version$1}`, `Commit: ${commit$1}`, `Date: ${formattedDate}`, `Browser: ${browser}`];
409
- return lines;
526
+ const isModulesSyntaxError = stderr => {
527
+ if (!stderr) {
528
+ return false;
529
+ }
530
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
410
531
  };
411
-
412
- const Button$2 = 'Button';
413
- const ButtonPrimary = 'ButtonPrimary';
414
- const ButtonSecondary = 'ButtonSecondary';
415
- const DialogButtonsRow = 'DialogButtonsRow';
416
- const DialogClose = 'DialogClose';
417
- const DialogContent = 'DialogContent';
418
- const DialogContentRight = 'DialogContentRight';
419
- const DialogHeading$1 = 'DialogHeading';
420
- const DialogMessage = 'DialogMessage';
421
- const DialogMessageRow = 'DialogMessageRow';
422
- const About = 'About';
423
- const Viewlet = 'Viewlet';
424
- const DialogToolBarRow = 'DialogToolBarRow';
425
- const MaskIcon = 'MaskIcon';
426
- const MaskIconClose = 'MaskIconClose';
427
- const DialogIcon$1 = 'DialogIcon';
428
- const DialogInfoIcon = 'DialogInfoIcon';
429
- const MaskIconInfo = 'MaskIconInfo';
430
-
431
- const HandleClickClose = 'handleClickClose';
432
- const HandleClickCopy = 'handleClickCopy';
433
- const HandleClickOk = 'handleClickOk';
434
- const HandleContextMenu = 'handleContextMenu';
435
- const HandleFocusIn = 'handleFocusIn';
436
-
437
- const Button$1 = 1;
438
- const Div = 4;
439
- const Text = 12;
440
- const Br = 55;
441
-
442
- const text = data => {
532
+ const getModuleSyntaxError = () => {
443
533
  return {
444
- type: Text,
445
- text: data,
446
- childCount: 0
534
+ message: `ES Modules are not supported in electron`,
535
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
447
536
  };
448
537
  };
449
-
450
- const br = {
451
- type: Br,
452
- childCount: 0
453
- };
454
- const renderLine = (line, index) => {
455
- if (index === 0) {
456
- return [text(line)];
538
+ const isModuleNotFoundError = stderr => {
539
+ if (!stderr) {
540
+ return false;
457
541
  }
458
- return [br, text(line)];
542
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
459
543
  };
460
- const getAboutContentVirtualDom = lines => {
461
- const dom = [{
462
- type: Div,
463
- className: DialogMessage,
464
- childCount: lines.length * 2 - 1
465
- }, ...lines.flatMap(renderLine)];
466
- return dom;
544
+ const isNormalStackLine = line => {
545
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
467
546
  };
468
-
469
- const True = 'true';
470
-
471
- const Button = 'button';
472
- const Dialog = 'dialog';
473
-
474
- const joinBySpace = (...items) => {
475
- return items.join(' ');
547
+ const getDetails = lines => {
548
+ const index = lines.findIndex(isNormalStackLine);
549
+ if (index === -1) {
550
+ return {
551
+ actualMessage: joinLines$1(lines),
552
+ rest: []
553
+ };
554
+ }
555
+ let lastIndex = index - 1;
556
+ while (++lastIndex < lines.length) {
557
+ if (!isNormalStackLine(lines[lastIndex])) {
558
+ break;
559
+ }
560
+ }
561
+ return {
562
+ actualMessage: lines[index - 1],
563
+ rest: lines.slice(index, lastIndex)
564
+ };
476
565
  };
477
-
478
- const mergeClassNames = (...classNames) => {
479
- return joinBySpace(...classNames.filter(Boolean));
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);
581
+ return {
582
+ message: `${actualMessage}`,
583
+ code: '',
584
+ stack: rest
585
+ };
480
586
  };
481
-
482
- const getPrimaryButtonVirtualDom = (message, onClick) => {
483
- return [{
484
- type: Button$1,
485
- className: mergeClassNames(Button$2, ButtonPrimary),
486
- onClick,
487
- childCount: 1
488
- }, text(message)];
587
+ const normalizeLine = 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;
489
595
  };
490
- const getSecondaryButtonVirtualDom = (message, onClick) => {
491
- return [{
492
- type: Button$1,
493
- className: mergeClassNames(Button$2, ButtonSecondary),
494
- onClick,
495
- childCount: 1
496
- }, text(message)];
596
+ const getCombinedMessage = (error, message) => {
597
+ const stringifiedError = normalizeLine(`${error}`);
598
+ if (message) {
599
+ return `${message}: ${stringifiedError}`;
600
+ }
601
+ return stringifiedError;
497
602
  };
498
-
499
- const DialogIcon = 'DialogIcon';
500
- const DialogHeading = 'DialogHeading';
501
-
502
- const Focusable = -1;
503
-
504
- const getDialogVirtualDom = (content, closeMessage, infoMessage, okMessage, copyMessage, productName) => {
505
- const dom = [{
506
- type: Div,
507
- className: DialogContent,
508
- tabIndex: Focusable,
509
- role: Dialog,
510
- ariaModal: True,
511
- ariaLabelledBy: joinBySpace(DialogIcon, DialogHeading),
512
- onFocusIn: HandleFocusIn,
513
- childCount: 3
514
- }, {
515
- type: Div,
516
- className: DialogToolBarRow,
517
- childCount: 1
518
- }, {
519
- type: Div,
520
- className: DialogClose,
521
- ariaLabel: closeMessage,
522
- role: Button,
523
- onClick: HandleClickClose,
524
- childCount: 1
525
- }, {
526
- type: Div,
527
- className: mergeClassNames(MaskIcon, MaskIconClose),
528
- childCount: 0
529
- }, {
530
- type: Div,
531
- className: DialogMessageRow,
532
- childCount: 2
533
- }, {
534
- type: Div,
535
- className: mergeClassNames(DialogIcon$1, DialogInfoIcon, MaskIcon, MaskIconInfo),
536
- id: DialogIcon,
537
- ariaLabel: infoMessage,
538
- childCount: 0
539
- }, {
540
- type: Div,
541
- className: DialogContentRight,
542
- childCount: 2
543
- }, {
544
- type: Div,
545
- id: DialogHeading,
546
- className: DialogHeading$1,
547
- childCount: 1
548
- }, text(productName), ...content, {
549
- type: Div,
550
- className: DialogButtonsRow,
551
- childCount: 2
552
- }, ...getSecondaryButtonVirtualDom(okMessage, HandleClickOk), ...getPrimaryButtonVirtualDom(copyMessage, HandleClickCopy)];
553
- return dom;
603
+ const NewLine$2 = '\n';
604
+ const getNewLineIndex = (string, startIndex = undefined) => {
605
+ return string.indexOf(NewLine$2, startIndex);
554
606
  };
555
-
556
- const getAboutVirtualDom = (productName, lines, closeMessage, okMessage, copyMessage, infoMessage) => {
557
- const content = getAboutContentVirtualDom(lines);
558
- return [{
559
- type: Div,
560
- className: mergeClassNames(Viewlet, About),
561
- onContextMenu: HandleContextMenu,
562
- childCount: 1
563
- }, ...getDialogVirtualDom(content, closeMessage, infoMessage, okMessage, copyMessage, productName)];
607
+ const mergeStacks = (parent, child) => {
608
+ if (!child) {
609
+ return parent;
610
+ }
611
+ const parentNewLineIndex = getNewLineIndex(parent);
612
+ const childNewLineIndex = getNewLineIndex(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(child.slice(0, childNewLineIndex));
619
+ if (parentFirstLine.includes(childFirstLine)) {
620
+ return parentFirstLine + childRest;
621
+ }
622
+ return child;
564
623
  };
565
-
566
- const loadContent = state => {
567
- const lines = getDetailStringWeb();
624
+ class VError extends Error {
625
+ constructor(error, message) {
626
+ const combinedMessage = getCombinedMessage(error, message);
627
+ super(combinedMessage);
628
+ this.name = 'VError';
629
+ if (error instanceof Error) {
630
+ this.stack = mergeStacks(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
+ }
640
+ }
641
+ }
642
+ class IpcError extends VError {
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;
666
+ }
667
+ }
668
+ const withResolvers = () => {
669
+ let _resolve;
670
+ const promise = new Promise(resolve => {
671
+ _resolve = resolve;
672
+ });
568
673
  return {
569
- ...state,
570
- productName: productNameLong,
571
- lines,
572
- focusId: Ok
674
+ resolve: _resolve,
675
+ promise
573
676
  };
574
677
  };
678
+ const waitForFirstMessage = async port => {
679
+ const {
680
+ 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();
728
+ }
729
+ }
730
+ onClose(callback) {
731
+ // ignore
732
+ }
733
+ onMessage(callback) {
734
+ this._rawIpc.addEventListener('message', callback);
735
+ this._rawIpc.start();
736
+ }
737
+ }
738
+ const wrap$4 = port => {
739
+ return new IpcChildWithModuleWorkerAndMessagePort(port);
740
+ };
741
+ const IpcChildWithModuleWorkerAndMessagePort$1 = {
742
+ __proto__: null,
743
+ listen: listen$1$1,
744
+ wrap: wrap$4
745
+ };
575
746
 
576
- /**
577
- * @enum {string}
578
- */
579
- const UiStrings = {
580
- Ok: 'Ok',
581
- Copy: 'Copy',
582
- Version: 'Version',
583
- Commit: 'Commit',
584
- Date: 'Date',
585
- Browser: 'Browser',
586
- Info: 'Info',
587
- Close: 'Close',
588
- CloseDialog: 'Close Dialog'
747
+ const createRpc = ipc => {
748
+ const rpc = {
749
+ /**
750
+ * @deprecated
751
+ */
752
+ send(method, ...params) {
753
+ send(ipc, method, ...params);
754
+ },
755
+ invoke(method, ...params) {
756
+ return invoke(ipc, method, ...params);
757
+ },
758
+ invokeAndTransfer(method, ...params) {
759
+ return invokeAndTransfer(ipc, method, ...params);
760
+ }
761
+ };
762
+ return rpc;
589
763
  };
590
- const ok = () => {
591
- return i18nString(UiStrings.Ok);
764
+ const requiresSocket = () => {
765
+ return false;
592
766
  };
593
- const copy = () => {
594
- return i18nString(UiStrings.Copy);
767
+ const preparePrettyError = error => {
768
+ return error;
595
769
  };
596
- const info = () => {
597
- return i18nString(UiStrings.Info);
770
+ const logError = () => {
771
+ // handled by renderer worker
598
772
  };
599
- const closeDialog = () => {
600
- return i18nString(UiStrings.CloseDialog);
773
+ const handleMessage = event => {
774
+ return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
775
+ };
776
+ const handleIpc = ipc => {
777
+ ipc.addEventListener('message', handleMessage);
601
778
  };
602
779
 
603
- const renderDialog = {
604
- isEqual(oldState, newState) {
605
- return oldState.productName === newState.productName && oldState.lines === newState.lines;
606
- },
607
- apply(oldState, newState) {
608
- const okMessage = ok();
609
- const copyMessage = copy();
610
- const closeMessage = closeDialog();
611
- const infoMessage = info();
612
- const dom = getAboutVirtualDom(newState.productName, newState.lines, closeMessage, okMessage, copyMessage, infoMessage);
613
- return ['Viewlet.setDom2', dom];
614
- }
780
+ // @ts-ignore
781
+ const listen$1 = async () => {
782
+ const module = IpcChildWithModuleWorkerAndMessagePort$1;
783
+ const rawIpc = await module.listen();
784
+ const ipc = module.wrap(rawIpc);
785
+ return ipc;
615
786
  };
616
- const getFocusSelector = focusId => {
787
+ const create$1 = async ({
788
+ commandMap
789
+ }) => {
790
+ // TODO create a commandMap per rpc instance
791
+ register(commandMap);
792
+ const ipc = await listen$1();
793
+ handleIpc(ipc);
794
+ const rpc = createRpc(ipc);
795
+ return rpc;
796
+ };
797
+ const WebWorkerRpcClient = {
798
+ __proto__: null,
799
+ create: create$1
800
+ };
801
+
802
+ const None = 0;
803
+ const Ok = 1;
804
+ const Copy = 2;
805
+
806
+ const getNextFocus = focusId => {
617
807
  switch (focusId) {
618
- case Copy:
619
- return '.ButtonPrimary';
620
808
  case Ok:
621
- return '.ButtonSecondary';
809
+ return Copy;
810
+ case Copy:
811
+ return Ok;
622
812
  default:
623
- return '';
813
+ return None;
624
814
  }
625
815
  };
626
- const renderFocus = {
627
- isEqual(oldState, newState) {
628
- return oldState.focusId === newState.focusId;
629
- },
630
- apply(oldState, newState) {
631
- const selector = getFocusSelector(newState.focusId);
632
- return ['setFocused', selector];
633
- }
816
+
817
+ const focusNext = state => {
818
+ const {
819
+ focusId
820
+ } = state;
821
+ return {
822
+ ...state,
823
+ focusId: getNextFocus(focusId)
824
+ };
634
825
  };
635
- const render = [renderDialog, renderFocus];
636
- const doRender = (oldState, newState) => {
637
- const commands = [];
638
- for (const fn of render) {
639
- if (!fn.isEqual(oldState, newState)) {
640
- commands.push(fn.apply(oldState, newState));
641
- }
826
+
827
+ const getPreviousFocus = focusId => {
828
+ switch (focusId) {
829
+ case Ok:
830
+ return Copy;
831
+ case Copy:
832
+ return Ok;
833
+ default:
834
+ return None;
642
835
  }
643
- return commands;
644
836
  };
645
837
 
646
- const commandMap = {
647
- 'About.focusNext': focusNext,
648
- 'About.focusPrevious': focusPrevious,
649
- 'About.getDetailString': getDetailString,
650
- 'About.getDetailStringWeb': getDetailStringWeb,
651
- 'About.getVirtualDom': getAboutVirtualDom,
652
- 'About.loadContent': loadContent,
653
- 'About.render': doRender
838
+ const focusPrevious = state => {
839
+ const {
840
+ focusId
841
+ } = state;
842
+ return {
843
+ ...state,
844
+ focusId: getPreviousFocus(focusId)
845
+ };
654
846
  };
655
847
 
656
- const Two = '2.0';
657
- class AssertionError extends Error {
658
- constructor(message) {
659
- super(message);
660
- this.name = 'AssertionError';
661
- }
662
- }
663
- const getType = value => {
664
- switch (typeof value) {
665
- case 'number':
666
- return 'number';
667
- case 'function':
668
- return 'function';
669
- case 'string':
670
- return 'string';
671
- case 'object':
672
- if (value === null) {
673
- return 'null';
674
- }
675
- if (Array.isArray(value)) {
676
- return 'array';
677
- }
678
- return 'object';
679
- case 'boolean':
680
- return 'boolean';
681
- default:
682
- return 'unknown';
848
+ const emptyObject = {};
849
+ const RE_PLACEHOLDER = /{(PH\d+)}/g;
850
+ const i18nString = (key, placeholders = emptyObject) => {
851
+ if (placeholders === emptyObject) {
852
+ return key;
683
853
  }
854
+ const replacer = (match, rest) => {
855
+ // @ts-ignore
856
+ return placeholders[rest];
857
+ };
858
+ return key.replaceAll(RE_PLACEHOLDER, replacer);
684
859
  };
685
- const number = value => {
686
- const type = getType(value);
687
- if (type !== 'number') {
688
- throw new AssertionError('expected value to be of type number');
689
- }
860
+
861
+ // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
862
+
863
+ /**
864
+ * @enum {string}
865
+ */
866
+ const UiStrings$1 = {
867
+ OneSecondAgo: '1 second ago',
868
+ SomeSecondsAgo: '{PH1} seconds ago',
869
+ OneMinuteAgo: '1 minute ago',
870
+ SomeMinutesAgo: '{PH1} minutes ago',
871
+ OneHourAgo: '1 hour ago',
872
+ SomeHoursAgo: '{PH1} hours ago',
873
+ OneDayAgo: '1 day ago',
874
+ SomeDaysAgo: '{PH1} days ago',
875
+ OneWeekAgo: '1 week ago',
876
+ SomeWeeksAgo: '{PH1} weeks ago',
877
+ OneMonthAgo: '1 month ago',
878
+ SomeMonthsAgo: '{PH1} months ago',
879
+ OneYearAgo: '1 year ago',
880
+ SomeYearsAgo: '{PH1} years ago',
881
+ InOneSecond: 'in 1 second',
882
+ InSomeSeconds: 'in {PH1} seconds',
883
+ InOneMinute: 'in 1 minute',
884
+ InSomeMinutes: 'in {PH1} minutes',
885
+ InOneHour: 'in 1 hour',
886
+ InSomeHours: 'in {PH1} hours',
887
+ InOneDay: 'in 1 day',
888
+ InSomeDays: 'in {PH1} days',
889
+ InOneWeek: 'in 1 week',
890
+ InSomeWeeks: 'in {PH1} weeks',
891
+ InOneMonth: 'in 1 month',
892
+ InSomeMonths: 'in {PH1} months',
893
+ InOneYear: 'in 1 year',
894
+ InSomeYears: 'in {PH1} years'
690
895
  };
691
- const state$1 = {
692
- callbacks: Object.create(null)
896
+ const oneSecondAgo = () => {
897
+ return i18nString(UiStrings$1.OneSecondAgo);
693
898
  };
694
- const get = id => {
695
- return state$1.callbacks[id];
899
+ const someSecondsAgo = seconds => {
900
+ return i18nString(UiStrings$1.SomeSecondsAgo, {
901
+ PH1: seconds
902
+ });
696
903
  };
697
- const remove = id => {
698
- delete state$1.callbacks[id];
904
+ const oneMinuteAgo = () => {
905
+ return i18nString(UiStrings$1.OneMinuteAgo);
699
906
  };
700
- const warn = (...args) => {
701
- console.warn(...args);
907
+ const someMinutesAgo = minutes => {
908
+ return i18nString(UiStrings$1.SomeMinutesAgo, {
909
+ PH1: minutes
910
+ });
702
911
  };
703
- const resolve = (id, args) => {
704
- number(id);
705
- const fn = get(id);
706
- if (!fn) {
707
- console.log(args);
708
- warn(`callback ${id} may already be disposed`);
709
- return;
710
- }
711
- fn(args);
712
- remove(id);
912
+ const oneHourAgo = () => {
913
+ return i18nString(UiStrings$1.OneHourAgo);
713
914
  };
714
- class JsonRpcError extends Error {
715
- constructor(message) {
716
- super(message);
717
- this.name = 'JsonRpcError';
718
- }
719
- }
720
- const MethodNotFound = -32601;
721
- const Custom = -32001;
722
- const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
723
- const getErrorType = prettyError => {
724
- if (prettyError && prettyError.type) {
725
- return prettyError.type;
726
- }
727
- if (prettyError && prettyError.constructor && prettyError.constructor.name) {
728
- return prettyError.constructor.name;
729
- }
730
- return undefined;
915
+ const someHoursAgo = hours => {
916
+ return i18nString(UiStrings$1.SomeHoursAgo, {
917
+ PH1: hours
918
+ });
731
919
  };
732
- const getErrorProperty = (error, prettyError) => {
733
- if (error && error.code === E_COMMAND_NOT_FOUND) {
734
- return {
735
- code: MethodNotFound,
736
- message: error.message,
737
- data: error.stack
738
- };
739
- }
740
- return {
741
- code: Custom,
742
- message: prettyError.message,
743
- data: {
744
- stack: prettyError.stack,
745
- codeFrame: prettyError.codeFrame,
746
- type: getErrorType(prettyError),
747
- code: prettyError.code,
748
- name: prettyError.name
749
- }
750
- };
920
+ const oneDayAgo = () => {
921
+ return i18nString(UiStrings$1.OneDayAgo);
751
922
  };
752
- const create$1 = (message, error) => {
753
- return {
754
- jsonrpc: Two,
755
- id: message.id,
756
- error
757
- };
923
+ const someDaysAgo = days => {
924
+ return i18nString(UiStrings$1.SomeDaysAgo, {
925
+ PH1: days
926
+ });
758
927
  };
759
- const getErrorResponse = (message, error, preparePrettyError, logError) => {
760
- const prettyError = preparePrettyError(error);
761
- logError(error, prettyError);
762
- const errorProperty = getErrorProperty(error, prettyError);
763
- return create$1(message, errorProperty);
928
+ const oneWeekAgo = () => {
929
+ return i18nString(UiStrings$1.OneWeekAgo);
764
930
  };
765
- const create = (message, result) => {
766
- return {
767
- jsonrpc: Two,
768
- id: message.id,
769
- result: result ?? null
770
- };
931
+ const someWeeksAgo = weeks => {
932
+ return i18nString(UiStrings$1.SomeWeeksAgo, {
933
+ PH1: weeks
934
+ });
771
935
  };
772
- const getSuccessResponse = (message, result) => {
773
- const resultProperty = result ?? null;
774
- return create(message, resultProperty);
936
+ const oneMonthAgo = () => {
937
+ return i18nString(UiStrings$1.OneMonthAgo);
775
938
  };
776
- const getResponse = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
777
- try {
778
- const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
779
- return getSuccessResponse(message, result);
780
- } catch (error) {
781
- return getErrorResponse(message, error, preparePrettyError, logError);
782
- }
939
+ const someMonthsAgo = months => {
940
+ return i18nString(UiStrings$1.SomeMonthsAgo, {
941
+ PH1: months
942
+ });
783
943
  };
784
- const defaultPreparePrettyError = error => {
785
- return error;
944
+ const oneYearAgo = () => {
945
+ return i18nString(UiStrings$1.OneYearAgo);
946
+ };
947
+ const someYearsAgo = years => {
948
+ return i18nString(UiStrings$1.SomeYearsAgo, {
949
+ PH1: years
950
+ });
951
+ };
952
+ const inOneSecond = () => {
953
+ return i18nString(UiStrings$1.InOneSecond);
954
+ };
955
+ const inSomeSeconds = seconds => {
956
+ return i18nString(UiStrings$1.InSomeSeconds, {
957
+ PH1: seconds
958
+ });
959
+ };
960
+ const inOneMinute = () => {
961
+ return i18nString(UiStrings$1.InOneMinute);
962
+ };
963
+ const inSomeMinutes = minutes => {
964
+ return i18nString(UiStrings$1.InSomeMinutes, {
965
+ PH1: minutes
966
+ });
967
+ };
968
+ const inOneHour = () => {
969
+ return i18nString(UiStrings$1.InOneHour);
970
+ };
971
+ const inSomeHours = hours => {
972
+ return i18nString(UiStrings$1.InSomeHours, {
973
+ PH1: hours
974
+ });
975
+ };
976
+ const inOneDay = () => {
977
+ return i18nString(UiStrings$1.InOneDay);
786
978
  };
787
- const defaultLogError = () => {
788
- // ignore
979
+ const inSomeDays = days => {
980
+ return i18nString(UiStrings$1.InSomeDays, {
981
+ PH1: days
982
+ });
789
983
  };
790
- const defaultRequiresSocket = () => {
791
- return false;
984
+ const inOneWeek = () => {
985
+ return i18nString(UiStrings$1.InOneWeek);
792
986
  };
793
- const defaultResolve = resolve;
794
- const handleJsonRpcMessage = async (...args) => {
795
- let message;
796
- let ipc;
797
- let execute;
798
- let preparePrettyError;
799
- let logError;
800
- let resolve;
801
- let requiresSocket;
802
- if (args.length === 1) {
803
- const arg = args[0];
804
- message = arg.message;
805
- ipc = arg.ipc;
806
- execute = arg.execute;
807
- preparePrettyError = arg.preparePrettyError || defaultPreparePrettyError;
808
- logError = arg.logError || defaultLogError;
809
- requiresSocket = arg.requiresSocket || defaultRequiresSocket;
810
- resolve = arg.resolve || defaultResolve;
811
- } else {
812
- ipc = args[0];
813
- message = args[1];
814
- execute = args[2];
815
- resolve = args[3];
816
- preparePrettyError = args[4];
817
- logError = args[5];
818
- requiresSocket = args[6];
819
- }
820
- if ('id' in message) {
821
- if ('method' in message) {
822
- const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
823
- try {
824
- ipc.send(response);
825
- } catch (error) {
826
- const errorResponse = getErrorResponse(message, error, preparePrettyError, logError);
827
- ipc.send(errorResponse);
828
- }
829
- return;
830
- }
831
- resolve(message.id, message);
832
- return;
833
- }
834
- if ('method' in message) {
835
- await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
836
- return;
837
- }
838
- throw new JsonRpcError('unexpected message');
987
+ const inSomeWeeks = weeks => {
988
+ return i18nString(UiStrings$1.InSomeWeeks, {
989
+ PH1: weeks
990
+ });
839
991
  };
840
-
841
- const requiresSocket = () => {
842
- return false;
992
+ const inOneMonth = () => {
993
+ return i18nString(UiStrings$1.InOneMonth);
843
994
  };
844
- const preparePrettyError = error => {
845
- return error;
995
+ const inSomeMonths = months => {
996
+ return i18nString(UiStrings$1.InSomeMonths, {
997
+ PH1: months
998
+ });
846
999
  };
847
- const logError = () => {
848
- // handled by renderer worker
1000
+ const inOneYear = () => {
1001
+ return i18nString(UiStrings$1.InOneYear);
849
1002
  };
850
- const handleMessage = event => {
851
- return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
1003
+ const inSomeYears = years => {
1004
+ return i18nString(UiStrings$1.InSomeYears, {
1005
+ PH1: years
1006
+ });
852
1007
  };
853
1008
 
854
- const handleIpc = ipc => {
855
- ipc.addEventListener('message', handleMessage);
856
- };
1009
+ const minute = 60;
1010
+ const hour = minute * 60;
1011
+ const day = hour * 24;
1012
+ const week = day * 7;
1013
+ const month = day * 30;
1014
+ const year = day * 365;
857
1015
 
858
- const getData$1 = event => {
859
- return event.data;
860
- };
861
- const walkValue = (value, transferrables, isTransferrable) => {
862
- if (!value) {
863
- return;
1016
+ // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
1017
+ const formatDateFuture = seconds => {
1018
+ if (seconds < minute) {
1019
+ if (seconds === 1) {
1020
+ return inOneSecond();
1021
+ }
1022
+ return inSomeSeconds(seconds);
864
1023
  }
865
- if (isTransferrable(value)) {
866
- transferrables.push(value);
867
- return;
1024
+ if (seconds < hour) {
1025
+ const minutes = Math.floor(seconds / minute);
1026
+ if (minutes === 1) {
1027
+ return inOneMinute();
1028
+ }
1029
+ return inSomeMinutes(minutes);
868
1030
  }
869
- if (Array.isArray(value)) {
870
- for (const item of value) {
871
- walkValue(item, transferrables, isTransferrable);
1031
+ if (seconds < day) {
1032
+ const days = Math.floor(seconds / hour);
1033
+ if (days === 1) {
1034
+ return inOneHour();
872
1035
  }
873
- return;
1036
+ return inSomeHours(days);
874
1037
  }
875
- if (typeof value === 'object') {
876
- for (const property of Object.values(value)) {
877
- walkValue(property, transferrables, isTransferrable);
1038
+ if (seconds < week) {
1039
+ const days = Math.floor(seconds / day);
1040
+ if (days === 1) {
1041
+ return inOneDay();
878
1042
  }
879
- return;
1043
+ return inSomeDays(days);
880
1044
  }
881
- };
882
- const isMessagePort = value => {
883
- return value && value instanceof MessagePort;
884
- };
885
- const isMessagePortMain = value => {
886
- return value && value.constructor && value.constructor.name === 'MessagePortMain';
887
- };
888
- const isOffscreenCanvas = value => {
889
- return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
890
- };
891
- const isInstanceOf = (value, constructorName) => {
892
- return value?.constructor?.name === constructorName;
893
- };
894
- const isSocket = value => {
895
- return isInstanceOf(value, 'Socket');
896
- };
897
- const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
898
- const isTransferrable = value => {
899
- for (const fn of transferrables) {
900
- if (fn(value)) {
901
- return true;
1045
+ if (seconds < month) {
1046
+ const weeks = Math.floor(seconds / week);
1047
+ if (weeks === 1) {
1048
+ return inOneWeek();
902
1049
  }
1050
+ return inSomeWeeks(weeks);
903
1051
  }
904
- return false;
905
- };
906
- const getTransferrables = value => {
907
- const transferrables = [];
908
- walkValue(value, transferrables, isTransferrable);
909
- return transferrables;
910
- };
911
- const attachEvents = that => {
912
- const handleMessage = (...args) => {
913
- const data = that.getData(...args);
914
- that.dispatchEvent(new MessageEvent('message', {
915
- data
916
- }));
917
- };
918
- that.onMessage(handleMessage);
919
- const handleClose = event => {
920
- that.dispatchEvent(new Event('close'));
921
- };
922
- that.onClose(handleClose);
923
- };
924
- class Ipc extends EventTarget {
925
- constructor(rawIpc) {
926
- super();
927
- this._rawIpc = rawIpc;
928
- attachEvents(this);
1052
+ if (seconds < year) {
1053
+ const months = Math.floor(seconds / month);
1054
+ if (months === 1) {
1055
+ return inOneMonth();
1056
+ }
1057
+ return inSomeMonths(months);
929
1058
  }
930
- }
931
- const readyMessage = 'ready';
932
- const listen$4 = () => {
933
- // @ts-ignore
934
- if (typeof WorkerGlobalScope === 'undefined') {
935
- throw new TypeError('module is not in web worker scope');
1059
+ const years = Math.floor(seconds / year);
1060
+ if (years === 1) {
1061
+ return inOneYear();
936
1062
  }
937
- return globalThis;
938
- };
939
- const signal$3 = global => {
940
- global.postMessage(readyMessage);
1063
+ return inSomeYears(years);
941
1064
  };
942
- class IpcChildWithModuleWorker extends Ipc {
943
- getData(event) {
944
- return getData$1(event);
1065
+
1066
+ // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
1067
+ const formatDatePast = seconds => {
1068
+ if (seconds < minute) {
1069
+ if (seconds === 1) {
1070
+ return oneSecondAgo();
1071
+ }
1072
+ return someSecondsAgo(seconds);
945
1073
  }
946
- send(message) {
947
- // @ts-ignore
948
- this._rawIpc.postMessage(message);
1074
+ if (seconds < hour) {
1075
+ const minutes = Math.floor(seconds / minute);
1076
+ if (minutes === 1) {
1077
+ return oneMinuteAgo();
1078
+ }
1079
+ return someMinutesAgo(minutes);
949
1080
  }
950
- sendAndTransfer(message) {
951
- const transfer = getTransferrables(message);
952
- // @ts-ignore
953
- this._rawIpc.postMessage(message, transfer);
1081
+ if (seconds < day) {
1082
+ const days = Math.floor(seconds / hour);
1083
+ if (days === 1) {
1084
+ return oneHourAgo();
1085
+ }
1086
+ return someHoursAgo(days);
954
1087
  }
955
- dispose() {
956
- // ignore
1088
+ if (seconds < week) {
1089
+ const days = Math.floor(seconds / day);
1090
+ if (days === 1) {
1091
+ return oneDayAgo();
1092
+ }
1093
+ return someDaysAgo(days);
957
1094
  }
958
- onClose(callback) {
959
- // ignore
1095
+ if (seconds < month) {
1096
+ const weeks = Math.floor(seconds / week);
1097
+ if (weeks === 1) {
1098
+ return oneWeekAgo();
1099
+ }
1100
+ return someWeeksAgo(weeks);
960
1101
  }
961
- onMessage(callback) {
962
- this._rawIpc.addEventListener('message', callback);
1102
+ if (seconds < year) {
1103
+ const months = Math.floor(seconds / month);
1104
+ if (months === 1) {
1105
+ return oneMonthAgo();
1106
+ }
1107
+ return someMonthsAgo(months);
1108
+ }
1109
+ const years = Math.floor(seconds / year);
1110
+ if (years === 1) {
1111
+ return oneYearAgo();
1112
+ }
1113
+ return someYearsAgo(years);
1114
+ };
1115
+
1116
+ // based on https://github.com/microsoft/vscode/blob/bd782eb059e133d3a20fdb446b8feb0010a278ad/src/vs/base/common/date.ts (License MIT)
1117
+ const formatDate = (date, now) => {
1118
+ const difference = now - date;
1119
+ const seconds = Math.round(difference / 1000);
1120
+ if (seconds >= 0) {
1121
+ return formatDatePast(seconds);
1122
+ }
1123
+ return formatDateFuture(-seconds);
1124
+ };
1125
+
1126
+ const formatAboutDate = (isoDate, now) => {
1127
+ if (!isoDate) {
1128
+ return 'unknown';
1129
+ }
1130
+ const date = new Date(isoDate).getTime();
1131
+ if (isNaN(date)) {
1132
+ return `Invalid Date: ${isoDate}`;
963
1133
  }
964
- }
965
- const wrap$6 = global => {
966
- return new IpcChildWithModuleWorker(global);
967
- };
968
- const IpcChildWithModuleWorker$1 = {
969
- __proto__: null,
970
- listen: listen$4,
971
- signal: signal$3,
972
- wrap: wrap$6
1134
+ const ago = formatDate(date, now);
1135
+ return `${isoDate} (${ago})`;
973
1136
  };
974
- const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
975
- const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
976
- const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
977
- const NewLine$1 = '\n';
1137
+
1138
+ const NewLine = '\n';
1139
+
978
1140
  const joinLines = lines => {
979
- return lines.join(NewLine$1);
1141
+ return lines.join(NewLine);
980
1142
  };
981
- const splitLines = lines => {
982
- return lines.split(NewLine$1);
1143
+
1144
+ const version = '0.0.0-dev';
1145
+ const commit = 'unknown commit';
1146
+ const date = '';
1147
+ const getElectronVersion = () => {
1148
+ return '';
983
1149
  };
984
- const isModuleNotFoundMessage = line => {
985
- return line.includes('[ERR_MODULE_NOT_FOUND]');
1150
+ const getNodeVersion = () => {
1151
+ return '';
986
1152
  };
987
- const getModuleNotFoundError = stderr => {
988
- const lines = splitLines(stderr);
989
- const messageIndex = lines.findIndex(isModuleNotFoundMessage);
990
- const message = lines[messageIndex];
991
- return {
992
- message,
993
- code: ERR_MODULE_NOT_FOUND
994
- };
1153
+ const getChromeVersion = () => {
1154
+ return '';
995
1155
  };
996
- const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
997
- const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
998
- const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
999
- const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
1000
- const RE_AT = /^\s+at/;
1001
- const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
1002
- const isUnhelpfulNativeModuleError = stderr => {
1003
- return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
1156
+ const getVersion = () => {
1157
+ return version;
1004
1158
  };
1005
- const isMessageCodeBlockStartIndex = line => {
1006
- return RE_MESSAGE_CODE_BLOCK_START.test(line);
1159
+ const getCommit = () => {
1160
+ return commit;
1007
1161
  };
1008
- const isMessageCodeBlockEndIndex = line => {
1009
- return RE_MESSAGE_CODE_BLOCK_END.test(line);
1162
+ const getV8Version = () => {
1163
+ return '';
1010
1164
  };
1011
- const getMessageCodeBlock = stderr => {
1012
- const lines = splitLines(stderr);
1013
- const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
1014
- const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
1015
- const relevantLines = lines.slice(startIndex, endIndex);
1016
- const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
1017
- return relevantMessage;
1165
+ const getDate = () => {
1166
+ return date;
1018
1167
  };
1019
- const getNativeModuleErrorMessage = stderr => {
1020
- const message = getMessageCodeBlock(stderr);
1021
- return {
1022
- message: `Incompatible native node module: ${message}`,
1023
- code: E_INCOMPATIBLE_NATIVE_MODULE
1024
- };
1168
+ const productNameLong = 'Lvce Editor - OSS';
1169
+
1170
+ const getDetailString = async () => {
1171
+ const [electronVersion, nodeVersion, chromeVersion, version, commit, v8Version, date] = await Promise.all([getElectronVersion(), getNodeVersion(), getChromeVersion(), getVersion(), getCommit(), getV8Version(), getDate()]);
1172
+ const now = Date.now();
1173
+ const formattedDate = formatAboutDate(date, now);
1174
+ const lines = [`Version: ${version}`, `Commit: ${commit}`, `Date: ${formattedDate}`, `Electron: ${electronVersion}`, `Chromium: ${chromeVersion}`, `Node: ${nodeVersion}`, `V8: ${v8Version}`];
1175
+ return joinLines(lines);
1025
1176
  };
1026
- const isModulesSyntaxError = stderr => {
1027
- if (!stderr) {
1028
- return false;
1029
- }
1030
- return stderr.includes('SyntaxError: Cannot use import statement outside a module');
1177
+
1178
+ const getBrowser = () => {
1179
+ return `${navigator.userAgent}`;
1031
1180
  };
1032
- const getModuleSyntaxError = () => {
1181
+
1182
+ const getDetailStringWeb = () => {
1183
+ const version$1 = version;
1184
+ const commit$1 = commit;
1185
+ const date$1 = date;
1186
+ const now = Date.now();
1187
+ const formattedDate = formatAboutDate(date$1, now);
1188
+ const browser = getBrowser();
1189
+ const lines = [`Version: ${version$1}`, `Commit: ${commit$1}`, `Date: ${formattedDate}`, `Browser: ${browser}`];
1190
+ return lines;
1191
+ };
1192
+
1193
+ const Button$2 = 'Button';
1194
+ const ButtonPrimary = 'ButtonPrimary';
1195
+ const ButtonSecondary = 'ButtonSecondary';
1196
+ const DialogButtonsRow = 'DialogButtonsRow';
1197
+ const DialogClose = 'DialogClose';
1198
+ const DialogContent = 'DialogContent';
1199
+ const DialogContentRight = 'DialogContentRight';
1200
+ const DialogHeading$1 = 'DialogHeading';
1201
+ const DialogMessage = 'DialogMessage';
1202
+ const DialogMessageRow = 'DialogMessageRow';
1203
+ const About = 'About';
1204
+ const Viewlet = 'Viewlet';
1205
+ const DialogToolBarRow = 'DialogToolBarRow';
1206
+ const MaskIcon = 'MaskIcon';
1207
+ const MaskIconClose = 'MaskIconClose';
1208
+ const DialogIcon$1 = 'DialogIcon';
1209
+ const DialogInfoIcon = 'DialogInfoIcon';
1210
+ const MaskIconInfo = 'MaskIconInfo';
1211
+
1212
+ const HandleClickClose = 'handleClickClose';
1213
+ const HandleClickCopy = 'handleClickCopy';
1214
+ const HandleClickOk = 'handleClickOk';
1215
+ const HandleContextMenu = 'handleContextMenu';
1216
+ const HandleFocusIn = 'handleFocusIn';
1217
+
1218
+ const Button$1 = 1;
1219
+ const Div = 4;
1220
+ const Text = 12;
1221
+ const Br = 55;
1222
+
1223
+ const text = data => {
1033
1224
  return {
1034
- message: `ES Modules are not supported in electron`,
1035
- code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
1225
+ type: Text,
1226
+ text: data,
1227
+ childCount: 0
1036
1228
  };
1037
1229
  };
1038
- const isModuleNotFoundError = stderr => {
1039
- if (!stderr) {
1040
- return false;
1230
+
1231
+ const br = {
1232
+ type: Br,
1233
+ childCount: 0
1234
+ };
1235
+ const renderLine = (line, index) => {
1236
+ if (index === 0) {
1237
+ return [text(line)];
1041
1238
  }
1042
- return stderr.includes('ERR_MODULE_NOT_FOUND');
1239
+ return [br, text(line)];
1043
1240
  };
1044
- const isNormalStackLine = line => {
1045
- return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
1241
+ const getAboutContentVirtualDom = lines => {
1242
+ const dom = [{
1243
+ type: Div,
1244
+ className: DialogMessage,
1245
+ childCount: lines.length * 2 - 1
1246
+ }, ...lines.flatMap(renderLine)];
1247
+ return dom;
1046
1248
  };
1047
- const getDetails = lines => {
1048
- const index = lines.findIndex(isNormalStackLine);
1049
- if (index === -1) {
1050
- return {
1051
- actualMessage: joinLines(lines),
1052
- rest: []
1053
- };
1054
- }
1055
- let lastIndex = index - 1;
1056
- while (++lastIndex < lines.length) {
1057
- if (!isNormalStackLine(lines[lastIndex])) {
1058
- break;
1059
- }
1060
- }
1061
- return {
1062
- actualMessage: lines[index - 1],
1063
- rest: lines.slice(index, lastIndex)
1064
- };
1249
+
1250
+ const True = 'true';
1251
+
1252
+ const Button = 'button';
1253
+ const Dialog = 'dialog';
1254
+
1255
+ const joinBySpace = (...items) => {
1256
+ return items.join(' ');
1257
+ };
1258
+
1259
+ const mergeClassNames = (...classNames) => {
1260
+ return joinBySpace(...classNames.filter(Boolean));
1261
+ };
1262
+
1263
+ const getPrimaryButtonVirtualDom = (message, onClick) => {
1264
+ return [{
1265
+ type: Button$1,
1266
+ className: mergeClassNames(Button$2, ButtonPrimary),
1267
+ onClick,
1268
+ childCount: 1
1269
+ }, text(message)];
1270
+ };
1271
+ const getSecondaryButtonVirtualDom = (message, onClick) => {
1272
+ return [{
1273
+ type: Button$1,
1274
+ className: mergeClassNames(Button$2, ButtonSecondary),
1275
+ onClick,
1276
+ childCount: 1
1277
+ }, text(message)];
1278
+ };
1279
+
1280
+ const DialogIcon = 'DialogIcon';
1281
+ const DialogHeading = 'DialogHeading';
1282
+
1283
+ const Focusable = -1;
1284
+
1285
+ const getDialogVirtualDom = (content, closeMessage, infoMessage, okMessage, copyMessage, productName) => {
1286
+ const dom = [{
1287
+ type: Div,
1288
+ className: DialogContent,
1289
+ tabIndex: Focusable,
1290
+ role: Dialog,
1291
+ ariaModal: True,
1292
+ ariaLabelledBy: joinBySpace(DialogIcon, DialogHeading),
1293
+ onFocusIn: HandleFocusIn,
1294
+ childCount: 3
1295
+ }, {
1296
+ type: Div,
1297
+ className: DialogToolBarRow,
1298
+ childCount: 1
1299
+ }, {
1300
+ type: Div,
1301
+ className: DialogClose,
1302
+ ariaLabel: closeMessage,
1303
+ role: Button,
1304
+ onClick: HandleClickClose,
1305
+ childCount: 1
1306
+ }, {
1307
+ type: Div,
1308
+ className: mergeClassNames(MaskIcon, MaskIconClose),
1309
+ childCount: 0
1310
+ }, {
1311
+ type: Div,
1312
+ className: DialogMessageRow,
1313
+ childCount: 2
1314
+ }, {
1315
+ type: Div,
1316
+ className: mergeClassNames(DialogIcon$1, DialogInfoIcon, MaskIcon, MaskIconInfo),
1317
+ id: DialogIcon,
1318
+ ariaLabel: infoMessage,
1319
+ childCount: 0
1320
+ }, {
1321
+ type: Div,
1322
+ className: DialogContentRight,
1323
+ childCount: 2
1324
+ }, {
1325
+ type: Div,
1326
+ id: DialogHeading,
1327
+ className: DialogHeading$1,
1328
+ childCount: 1
1329
+ }, text(productName), ...content, {
1330
+ type: Div,
1331
+ className: DialogButtonsRow,
1332
+ childCount: 2
1333
+ }, ...getSecondaryButtonVirtualDom(okMessage, HandleClickOk), ...getPrimaryButtonVirtualDom(copyMessage, HandleClickCopy)];
1334
+ return dom;
1065
1335
  };
1066
- const getHelpfulChildProcessError = (stdout, stderr) => {
1067
- if (isUnhelpfulNativeModuleError(stderr)) {
1068
- return getNativeModuleErrorMessage(stderr);
1069
- }
1070
- if (isModulesSyntaxError(stderr)) {
1071
- return getModuleSyntaxError();
1072
- }
1073
- if (isModuleNotFoundError(stderr)) {
1074
- return getModuleNotFoundError(stderr);
1075
- }
1076
- const lines = splitLines(stderr);
1077
- const {
1078
- actualMessage,
1079
- rest
1080
- } = getDetails(lines);
1336
+
1337
+ const getAboutVirtualDom = (productName, lines, closeMessage, okMessage, copyMessage, infoMessage) => {
1338
+ const content = getAboutContentVirtualDom(lines);
1339
+ return [{
1340
+ type: Div,
1341
+ className: mergeClassNames(Viewlet, About),
1342
+ onContextMenu: HandleContextMenu,
1343
+ childCount: 1
1344
+ }, ...getDialogVirtualDom(content, closeMessage, infoMessage, okMessage, copyMessage, productName)];
1345
+ };
1346
+
1347
+ const loadContent = state => {
1348
+ const lines = getDetailStringWeb();
1081
1349
  return {
1082
- message: `${actualMessage}`,
1083
- code: '',
1084
- stack: rest
1350
+ ...state,
1351
+ productName: productNameLong,
1352
+ lines,
1353
+ focusId: Ok
1085
1354
  };
1086
1355
  };
1087
- const normalizeLine = line => {
1088
- if (line.startsWith('Error: ')) {
1089
- return line.slice(`Error: `.length);
1090
- }
1091
- if (line.startsWith('VError: ')) {
1092
- return line.slice(`VError: `.length);
1093
- }
1094
- return line;
1095
- };
1096
- const getCombinedMessage = (error, message) => {
1097
- const stringifiedError = normalizeLine(`${error}`);
1098
- if (message) {
1099
- return `${message}: ${stringifiedError}`;
1100
- }
1101
- return stringifiedError;
1102
- };
1103
- const NewLine = '\n';
1104
- const getNewLineIndex = (string, startIndex = undefined) => {
1105
- return string.indexOf(NewLine, startIndex);
1356
+
1357
+ /**
1358
+ * @enum {string}
1359
+ */
1360
+ const UiStrings = {
1361
+ Ok: 'Ok',
1362
+ Copy: 'Copy',
1363
+ Version: 'Version',
1364
+ Commit: 'Commit',
1365
+ Date: 'Date',
1366
+ Browser: 'Browser',
1367
+ Info: 'Info',
1368
+ Close: 'Close',
1369
+ CloseDialog: 'Close Dialog'
1106
1370
  };
1107
- const mergeStacks = (parent, child) => {
1108
- if (!child) {
1109
- return parent;
1110
- }
1111
- const parentNewLineIndex = getNewLineIndex(parent);
1112
- const childNewLineIndex = getNewLineIndex(child);
1113
- if (childNewLineIndex === -1) {
1114
- return parent;
1115
- }
1116
- const parentFirstLine = parent.slice(0, parentNewLineIndex);
1117
- const childRest = child.slice(childNewLineIndex);
1118
- const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
1119
- if (parentFirstLine.includes(childFirstLine)) {
1120
- return parentFirstLine + childRest;
1121
- }
1122
- return child;
1371
+ const ok = () => {
1372
+ return i18nString(UiStrings.Ok);
1123
1373
  };
1124
- class VError extends Error {
1125
- constructor(error, message) {
1126
- const combinedMessage = getCombinedMessage(error, message);
1127
- super(combinedMessage);
1128
- this.name = 'VError';
1129
- if (error instanceof Error) {
1130
- this.stack = mergeStacks(this.stack, error.stack);
1131
- }
1132
- if (error.codeFrame) {
1133
- // @ts-ignore
1134
- this.codeFrame = error.codeFrame;
1135
- }
1136
- if (error.code) {
1137
- // @ts-ignore
1138
- this.code = error.code;
1139
- }
1140
- }
1141
- }
1142
- class IpcError extends VError {
1143
- // @ts-ignore
1144
- constructor(betterMessage, stdout = '', stderr = '') {
1145
- if (stdout || stderr) {
1146
- // @ts-ignore
1147
- const {
1148
- message,
1149
- code,
1150
- stack
1151
- } = getHelpfulChildProcessError(stdout, stderr);
1152
- const cause = new Error(message);
1153
- // @ts-ignore
1154
- cause.code = code;
1155
- cause.stack = stack;
1156
- super(cause, betterMessage);
1157
- } else {
1158
- super(betterMessage);
1159
- }
1160
- // @ts-ignore
1161
- this.name = 'IpcError';
1162
- // @ts-ignore
1163
- this.stdout = stdout;
1164
- // @ts-ignore
1165
- this.stderr = stderr;
1166
- }
1167
- }
1168
- const withResolvers = () => {
1169
- let _resolve;
1170
- const promise = new Promise(resolve => {
1171
- _resolve = resolve;
1172
- });
1173
- return {
1174
- resolve: _resolve,
1175
- promise
1176
- };
1374
+ const copy = () => {
1375
+ return i18nString(UiStrings.Copy);
1177
1376
  };
1178
- const waitForFirstMessage = async port => {
1179
- const {
1180
- resolve,
1181
- promise
1182
- } = withResolvers();
1183
- port.addEventListener('message', resolve, {
1184
- once: true
1185
- });
1186
- const event = await promise;
1187
- // @ts-ignore
1188
- return event.data;
1377
+ const info = () => {
1378
+ return i18nString(UiStrings.Info);
1189
1379
  };
1190
- const listen$3 = async () => {
1191
- const parentIpcRaw = listen$4();
1192
- signal$3(parentIpcRaw);
1193
- const parentIpc = wrap$6(parentIpcRaw);
1194
- const firstMessage = await waitForFirstMessage(parentIpc);
1195
- if (firstMessage.method !== 'initialize') {
1196
- throw new IpcError('unexpected first message');
1197
- }
1198
- const type = firstMessage.params[0];
1199
- if (type === 'message-port') {
1200
- parentIpc.send({
1201
- jsonrpc: '2.0',
1202
- id: firstMessage.id,
1203
- result: null
1204
- });
1205
- parentIpc.dispose();
1206
- const port = firstMessage.params[1];
1207
- return port;
1208
- }
1209
- return globalThis;
1380
+ const closeDialog = () => {
1381
+ return i18nString(UiStrings.CloseDialog);
1210
1382
  };
1211
- class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
1212
- constructor(port) {
1213
- super(port);
1214
- }
1215
- getData(event) {
1216
- return getData$1(event);
1217
- }
1218
- send(message) {
1219
- this._rawIpc.postMessage(message);
1220
- }
1221
- sendAndTransfer(message) {
1222
- const transfer = getTransferrables(message);
1223
- this._rawIpc.postMessage(message, transfer);
1224
- }
1225
- dispose() {
1226
- if (this._rawIpc.close) {
1227
- this._rawIpc.close();
1228
- }
1229
- }
1230
- onClose(callback) {
1231
- // ignore
1232
- }
1233
- onMessage(callback) {
1234
- this._rawIpc.addEventListener('message', callback);
1235
- this._rawIpc.start();
1383
+
1384
+ const getFocusSelector = focusId => {
1385
+ switch (focusId) {
1386
+ case Copy:
1387
+ return '.ButtonPrimary';
1388
+ case Ok:
1389
+ return '.ButtonSecondary';
1390
+ default:
1391
+ return '';
1236
1392
  }
1237
- }
1238
- const wrap$5 = port => {
1239
- return new IpcChildWithModuleWorkerAndMessagePort(port);
1240
- };
1241
- const IpcChildWithModuleWorkerAndMessagePort$1 = {
1242
- __proto__: null,
1243
- listen: listen$3,
1244
- wrap: wrap$5
1245
1393
  };
1246
1394
 
1247
- const MessagePort$1 = 1;
1248
- const ModuleWorker = 2;
1249
- const ReferencePort = 3;
1250
- const ModuleWorkerAndMessagePort = 8;
1251
- const Auto = () => {
1252
- // @ts-expect-error
1253
- if (globalThis.acceptPort) {
1254
- return MessagePort$1;
1395
+ const renderDialog = {
1396
+ isEqual(oldState, newState) {
1397
+ return oldState.productName === newState.productName && oldState.lines === newState.lines;
1398
+ },
1399
+ apply(oldState, newState) {
1400
+ const okMessage = ok();
1401
+ const copyMessage = copy();
1402
+ const closeMessage = closeDialog();
1403
+ const infoMessage = info();
1404
+ const dom = getAboutVirtualDom(newState.productName, newState.lines, closeMessage, okMessage, copyMessage, infoMessage);
1405
+ return ['Viewlet.setDom2', dom];
1255
1406
  }
1256
- // @ts-expect-error
1257
- if (globalThis.acceptReferencePort) {
1258
- return ReferencePort;
1407
+ };
1408
+ const renderFocus = {
1409
+ isEqual(oldState, newState) {
1410
+ return oldState.focusId === newState.focusId;
1411
+ },
1412
+ apply(oldState, newState) {
1413
+ const selector = getFocusSelector(newState.focusId);
1414
+ return ['setFocused', selector];
1259
1415
  }
1260
- return ModuleWorkerAndMessagePort;
1261
1416
  };
1262
-
1263
- // @ts-ignore
1264
- const getModule = method => {
1265
- switch (method) {
1266
- case ModuleWorker:
1267
- return IpcChildWithModuleWorker$1;
1268
- case ModuleWorkerAndMessagePort:
1269
- return IpcChildWithModuleWorkerAndMessagePort$1;
1270
- default:
1271
- throw new Error('unexpected ipc type');
1417
+ const render = [renderDialog, renderFocus];
1418
+ const doRender = (oldState, newState) => {
1419
+ const commands = [];
1420
+ for (const fn of render) {
1421
+ if (!fn.isEqual(oldState, newState)) {
1422
+ commands.push(fn.apply(oldState, newState));
1423
+ }
1272
1424
  }
1425
+ return commands;
1273
1426
  };
1274
1427
 
1275
- const listen$1 = async ({
1276
- method
1277
- }) => {
1278
- const module = getModule(method);
1279
- const rawIpc = await module.listen();
1280
- if (module.signal) {
1281
- module.signal(rawIpc);
1282
- }
1283
- const ipc = module.wrap(rawIpc);
1284
- return ipc;
1428
+ const commandMap = {
1429
+ 'About.focusNext': focusNext,
1430
+ 'About.focusPrevious': focusPrevious,
1431
+ 'About.getDetailString': getDetailString,
1432
+ 'About.getDetailStringWeb': getDetailStringWeb,
1433
+ 'About.getVirtualDom': getAboutVirtualDom,
1434
+ 'About.loadContent': loadContent,
1435
+ 'About.render': doRender
1285
1436
  };
1286
1437
 
1287
1438
  const listen = async () => {
1288
- register(commandMap);
1289
- const ipc = await listen$1({
1290
- method: Auto()
1439
+ await WebWorkerRpcClient.create({
1440
+ commandMap: commandMap
1291
1441
  });
1292
- handleIpc(ipc);
1293
1442
  };
1294
1443
 
1295
1444
  const main = async () => {