@lvce-editor/chat-storage-worker 1.4.0 → 1.5.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
  const isMessagePort = value => {
2
58
  return value && value instanceof MessagePort;
3
59
  };
@@ -68,48 +124,148 @@ class Ipc extends EventTarget {
68
124
  attachEvents(this);
69
125
  }
70
126
  }
71
- const readyMessage = 'ready';
72
- const getData$2 = event => {
73
- return event.data;
127
+ const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
128
+ const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
129
+ const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
130
+ const NewLine$1 = '\n';
131
+ const joinLines$1 = lines => {
132
+ return lines.join(NewLine$1);
133
+ };
134
+ const RE_AT = /^\s+at/;
135
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
136
+ const isNormalStackLine = line => {
137
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
138
+ };
139
+ const getDetails = lines => {
140
+ const index = lines.findIndex(isNormalStackLine);
141
+ if (index === -1) {
142
+ return {
143
+ actualMessage: joinLines$1(lines),
144
+ rest: []
145
+ };
146
+ }
147
+ let lastIndex = index - 1;
148
+ while (++lastIndex < lines.length) {
149
+ if (!isNormalStackLine(lines[lastIndex])) {
150
+ break;
151
+ }
152
+ }
153
+ return {
154
+ actualMessage: lines[index - 1],
155
+ rest: lines.slice(index, lastIndex)
156
+ };
74
157
  };
75
- const listen$8 = ({
76
- port
77
- }) => {
78
- return port;
158
+ const splitLines$1 = lines => {
159
+ return lines.split(NewLine$1);
79
160
  };
80
- const signal$9 = port => {
81
- port.postMessage(readyMessage);
161
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
162
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
163
+ const isMessageCodeBlockStartIndex = line => {
164
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
82
165
  };
83
- class IpcChildWithMessagePort extends Ipc {
84
- getData(event) {
85
- return getData$2(event);
166
+ const isMessageCodeBlockEndIndex = line => {
167
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
168
+ };
169
+ const getMessageCodeBlock = stderr => {
170
+ const lines = splitLines$1(stderr);
171
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
172
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
173
+ const relevantLines = lines.slice(startIndex, endIndex);
174
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
175
+ return relevantMessage;
176
+ };
177
+ const isModuleNotFoundMessage = line => {
178
+ return line.includes('[ERR_MODULE_NOT_FOUND]');
179
+ };
180
+ const getModuleNotFoundError = stderr => {
181
+ const lines = splitLines$1(stderr);
182
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
183
+ const message = lines[messageIndex];
184
+ return {
185
+ code: ERR_MODULE_NOT_FOUND,
186
+ message
187
+ };
188
+ };
189
+ const isModuleNotFoundError = stderr => {
190
+ if (!stderr) {
191
+ return false;
86
192
  }
87
- send(message) {
88
- this._rawIpc.postMessage(message);
193
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
194
+ };
195
+ const isModulesSyntaxError = stderr => {
196
+ if (!stderr) {
197
+ return false;
89
198
  }
90
- sendAndTransfer(message) {
91
- const transfer = getTransferrables(message);
92
- this._rawIpc.postMessage(message, transfer);
199
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
200
+ };
201
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
202
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
203
+ const isUnhelpfulNativeModuleError = stderr => {
204
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
205
+ };
206
+ const getNativeModuleErrorMessage = stderr => {
207
+ const message = getMessageCodeBlock(stderr);
208
+ return {
209
+ code: E_INCOMPATIBLE_NATIVE_MODULE,
210
+ message: `Incompatible native node module: ${message}`
211
+ };
212
+ };
213
+ const getModuleSyntaxError = () => {
214
+ return {
215
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON,
216
+ message: `ES Modules are not supported in electron`
217
+ };
218
+ };
219
+ const getHelpfulChildProcessError = (stdout, stderr) => {
220
+ if (isUnhelpfulNativeModuleError(stderr)) {
221
+ return getNativeModuleErrorMessage(stderr);
93
222
  }
94
- dispose() {
95
- // ignore
223
+ if (isModulesSyntaxError(stderr)) {
224
+ return getModuleSyntaxError();
96
225
  }
97
- onClose(callback) {
98
- // ignore
226
+ if (isModuleNotFoundError(stderr)) {
227
+ return getModuleNotFoundError(stderr);
99
228
  }
100
- onMessage(callback) {
101
- this._rawIpc.addEventListener('message', callback);
102
- this._rawIpc.start();
229
+ const lines = splitLines$1(stderr);
230
+ const {
231
+ actualMessage,
232
+ rest
233
+ } = getDetails(lines);
234
+ return {
235
+ code: '',
236
+ message: actualMessage,
237
+ stack: rest
238
+ };
239
+ };
240
+ class IpcError extends VError {
241
+ // @ts-ignore
242
+ constructor(betterMessage, stdout = '', stderr = '') {
243
+ if (stdout || stderr) {
244
+ // @ts-ignore
245
+ const {
246
+ code,
247
+ message,
248
+ stack
249
+ } = getHelpfulChildProcessError(stdout, stderr);
250
+ const cause = new Error(message);
251
+ // @ts-ignore
252
+ cause.code = code;
253
+ cause.stack = stack;
254
+ super(cause, betterMessage);
255
+ } else {
256
+ super(betterMessage);
257
+ }
258
+ // @ts-ignore
259
+ this.name = 'IpcError';
260
+ // @ts-ignore
261
+ this.stdout = stdout;
262
+ // @ts-ignore
263
+ this.stderr = stderr;
103
264
  }
104
265
  }
105
- const wrap$g = port => {
106
- return new IpcChildWithMessagePort(port);
107
- };
108
- const IpcChildWithMessagePort$1 = {
109
- __proto__: null,
110
- listen: listen$8,
111
- signal: signal$9,
112
- wrap: wrap$g
266
+ const readyMessage = 'ready';
267
+ const getData$2 = event => {
268
+ return event.data;
113
269
  };
114
270
  const listen$7 = () => {
115
271
  // @ts-ignore
@@ -153,6 +309,100 @@ const IpcChildWithModuleWorker$1 = {
153
309
  signal: signal$8,
154
310
  wrap: wrap$f
155
311
  };
312
+ const addListener = (emitter, type, callback) => {
313
+ if ('addEventListener' in emitter) {
314
+ emitter.addEventListener(type, callback);
315
+ } else {
316
+ emitter.on(type, callback);
317
+ }
318
+ };
319
+ const removeListener = (emitter, type, callback) => {
320
+ if ('removeEventListener' in emitter) {
321
+ emitter.removeEventListener(type, callback);
322
+ } else {
323
+ emitter.off(type, callback);
324
+ }
325
+ };
326
+ const getFirstEvent = (eventEmitter, eventMap) => {
327
+ const {
328
+ promise,
329
+ resolve
330
+ } = Promise.withResolvers();
331
+ const listenerMap = Object.create(null);
332
+ const cleanup = value => {
333
+ for (const event of Object.keys(eventMap)) {
334
+ removeListener(eventEmitter, event, listenerMap[event]);
335
+ }
336
+ resolve(value);
337
+ };
338
+ for (const [event, type] of Object.entries(eventMap)) {
339
+ const listener = event => {
340
+ cleanup({
341
+ event,
342
+ type
343
+ });
344
+ };
345
+ addListener(eventEmitter, event, listener);
346
+ listenerMap[event] = listener;
347
+ }
348
+ return promise;
349
+ };
350
+ const Message$1 = 3;
351
+ const create$5$1 = async ({
352
+ isMessagePortOpen,
353
+ messagePort
354
+ }) => {
355
+ if (!isMessagePort(messagePort)) {
356
+ throw new IpcError('port must be of type MessagePort');
357
+ }
358
+ if (isMessagePortOpen) {
359
+ return messagePort;
360
+ }
361
+ const eventPromise = getFirstEvent(messagePort, {
362
+ message: Message$1
363
+ });
364
+ messagePort.start();
365
+ const {
366
+ event,
367
+ type
368
+ } = await eventPromise;
369
+ if (type !== Message$1) {
370
+ throw new IpcError('Failed to wait for ipc message');
371
+ }
372
+ if (event.data !== readyMessage) {
373
+ throw new IpcError('unexpected first message');
374
+ }
375
+ return messagePort;
376
+ };
377
+ const signal$1 = messagePort => {
378
+ messagePort.start();
379
+ };
380
+ class IpcParentWithMessagePort extends Ipc {
381
+ getData = getData$2;
382
+ send(message) {
383
+ this._rawIpc.postMessage(message);
384
+ }
385
+ sendAndTransfer(message) {
386
+ const transfer = getTransferrables(message);
387
+ this._rawIpc.postMessage(message, transfer);
388
+ }
389
+ dispose() {
390
+ this._rawIpc.close();
391
+ }
392
+ onMessage(callback) {
393
+ this._rawIpc.addEventListener('message', callback);
394
+ }
395
+ onClose(callback) {}
396
+ }
397
+ const wrap$5 = messagePort => {
398
+ return new IpcParentWithMessagePort(messagePort);
399
+ };
400
+ const IpcParentWithMessagePort$1 = {
401
+ __proto__: null,
402
+ create: create$5$1,
403
+ signal: signal$1,
404
+ wrap: wrap$5
405
+ };
156
406
 
157
407
  class CommandNotFoundError extends Error {
158
408
  constructor(command) {
@@ -611,15 +861,19 @@ const listen$1 = async (module, options) => {
611
861
 
612
862
  const create$1 = async ({
613
863
  commandMap,
864
+ isMessagePortOpen = true,
614
865
  messagePort
615
866
  }) => {
616
867
  // TODO create a commandMap per rpc instance
617
868
  register(commandMap);
618
- const ipc = await listen$1(IpcChildWithMessagePort$1, {
619
- port: messagePort
869
+ const rawIpc = await IpcParentWithMessagePort$1.create({
870
+ isMessagePortOpen,
871
+ messagePort
620
872
  });
873
+ const ipc = IpcParentWithMessagePort$1.wrap(rawIpc);
621
874
  handleIpc(ipc);
622
875
  const rpc = createRpc(ipc);
876
+ messagePort.start();
623
877
  return rpc;
624
878
  };
625
879
 
@@ -1459,6 +1713,7 @@ const getChatViewEvents = async sessionId => {
1459
1713
  const handleMessagePort = async port => {
1460
1714
  await create$1({
1461
1715
  commandMap: commandMap,
1716
+ isMessagePortOpen: true,
1462
1717
  messagePort: port
1463
1718
  });
1464
1719
  };
@@ -1523,7 +1778,8 @@ const commandMap = {
1523
1778
  'ChatStorage.setSession': setSession,
1524
1779
  'ChatStorage.setTodosInCacheStorage': setTodosInCacheStorage,
1525
1780
  'ChatStorage.setTodosInIndexedDb': setTodosInIndexedDb,
1526
- 'HandleMessagePort.handleMessagePort': handleMessagePort
1781
+ 'HandleMessagePort.handleMessagePort': handleMessagePort,
1782
+ initialize: (_, port) => handleMessagePort(port)
1527
1783
  };
1528
1784
 
1529
1785
  const listen = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/chat-storage-worker",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Chat Storage Worker",
5
5
  "repository": {
6
6
  "type": "git",