@lvce-editor/ipc 3.1.0 → 3.3.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.
@@ -0,0 +1,1134 @@
1
+ const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
2
+ const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
3
+ const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
4
+
5
+ const NewLine$1 = '\n';
6
+
7
+ const joinLines = lines => {
8
+ return lines.join(NewLine$1);
9
+ };
10
+
11
+ const splitLines = lines => {
12
+ return lines.split(NewLine$1);
13
+ };
14
+
15
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
16
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
17
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
18
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
19
+ const RE_AT = /^\s+at/;
20
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
21
+ const isUnhelpfulNativeModuleError = stderr => {
22
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
23
+ };
24
+ const isMessageCodeBlockStartIndex = line => {
25
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
26
+ };
27
+ const isMessageCodeBlockEndIndex = line => {
28
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
29
+ };
30
+ const getMessageCodeBlock = stderr => {
31
+ const lines = splitLines(stderr);
32
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
33
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
34
+ const relevantLines = lines.slice(startIndex, endIndex);
35
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
36
+ return relevantMessage;
37
+ };
38
+ const getNativeModuleErrorMessage = stderr => {
39
+ const message = getMessageCodeBlock(stderr);
40
+ return {
41
+ message: `Incompatible native node module: ${message}`,
42
+ code: E_INCOMPATIBLE_NATIVE_MODULE
43
+ };
44
+ };
45
+ const isModulesSyntaxError = stderr => {
46
+ if (!stderr) {
47
+ return false;
48
+ }
49
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
50
+ };
51
+ const getModuleSyntaxError = () => {
52
+ return {
53
+ message: `ES Modules are not supported in electron`,
54
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
55
+ };
56
+ };
57
+ const isModuleNotFoundError = stderr => {
58
+ if (!stderr) {
59
+ return false;
60
+ }
61
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
62
+ };
63
+ const isModuleNotFoundMessage = line => {
64
+ return line.includes('ERR_MODULE_NOT_FOUND');
65
+ };
66
+ const getModuleNotFoundError = stderr => {
67
+ const lines = splitLines(stderr);
68
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
69
+ const message = lines[messageIndex];
70
+ return {
71
+ message,
72
+ code: ERR_MODULE_NOT_FOUND
73
+ };
74
+ };
75
+ const isNormalStackLine = line => {
76
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
77
+ };
78
+ const getDetails = lines => {
79
+ const index = lines.findIndex(isNormalStackLine);
80
+ if (index === -1) {
81
+ return {
82
+ actualMessage: joinLines(lines),
83
+ rest: []
84
+ };
85
+ }
86
+ let lastIndex = index - 1;
87
+ while (++lastIndex < lines.length) {
88
+ if (!isNormalStackLine(lines[lastIndex])) {
89
+ break;
90
+ }
91
+ }
92
+ return {
93
+ actualMessage: lines[index - 1],
94
+ rest: lines.slice(index, lastIndex)
95
+ };
96
+ };
97
+ const getHelpfulChildProcessError = (stdout, stderr) => {
98
+ if (isUnhelpfulNativeModuleError(stderr)) {
99
+ return getNativeModuleErrorMessage(stderr);
100
+ }
101
+ if (isModulesSyntaxError(stderr)) {
102
+ return getModuleSyntaxError();
103
+ }
104
+ if (isModuleNotFoundError(stderr)) {
105
+ return getModuleNotFoundError(stderr);
106
+ }
107
+ const lines = splitLines(stderr);
108
+ const {
109
+ actualMessage,
110
+ rest
111
+ } = getDetails(lines);
112
+ return {
113
+ message: `${actualMessage}`,
114
+ code: '',
115
+ stack: rest
116
+ };
117
+ };
118
+
119
+ const normalizeLine = line => {
120
+ if (line.startsWith('Error: ')) {
121
+ return line.slice(`Error: `.length);
122
+ }
123
+ if (line.startsWith('VError: ')) {
124
+ return line.slice(`VError: `.length);
125
+ }
126
+ return line;
127
+ };
128
+ const getCombinedMessage = (error, message) => {
129
+ const stringifiedError = normalizeLine(`${error}`);
130
+ if (message) {
131
+ return `${message}: ${stringifiedError}`;
132
+ }
133
+ return stringifiedError;
134
+ };
135
+ const NewLine = '\n';
136
+ const getNewLineIndex = (string, startIndex = undefined) => {
137
+ return string.indexOf(NewLine, startIndex);
138
+ };
139
+ const mergeStacks = (parent, child) => {
140
+ if (!child) {
141
+ return parent;
142
+ }
143
+ const parentNewLineIndex = getNewLineIndex(parent);
144
+ const childNewLineIndex = getNewLineIndex(child);
145
+ if (childNewLineIndex === -1) {
146
+ return parent;
147
+ }
148
+ const parentFirstLine = parent.slice(0, parentNewLineIndex);
149
+ const childRest = child.slice(childNewLineIndex);
150
+ const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
151
+ if (parentFirstLine.includes(childFirstLine)) {
152
+ return parentFirstLine + childRest;
153
+ }
154
+ return child;
155
+ };
156
+ class VError extends Error {
157
+ constructor(error, message) {
158
+ const combinedMessage = getCombinedMessage(error, message);
159
+ super(combinedMessage);
160
+ this.name = 'VError';
161
+ if (error instanceof Error) {
162
+ this.stack = mergeStacks(this.stack, error.stack);
163
+ }
164
+ if (error.codeFrame) {
165
+ // @ts-ignore
166
+ this.codeFrame = error.codeFrame;
167
+ }
168
+ if (error.code) {
169
+ // @ts-ignore
170
+ this.code = error.code;
171
+ }
172
+ }
173
+ }
174
+
175
+ class IpcError extends VError {
176
+ // @ts-ignore
177
+ constructor(message, stdout = '', stderr = '') {
178
+ if (stdout || stderr) {
179
+ // @ts-ignore
180
+ const {
181
+ message,
182
+ code,
183
+ stack
184
+ } = getHelpfulChildProcessError(stdout, stderr);
185
+ const cause = new Error(message);
186
+ // @ts-ignore
187
+ cause.code = code;
188
+ cause.stack = stack;
189
+ super(cause, message);
190
+ } else {
191
+ super(message);
192
+ }
193
+ // @ts-ignore
194
+ this.name = 'IpcError';
195
+ // @ts-ignore
196
+ this.stdout = stdout;
197
+ // @ts-ignore
198
+ this.stderr = stderr;
199
+ }
200
+ }
201
+
202
+ const isMessagePortMain = value => {
203
+ return value && value.constructor && value.constructor.name === 'MessagePortMain';
204
+ };
205
+
206
+ // @ts-ignore
207
+ const listen$5 = ({
208
+ messagePort
209
+ }) => {
210
+ if (!isMessagePortMain(messagePort)) {
211
+ throw new IpcError('port must be of type MessagePortMain');
212
+ }
213
+ return messagePort;
214
+ };
215
+
216
+ // @ts-ignore
217
+ const getActualData$1 = event => {
218
+ const {
219
+ data,
220
+ ports
221
+ } = event;
222
+ if (ports.length === 0) {
223
+ return data;
224
+ }
225
+ return {
226
+ ...data,
227
+ params: [...ports, ...data.params]
228
+ };
229
+ };
230
+
231
+ // @ts-ignore
232
+ const wrap$8 = messagePort => {
233
+ return {
234
+ messagePort,
235
+ // @ts-ignore
236
+ on(event, listener) {
237
+ if (event === 'message') {
238
+ // @ts-ignore
239
+ const wrappedListener = event => {
240
+ const actualData = getActualData$1(event);
241
+ listener(actualData);
242
+ };
243
+ this.messagePort.on(event, wrappedListener);
244
+ } else if (event === 'close') {
245
+ this.messagePort.on('close', listener);
246
+ } else {
247
+ throw new Error('unsupported event type');
248
+ }
249
+ },
250
+ // @ts-ignore
251
+ off(event, listener) {
252
+ this.messagePort.off(event, listener);
253
+ },
254
+ // @ts-ignore
255
+ send(message) {
256
+ this.messagePort.postMessage(message);
257
+ },
258
+ dispose() {
259
+ this.messagePort.close();
260
+ },
261
+ start() {
262
+ this.messagePort.start();
263
+ }
264
+ };
265
+ };
266
+
267
+ const IpcChildWithElectronMessagePort = {
268
+ __proto__: null,
269
+ listen: listen$5,
270
+ wrap: wrap$8
271
+ };
272
+
273
+ // @ts-ignore
274
+ const getUtilityProcessPortData = event => {
275
+ const {
276
+ data,
277
+ ports
278
+ } = event;
279
+ if (ports.length === 0) {
280
+ return data;
281
+ }
282
+ return {
283
+ ...data,
284
+ params: [...ports, ...data.params]
285
+ };
286
+ };
287
+
288
+ const listen$4 = () => {
289
+ // @ts-ignore
290
+ const {
291
+ parentPort
292
+ } = process;
293
+ if (!parentPort) {
294
+ throw new Error('parent port must be defined');
295
+ }
296
+ return parentPort;
297
+ };
298
+
299
+ // @ts-ignore
300
+ const signal$2 = parentPort => {
301
+ parentPort.postMessage('ready');
302
+ };
303
+
304
+ // @ts-ignore
305
+ const wrap$7 = parentPort => {
306
+ return {
307
+ parentPort,
308
+ // @ts-ignore
309
+ on(event, listener) {
310
+ if (event === 'message') {
311
+ // @ts-ignore
312
+ const wrappedListener = event => {
313
+ const actualData = getUtilityProcessPortData(event);
314
+ listener(actualData);
315
+ };
316
+ this.parentPort.on(event, wrappedListener);
317
+ } else if (event === 'close') {
318
+ this.parentPort.on('close', listener);
319
+ } else {
320
+ throw new Error('unsupported event type');
321
+ }
322
+ },
323
+ // @ts-ignore
324
+ off(event, listener) {
325
+ this.parentPort.off(event, listener);
326
+ },
327
+ // @ts-ignore
328
+ send(message) {
329
+ this.parentPort.postMessage(message);
330
+ },
331
+ // @ts-ignore
332
+ sendAndTransfer(message, transfer) {
333
+ this.parentPort.postMessage(message, transfer);
334
+ },
335
+ dispose() {
336
+ this.parentPort.close();
337
+ }
338
+ };
339
+ };
340
+
341
+ const IpcChildWithElectronUtilityProcess = {
342
+ __proto__: null,
343
+ listen: listen$4,
344
+ signal: signal$2,
345
+ wrap: wrap$7
346
+ };
347
+
348
+ const getData = event => {
349
+ return event.data;
350
+ };
351
+
352
+ const listen$3 = () => {
353
+ // @ts-ignore
354
+ if (typeof WorkerGlobalScope === 'undefined') {
355
+ throw new TypeError('module is not in web worker scope');
356
+ }
357
+ // @ts-ignore
358
+ globalThis.postMessage('ready');
359
+ return globalThis;
360
+ };
361
+ const signal$1 = global => {
362
+ global.postMessage('ready');
363
+ };
364
+ const wrap$6 = global => {
365
+ return {
366
+ global,
367
+ /**
368
+ * @type {any}
369
+ */
370
+ listener: undefined,
371
+ send(message) {
372
+ this.global.postMessage(message);
373
+ },
374
+ sendAndTransfer(message, transferables) {
375
+ this.global.postMessage(message, transferables);
376
+ },
377
+ get onmessage() {
378
+ return this.listener;
379
+ },
380
+ set onmessage(listener) {
381
+ const wrappedListener = event => {
382
+ const data = getData(event);
383
+ // @ts-expect-error
384
+ listener({
385
+ data,
386
+ target: this
387
+ });
388
+ };
389
+ this.listener = listener;
390
+ this.global.onmessage = wrappedListener;
391
+ }
392
+ };
393
+ };
394
+
395
+ const IpcChildWithModuleWorker = {
396
+ __proto__: null,
397
+ listen: listen$3,
398
+ signal: signal$1,
399
+ wrap: wrap$6
400
+ };
401
+
402
+ const withResolvers = () => {
403
+ let _resolve;
404
+ const promise = new Promise(resolve => {
405
+ _resolve = resolve;
406
+ });
407
+ return {
408
+ resolve: _resolve,
409
+ promise
410
+ };
411
+ };
412
+
413
+ const waitForFirstMessage = async port => {
414
+ const {
415
+ resolve,
416
+ promise
417
+ } = withResolvers();
418
+ const cleanup = value => {
419
+ port.onmessage = null;
420
+ resolve(value);
421
+ };
422
+ const handleMessage = event => {
423
+ cleanup(event);
424
+ };
425
+ port.onmessage = handleMessage;
426
+ const event = await promise;
427
+ // @ts-expect-error
428
+ return event.data;
429
+ };
430
+
431
+ const listen$2 = async () => {
432
+ const parentIpcRaw = listen$3();
433
+ const parentIpc = wrap$6(parentIpcRaw);
434
+ const firstMessage = await waitForFirstMessage(parentIpc);
435
+ if (firstMessage.method !== 'initialize') {
436
+ throw new IpcError('unexpected first message');
437
+ }
438
+ const type = firstMessage.params[0];
439
+ if (type === 'message-port') {
440
+ const port = firstMessage.params[1];
441
+ return port;
442
+ }
443
+ return globalThis;
444
+ };
445
+ const wrap$5 = port => {
446
+ return {
447
+ port,
448
+ /**
449
+ * @type {any}
450
+ */
451
+ wrappedListener: undefined,
452
+ send(message) {
453
+ this.port.postMessage(message);
454
+ },
455
+ sendAndTransfer(message, transferables) {
456
+ this.port.postMessage(message, transferables);
457
+ },
458
+ get onmessage() {
459
+ return this.wrappedListener;
460
+ },
461
+ set onmessage(listener) {
462
+ if (listener) {
463
+ // @ts-expect-error
464
+ this.wrappedListener = event => {
465
+ const data = getData(event);
466
+ // @ts-expect-error
467
+ listener({
468
+ data,
469
+ target: this
470
+ });
471
+ };
472
+ } else {
473
+ this.wrappedListener = undefined;
474
+ }
475
+ this.port.onmessage = this.wrappedListener;
476
+ }
477
+ };
478
+ };
479
+
480
+ const IpcChildWithModuleWorkerAndMessagePort = {
481
+ __proto__: null,
482
+ listen: listen$2,
483
+ wrap: wrap$5
484
+ };
485
+
486
+ const listen$1 = async () => {
487
+ if (!process.send) {
488
+ throw new Error('process.send must be defined');
489
+ }
490
+ return process;
491
+ };
492
+
493
+ // @ts-ignore
494
+ const signal = process => {
495
+ process.send('ready');
496
+ };
497
+
498
+ // @ts-ignore
499
+ const getActualData = (message, handle) => {
500
+ if (handle) {
501
+ return {
502
+ ...message,
503
+ params: [...message.params, handle]
504
+ };
505
+ }
506
+ return message;
507
+ };
508
+
509
+ // @ts-ignore
510
+ const wrap$4 = process => {
511
+ return {
512
+ process,
513
+ // @ts-ignore
514
+ on(event, listener) {
515
+ if (event === 'message') {
516
+ // @ts-ignore
517
+ const wrappedListener = (event, handle) => {
518
+ const actualData = getActualData(event, handle);
519
+ listener(actualData);
520
+ };
521
+ this.process.on(event, wrappedListener);
522
+ } else if (event === 'close') {
523
+ this.process.on('close', listener);
524
+ } else {
525
+ throw new Error('unsupported event type');
526
+ }
527
+ },
528
+ // @ts-ignore
529
+ off(event, listener) {
530
+ this.process.off(event, listener);
531
+ },
532
+ // @ts-ignore
533
+ send(message) {
534
+ this.process.send(message);
535
+ },
536
+ dispose() {}
537
+ };
538
+ };
539
+
540
+ const IpcChildWithNodeForkedProcess = {
541
+ __proto__: null,
542
+ listen: listen$1,
543
+ signal,
544
+ wrap: wrap$4
545
+ };
546
+
547
+ const Open = 1;
548
+ const Close = 2;
549
+
550
+ // @ts-ignore
551
+ const getFirstEvent = (eventEmitter, eventMap) => {
552
+ const {
553
+ resolve,
554
+ promise
555
+ } = withResolvers();
556
+ const listenerMap = Object.create(null);
557
+ // @ts-ignore
558
+ const cleanup = value => {
559
+ for (const event of Object.keys(eventMap)) {
560
+ eventEmitter.off(event, listenerMap[event]);
561
+ }
562
+ // @ts-ignore
563
+ resolve(value);
564
+ };
565
+ for (const [event, type] of Object.entries(eventMap)) {
566
+ // @ts-ignore
567
+ const listener = event => {
568
+ cleanup({
569
+ type,
570
+ event
571
+ });
572
+ };
573
+ eventEmitter.on(event, listener);
574
+ listenerMap[event] = listener;
575
+ }
576
+ return promise;
577
+ };
578
+
579
+ // @ts-ignore
580
+ const getFirstWebSocketEvent = async webSocket => {
581
+ // @ts-ignore
582
+ const {
583
+ WebSocket
584
+ } = await import('ws');
585
+ switch (webSocket.readyState) {
586
+ case WebSocket.OPEN:
587
+ return {
588
+ type: Open,
589
+ event: undefined
590
+ };
591
+ case WebSocket.CLOSED:
592
+ return {
593
+ type: Close,
594
+ event: undefined
595
+ };
596
+ }
597
+ // @ts-ignore
598
+ const {
599
+ type,
600
+ event
601
+ } = await getFirstEvent(webSocket, {
602
+ open: Open,
603
+ close: Close
604
+ });
605
+ return {
606
+ type,
607
+ event
608
+ };
609
+ };
610
+
611
+ // @ts-ignore
612
+ const isWebSocketOpen = async webSocket => {
613
+ // @ts-ignore
614
+ const {
615
+ WebSocket
616
+ } = await import('ws');
617
+ return webSocket.readyState === WebSocket.OPEN;
618
+ };
619
+
620
+ // @ts-ignore
621
+ const serialize = message => {
622
+ return JSON.stringify(message);
623
+ };
624
+
625
+ // @ts-ignore
626
+ const deserialize = message => {
627
+ return JSON.parse(message.toString());
628
+ };
629
+
630
+ // @ts-ignore
631
+ const handleUpgrade = async (...args) => {
632
+ const module = await import('@lvce-editor/web-socket-server');
633
+ // @ts-ignore
634
+ return module.handleUpgrade(...args);
635
+ };
636
+
637
+ // @ts-ignore
638
+ const listen = async ({
639
+ request,
640
+ handle
641
+ }) => {
642
+ if (!request) {
643
+ throw new IpcError('request must be defined');
644
+ }
645
+ if (!handle) {
646
+ throw new IpcError('handle must be defined');
647
+ }
648
+ const webSocket = await handleUpgrade(request, handle);
649
+ webSocket.pause();
650
+ if (!(await isWebSocketOpen(webSocket))) {
651
+ await getFirstWebSocketEvent(webSocket);
652
+ }
653
+ return webSocket;
654
+ };
655
+
656
+ // @ts-ignore
657
+ const wrap$3 = webSocket => {
658
+ return {
659
+ webSocket,
660
+ /**
661
+ * @type {any}
662
+ */
663
+ wrappedListener: undefined,
664
+ // @ts-ignore
665
+ on(event, listener) {
666
+ switch (event) {
667
+ case 'message':
668
+ // @ts-ignore
669
+ const wrappedListener = message => {
670
+ const data = deserialize(message);
671
+ listener(data);
672
+ };
673
+ webSocket.on('message', wrappedListener);
674
+ break;
675
+ case 'close':
676
+ webSocket.on('close', listener);
677
+ break;
678
+ default:
679
+ throw new Error('unknown event listener type');
680
+ }
681
+ },
682
+ // @ts-ignore
683
+ off(event, listener) {
684
+ this.webSocket.off(event, listener);
685
+ },
686
+ // @ts-ignore
687
+ send(message) {
688
+ const stringifiedMessage = serialize(message);
689
+ this.webSocket.send(stringifiedMessage);
690
+ },
691
+ dispose() {
692
+ this.webSocket.close();
693
+ },
694
+ start() {
695
+ this.webSocket.resume();
696
+ }
697
+ };
698
+ };
699
+
700
+ const IpcChildWithWebSocket = {
701
+ __proto__: null,
702
+ listen,
703
+ wrap: wrap$3
704
+ };
705
+
706
+ class AssertionError extends Error {
707
+ constructor(message) {
708
+ super(message);
709
+ this.name = 'AssertionError';
710
+ }
711
+ }
712
+ const getType = value => {
713
+ switch (typeof value) {
714
+ case 'number':
715
+ return 'number';
716
+ case 'function':
717
+ return 'function';
718
+ case 'string':
719
+ return 'string';
720
+ case 'object':
721
+ if (value === null) {
722
+ return 'null';
723
+ }
724
+ if (Array.isArray(value)) {
725
+ return 'array';
726
+ }
727
+ return 'object';
728
+ case 'boolean':
729
+ return 'boolean';
730
+ default:
731
+ return 'unknown';
732
+ }
733
+ };
734
+ const array = value => {
735
+ const type = getType(value);
736
+ if (type !== 'array') {
737
+ throw new AssertionError('expected value to be of type array');
738
+ }
739
+ };
740
+ const string = value => {
741
+ const type = getType(value);
742
+ if (type !== 'string') {
743
+ throw new AssertionError('expected value to be of type string');
744
+ }
745
+ };
746
+
747
+ const Exit = 1;
748
+ const Error$1 = 2;
749
+ const Message = 3;
750
+
751
+ /**
752
+ *
753
+ * @param {any} utilityProcess
754
+ * @returns
755
+ */
756
+ // @ts-ignore
757
+ const getFirstUtilityProcessEvent = async utilityProcess => {
758
+ const {
759
+ resolve,
760
+ promise
761
+ } = withResolvers();
762
+ let stdout = '';
763
+ let stderr = '';
764
+ // @ts-ignore
765
+ const cleanup = value => {
766
+ // @ts-ignore
767
+ utilityProcess.stderr.off('data', handleStdErrData);
768
+ // @ts-ignore
769
+ utilityProcess.stdout.off('data', handleStdoutData);
770
+ utilityProcess.off('message', handleMessage);
771
+ utilityProcess.off('exit', handleExit);
772
+ // @ts-ignore
773
+ resolve(value);
774
+ };
775
+ // @ts-ignore
776
+ const handleStdErrData = data => {
777
+ stderr += data;
778
+ };
779
+ // @ts-ignore
780
+ const handleStdoutData = data => {
781
+ stdout += data;
782
+ };
783
+ // @ts-ignore
784
+ const handleMessage = event => {
785
+ cleanup({
786
+ type: Message,
787
+ event,
788
+ stdout,
789
+ stderr
790
+ });
791
+ };
792
+ // @ts-ignore
793
+ const handleExit = event => {
794
+ cleanup({
795
+ type: Exit,
796
+ event,
797
+ stdout,
798
+ stderr
799
+ });
800
+ };
801
+ // @ts-ignore
802
+ utilityProcess.stderr.on('data', handleStdErrData);
803
+ // @ts-ignore
804
+ utilityProcess.stdout.on('data', handleStdoutData);
805
+ utilityProcess.on('message', handleMessage);
806
+ utilityProcess.on('exit', handleExit);
807
+ // @ts-ignore
808
+ const {
809
+ type,
810
+ event
811
+ } = await promise;
812
+ return {
813
+ type,
814
+ event,
815
+ stdout,
816
+ stderr
817
+ };
818
+ };
819
+
820
+ // @ts-ignore
821
+ const create$2 = async ({
822
+ path,
823
+ argv = [],
824
+ execArgv = [],
825
+ name
826
+ }) => {
827
+ string(path);
828
+ const actualArgv = ['--ipc-type=electron-utility-process', ...argv];
829
+ // @ts-ignore
830
+ const {
831
+ utilityProcess
832
+ } = await import('electron');
833
+ const childProcess = utilityProcess.fork(path, actualArgv, {
834
+ execArgv,
835
+ stdio: 'pipe',
836
+ serviceName: name
837
+ });
838
+ // @ts-ignore
839
+ childProcess.stdout.pipe(process.stdout);
840
+ const {
841
+ type,
842
+ event,
843
+ stdout,
844
+ stderr
845
+ } = await getFirstUtilityProcessEvent(childProcess);
846
+ if (type === Exit) {
847
+ throw new IpcError(`Utility process exited before ipc connection was established`, stdout, stderr);
848
+ }
849
+ // @ts-ignore
850
+ childProcess.stderr.pipe(process.stderr);
851
+ return childProcess;
852
+ };
853
+
854
+ // @ts-ignore
855
+ const wrap$2 = process => {
856
+ return {
857
+ process,
858
+ // @ts-ignore
859
+ on(event, listener) {
860
+ this.process.on(event, listener);
861
+ },
862
+ // @ts-ignore
863
+ send(message) {
864
+ this.process.postMessage(message);
865
+ },
866
+ // @ts-ignore
867
+ sendAndTransfer(message, transfer) {
868
+ array(transfer);
869
+ this.process.postMessage(message, transfer);
870
+ },
871
+ dispose() {
872
+ this.process.kill();
873
+ }
874
+ };
875
+ };
876
+
877
+ const IpcParentWithElectronUtilityProcess = {
878
+ __proto__: null,
879
+ create: create$2,
880
+ wrap: wrap$2
881
+ };
882
+
883
+ class ChildProcessError extends Error {
884
+ // @ts-ignore
885
+ constructor(stderr) {
886
+ // @ts-ignore
887
+ const {
888
+ message,
889
+ code,
890
+ stack
891
+ } = getHelpfulChildProcessError('', stderr);
892
+ super(message || 'child process error');
893
+ this.name = 'ChildProcessError';
894
+ if (code) {
895
+ // @ts-ignore
896
+ this.code = code;
897
+ }
898
+ if (stack) {
899
+ // @ts-ignore
900
+ const lines = splitLines(this.stack);
901
+ const [firstLine, ...stackLines] = lines;
902
+ const newStackLines = [firstLine, ...stack, ...stackLines];
903
+ const newStack = joinLines(newStackLines);
904
+ this.stack = newStack;
905
+ }
906
+ }
907
+ }
908
+
909
+ // @ts-ignore
910
+ const getFirstNodeChildProcessEvent = async childProcess => {
911
+ // @ts-ignore
912
+ const {
913
+ type,
914
+ event,
915
+ stdout,
916
+ stderr
917
+ } = await new Promise((resolve, reject) => {
918
+ let stderr = '';
919
+ let stdout = '';
920
+ // @ts-ignore
921
+ const cleanup = value => {
922
+ if (childProcess.stdout && childProcess.stderr) {
923
+ childProcess.stderr.off('data', handleStdErrData);
924
+ childProcess.stdout.off('data', handleStdoutData);
925
+ }
926
+ childProcess.off('message', handleMessage);
927
+ childProcess.off('exit', handleExit);
928
+ childProcess.off('error', handleError);
929
+ resolve(value);
930
+ };
931
+ // @ts-ignore
932
+ const handleStdErrData = data => {
933
+ stderr += data;
934
+ };
935
+ // @ts-ignore
936
+ const handleStdoutData = data => {
937
+ stdout += data;
938
+ };
939
+ // @ts-ignore
940
+ const handleMessage = event => {
941
+ cleanup({
942
+ type: Message,
943
+ event,
944
+ stdout,
945
+ stderr
946
+ });
947
+ };
948
+ // @ts-ignore
949
+ const handleExit = event => {
950
+ cleanup({
951
+ type: Exit,
952
+ event,
953
+ stdout,
954
+ stderr
955
+ });
956
+ };
957
+ // @ts-ignore
958
+ const handleError = event => {
959
+ cleanup({
960
+ type: Error$1,
961
+ event,
962
+ stdout,
963
+ stderr
964
+ });
965
+ };
966
+ if (childProcess.stdout && childProcess.stderr) {
967
+ childProcess.stderr.on('data', handleStdErrData);
968
+ childProcess.stdout.on('data', handleStdoutData);
969
+ }
970
+ childProcess.on('message', handleMessage);
971
+ childProcess.on('exit', handleExit);
972
+ childProcess.on('error', handleError);
973
+ });
974
+ return {
975
+ type,
976
+ event,
977
+ stdout,
978
+ stderr
979
+ };
980
+ };
981
+
982
+ // @ts-ignore
983
+ const create$1 = async ({
984
+ path,
985
+ argv = [],
986
+ env,
987
+ execArgv = [],
988
+ stdio = 'inherit',
989
+ name = 'child process'
990
+ }) => {
991
+ // @ts-ignore
992
+ try {
993
+ string(path);
994
+ const actualArgv = ['--ipc-type=node-forked-process', ...argv];
995
+ const {
996
+ fork
997
+ } = await import('node:child_process');
998
+ const childProcess = fork(path, actualArgv, {
999
+ env,
1000
+ execArgv,
1001
+ stdio: 'pipe'
1002
+ });
1003
+ const {
1004
+ type,
1005
+ event,
1006
+ stdout,
1007
+ stderr
1008
+ } = await getFirstNodeChildProcessEvent(childProcess);
1009
+ if (type === Exit) {
1010
+ throw new ChildProcessError(stderr);
1011
+ }
1012
+ if (type === Error$1) {
1013
+ throw new Error(`child process had an error ${event}`);
1014
+ }
1015
+ if (stdio === 'inherit' && childProcess.stdout && childProcess.stderr) {
1016
+ childProcess.stdout.pipe(process.stdout);
1017
+ childProcess.stderr.pipe(process.stderr);
1018
+ }
1019
+ return childProcess;
1020
+ } catch (error) {
1021
+ throw new VError(error, `Failed to launch ${name}`);
1022
+ }
1023
+ };
1024
+
1025
+ // @ts-ignore
1026
+ const wrap$1 = childProcess => {
1027
+ return {
1028
+ childProcess,
1029
+ // @ts-ignore
1030
+ on(event, listener) {
1031
+ this.childProcess.on(event, listener);
1032
+ },
1033
+ // @ts-ignore
1034
+ off(event, listener) {
1035
+ this.childProcess.off(event, listener);
1036
+ },
1037
+ // @ts-ignore
1038
+ send(message) {
1039
+ this.childProcess.send(message);
1040
+ },
1041
+ // @ts-ignore
1042
+ sendAndTransfer(message, handle) {
1043
+ this.childProcess.send(message, handle);
1044
+ },
1045
+ dispose() {
1046
+ this.childProcess.kill();
1047
+ },
1048
+ pid: childProcess.pid
1049
+ };
1050
+ };
1051
+
1052
+ const IpcParentWithNodeForkedProcess = {
1053
+ __proto__: null,
1054
+ create: create$1,
1055
+ wrap: wrap$1
1056
+ };
1057
+
1058
+ // @ts-ignore
1059
+ const getFirstNodeWorkerEvent = worker => {
1060
+ return getFirstEvent(worker, {
1061
+ exit: Exit,
1062
+ error: Error$1
1063
+ });
1064
+ };
1065
+
1066
+ // @ts-ignore
1067
+ const create = async ({
1068
+ path,
1069
+ argv = [],
1070
+ env = process.env,
1071
+ execArgv = []
1072
+ }) => {
1073
+ // @ts-ignore
1074
+ string(path);
1075
+ const actualArgv = ['--ipc-type=node-worker', ...argv];
1076
+ const actualEnv = {
1077
+ ...env,
1078
+ ELECTRON_RUN_AS_NODE: '1'
1079
+ };
1080
+ const {
1081
+ Worker
1082
+ } = await import('node:worker_threads');
1083
+ const worker = new Worker(path, {
1084
+ argv: actualArgv,
1085
+ env: actualEnv,
1086
+ execArgv
1087
+ });
1088
+ // @ts-ignore
1089
+ const {
1090
+ type,
1091
+ event
1092
+ } = await getFirstNodeWorkerEvent(worker);
1093
+ if (type === Exit) {
1094
+ throw new IpcError(`Worker exited before ipc connection was established`);
1095
+ }
1096
+ if (type === Error$1) {
1097
+ throw new IpcError(`Worker threw an error before ipc connection was established: ${event}`);
1098
+ }
1099
+ if (event !== 'ready') {
1100
+ throw new IpcError('unexpected first message from worker');
1101
+ }
1102
+ return worker;
1103
+ };
1104
+
1105
+ // @ts-ignore
1106
+ const wrap = worker => {
1107
+ return {
1108
+ worker,
1109
+ // @ts-ignore
1110
+ on(event, listener) {
1111
+ this.worker.on(event, listener);
1112
+ },
1113
+ // @ts-ignore
1114
+ send(message) {
1115
+ this.worker.postMessage(message);
1116
+ },
1117
+ // @ts-ignore
1118
+ sendAndTransfer(message, transfer) {
1119
+ array(transfer);
1120
+ this.worker.postMessage(message, transfer);
1121
+ },
1122
+ dispose() {
1123
+ this.worker.terminate();
1124
+ }
1125
+ };
1126
+ };
1127
+
1128
+ const IpcParentWithNodeWorker = {
1129
+ __proto__: null,
1130
+ create,
1131
+ wrap
1132
+ };
1133
+
1134
+ export { IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithModuleWorker, IpcChildWithModuleWorkerAndMessagePort, IpcChildWithNodeForkedProcess, IpcChildWithWebSocket, IpcParentWithElectronUtilityProcess, IpcParentWithNodeForkedProcess, IpcParentWithNodeWorker };
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export const IpcChildWithElectronMessagePort: IpcChild
7
7
  export const IpcChildWithElectronUtilityProcess: IpcChild
8
8
  export const IpcChildWithNodeForkedProcess: IpcChild
9
9
  export const IpcChildWithWebSocket: IpcChild
10
+ export const IpcChildWithModuleWorkerAndMessagePort: IpcChild
11
+ export const IpcChildWithModuleWorker: IpcChild
10
12
 
11
13
  interface IpcParent {
12
14
  readonly create: any
package/dist/index.js CHANGED
@@ -151,7 +151,7 @@ const isMessagePortMain = value => {
151
151
  };
152
152
 
153
153
  // @ts-ignore
154
- const listen$3 = ({
154
+ const listen$5 = ({
155
155
  messagePort
156
156
  }) => {
157
157
  if (!isMessagePortMain(messagePort)) {
@@ -176,7 +176,7 @@ const getActualData$1 = event => {
176
176
  };
177
177
 
178
178
  // @ts-ignore
179
- const wrap$6 = messagePort => {
179
+ const wrap$8 = messagePort => {
180
180
  return {
181
181
  messagePort,
182
182
  // @ts-ignore
@@ -213,8 +213,8 @@ const wrap$6 = messagePort => {
213
213
 
214
214
  const IpcChildWithElectronMessagePort = {
215
215
  __proto__: null,
216
- listen: listen$3,
217
- wrap: wrap$6
216
+ listen: listen$5,
217
+ wrap: wrap$8
218
218
  };
219
219
 
220
220
  // @ts-ignore
@@ -232,7 +232,7 @@ const getUtilityProcessPortData = event => {
232
232
  };
233
233
  };
234
234
 
235
- const listen$2 = () => {
235
+ const listen$4 = () => {
236
236
  // @ts-ignore
237
237
  const {
238
238
  parentPort
@@ -244,12 +244,12 @@ const listen$2 = () => {
244
244
  };
245
245
 
246
246
  // @ts-ignore
247
- const signal$1 = parentPort => {
247
+ const signal$2 = parentPort => {
248
248
  parentPort.postMessage('ready');
249
249
  };
250
250
 
251
251
  // @ts-ignore
252
- const wrap$5 = parentPort => {
252
+ const wrap$7 = parentPort => {
253
253
  return {
254
254
  parentPort,
255
255
  // @ts-ignore
@@ -287,8 +287,146 @@ const wrap$5 = parentPort => {
287
287
 
288
288
  const IpcChildWithElectronUtilityProcess = {
289
289
  __proto__: null,
290
- listen: listen$2,
290
+ listen: listen$4,
291
+ signal: signal$2,
292
+ wrap: wrap$7
293
+ };
294
+
295
+ const getData = event => {
296
+ return event.data;
297
+ };
298
+
299
+ const listen$3 = () => {
300
+ // @ts-ignore
301
+ if (typeof WorkerGlobalScope === 'undefined') {
302
+ throw new TypeError('module is not in web worker scope');
303
+ }
304
+ // @ts-ignore
305
+ globalThis.postMessage('ready');
306
+ return globalThis;
307
+ };
308
+ const signal$1 = global => {
309
+ global.postMessage('ready');
310
+ };
311
+ const wrap$6 = global => {
312
+ return {
313
+ global,
314
+ /**
315
+ * @type {any}
316
+ */
317
+ listener: undefined,
318
+ send(message) {
319
+ this.global.postMessage(message);
320
+ },
321
+ sendAndTransfer(message, transferables) {
322
+ this.global.postMessage(message, transferables);
323
+ },
324
+ get onmessage() {
325
+ return this.listener;
326
+ },
327
+ set onmessage(listener) {
328
+ const wrappedListener = event => {
329
+ const data = getData(event);
330
+ // @ts-expect-error
331
+ listener({
332
+ data,
333
+ target: this
334
+ });
335
+ };
336
+ this.listener = listener;
337
+ this.global.onmessage = wrappedListener;
338
+ }
339
+ };
340
+ };
341
+
342
+ const IpcChildWithModuleWorker = {
343
+ __proto__: null,
344
+ listen: listen$3,
291
345
  signal: signal$1,
346
+ wrap: wrap$6
347
+ };
348
+
349
+ const withResolvers = () => {
350
+ let _resolve;
351
+ const promise = new Promise(resolve => {
352
+ _resolve = resolve;
353
+ });
354
+ return {
355
+ resolve: _resolve,
356
+ promise
357
+ };
358
+ };
359
+
360
+ const waitForFirstMessage = async port => {
361
+ const {
362
+ resolve,
363
+ promise
364
+ } = withResolvers();
365
+ const cleanup = value => {
366
+ port.onmessage = null;
367
+ resolve(value);
368
+ };
369
+ const handleMessage = event => {
370
+ cleanup(event);
371
+ };
372
+ port.onmessage = handleMessage;
373
+ const event = await promise;
374
+ // @ts-expect-error
375
+ return event.data;
376
+ };
377
+
378
+ const listen$2 = async () => {
379
+ const parentIpcRaw = listen$3();
380
+ const parentIpc = wrap$6(parentIpcRaw);
381
+ const firstMessage = await waitForFirstMessage(parentIpc);
382
+ if (firstMessage.method !== 'initialize') {
383
+ throw new IpcError('unexpected first message');
384
+ }
385
+ const type = firstMessage.params[0];
386
+ if (type === 'message-port') {
387
+ const port = firstMessage.params[1];
388
+ return port;
389
+ }
390
+ return globalThis;
391
+ };
392
+ const wrap$5 = port => {
393
+ return {
394
+ port,
395
+ /**
396
+ * @type {any}
397
+ */
398
+ wrappedListener: undefined,
399
+ send(message) {
400
+ this.port.postMessage(message);
401
+ },
402
+ sendAndTransfer(message, transferables) {
403
+ this.port.postMessage(message, transferables);
404
+ },
405
+ get onmessage() {
406
+ return this.wrappedListener;
407
+ },
408
+ set onmessage(listener) {
409
+ if (listener) {
410
+ // @ts-expect-error
411
+ this.wrappedListener = event => {
412
+ const data = getData(event);
413
+ // @ts-expect-error
414
+ listener({
415
+ data,
416
+ target: this
417
+ });
418
+ };
419
+ } else {
420
+ this.wrappedListener = undefined;
421
+ }
422
+ this.port.onmessage = this.wrappedListener;
423
+ }
424
+ };
425
+ };
426
+
427
+ const IpcChildWithModuleWorkerAndMessagePort = {
428
+ __proto__: null,
429
+ listen: listen$2,
292
430
  wrap: wrap$5
293
431
  };
294
432
 
@@ -356,17 +494,6 @@ const IpcChildWithNodeForkedProcess = {
356
494
  const Open = 1;
357
495
  const Close = 2;
358
496
 
359
- const withResolvers = () => {
360
- let _resolve;
361
- const promise = new Promise(resolve => {
362
- _resolve = resolve;
363
- });
364
- return {
365
- resolve: _resolve,
366
- promise
367
- };
368
- };
369
-
370
497
  // @ts-ignore
371
498
  const getFirstEvent = (eventEmitter, eventMap) => {
372
499
  const {
@@ -910,4 +1037,4 @@ const IpcParentWithNodeWorker = {
910
1037
  wrap
911
1038
  };
912
1039
 
913
- export { IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithNodeForkedProcess, IpcChildWithWebSocket, IpcParentWithElectronUtilityProcess, IpcParentWithNodeForkedProcess, IpcParentWithNodeWorker };
1040
+ export { IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithModuleWorker, IpcChildWithModuleWorkerAndMessagePort, IpcChildWithNodeForkedProcess, IpcChildWithWebSocket, IpcParentWithElectronUtilityProcess, IpcParentWithNodeForkedProcess, IpcParentWithNodeWorker };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/ipc",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Inter Process Communication for Lvce Editor",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -21,5 +21,6 @@
21
21
  "engines": {
22
22
  "node": ">=18"
23
23
  },
24
- "types": "dist/index.d.ts"
24
+ "types": "dist/index.d.ts",
25
+ "browser": "dist/browser.js"
25
26
  }