@lvce-editor/ipc 2.1.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +18 -0
  3. package/dist/index.js +913 -7
  4. package/package.json +4 -3
  5. package/dist/parts/Assert/Assert.js +0 -1
  6. package/dist/parts/CamelCase/CamelCase.js +0 -11
  7. package/dist/parts/Character/Character.js +0 -12
  8. package/dist/parts/ChildProcessError/ChildProcessError.js +0 -21
  9. package/dist/parts/ErrorCodes/ErrorCodes.js +0 -22
  10. package/dist/parts/FirstNodeWorkerEventType/FirstNodeWorkerEventType.js +0 -3
  11. package/dist/parts/FirstWebSocketEventType/FirstWebSocketEventType.js +0 -2
  12. package/dist/parts/FormatUtilityProcessName/FormatUtilityProcessName.js +0 -5
  13. package/dist/parts/GetFirstEvent/GetFirstEvent.js +0 -23
  14. package/dist/parts/GetFirstNodeChildProcessEvent/GetFirstNodeChildProcessEvent.js +0 -41
  15. package/dist/parts/GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js +0 -9
  16. package/dist/parts/GetFirstUtilityProcessEvent/GetFirstUtilityProcessEvent.js +0 -42
  17. package/dist/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +0 -25
  18. package/dist/parts/GetHelpfulChildProcessError/GetHelpfulChildProcessError.js +0 -119
  19. package/dist/parts/GetUtilityProcessPortData/GetUtilityProcessPortData.js +0 -10
  20. package/dist/parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js +0 -51
  21. package/dist/parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js +0 -45
  22. package/dist/parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js +0 -46
  23. package/dist/parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js +0 -59
  24. package/dist/parts/IpcError/IpcError.js +0 -20
  25. package/dist/parts/IpcParentWithElectronUtilityProcess/IpcParentWithElectronUtilityProcess.js +0 -43
  26. package/dist/parts/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js +0 -54
  27. package/dist/parts/IpcParentWithNodeWorker/IpcParentWithNodeWorker.js +0 -49
  28. package/dist/parts/IsMessagePortMain/IsMessagePortMain.js +0 -3
  29. package/dist/parts/IsWebSocketOpen/IsWebSocketOpen.js +0 -5
  30. package/dist/parts/JoinLines/JoinLines.js +0 -5
  31. package/dist/parts/Promises/Promises.js +0 -19
  32. package/dist/parts/SplitLines/SplitLines.js +0 -5
  33. package/dist/parts/VError/VError.js +0 -1
  34. package/dist/parts/WebSocketReadyState/WebSocketReadyState.js +0 -5
  35. package/dist/parts/WebSocketSerialization/WebSocketSerialization.js +0 -7
  36. package/dist/parts/WebSocketServer/WebSocketServer.js +0 -1
package/dist/index.js CHANGED
@@ -1,7 +1,913 @@
1
- export * as IpcChildWithElectronMessagePort from './parts/IpcChildWithElectronMessagePort/IpcChildWithElectronMessagePort.js'
2
- export * as IpcChildWithElectronUtilityProcess from './parts/IpcChildWithElectronUtilityProcess/IpcChildWithElectronUtilityProcess.js'
3
- export * as IpcChildWithNodeForkedProcess from './parts/IpcChildWithNodeForkedProcess/IpcChildWithNodeForkedProcess.js'
4
- export * as IpcChildWithWebSocket from './parts/IpcChildWithWebSocket/IpcChildWithWebSocket.js'
5
- export * as IpcParentWithElectronUtilityProcess from './parts/IpcParentWithElectronUtilityProcess/IpcParentWithElectronUtilityProcess.js'
6
- export * as IpcParentWithNodeForkedProcess from './parts/IpcParentWithNodeForkedProcess/IpcParentWithNodeForkedProcess.js'
7
- export * as IpcParentWithNodeWorker from './parts/IpcParentWithNodeWorker/IpcParentWithNodeWorker.js'
1
+ import { VError } from '@lvce-editor/verror';
2
+ import { string, array } from '@lvce-editor/assert';
3
+
4
+ const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
5
+ const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
6
+ const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
7
+
8
+ const NewLine = '\n';
9
+
10
+ const joinLines = lines => {
11
+ return lines.join(NewLine);
12
+ };
13
+
14
+ const splitLines = lines => {
15
+ return lines.split(NewLine);
16
+ };
17
+
18
+ const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
19
+ const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
20
+ const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
21
+ const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
22
+ const RE_AT = /^\s+at/;
23
+ const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
24
+ const isUnhelpfulNativeModuleError = stderr => {
25
+ return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
26
+ };
27
+ const isMessageCodeBlockStartIndex = line => {
28
+ return RE_MESSAGE_CODE_BLOCK_START.test(line);
29
+ };
30
+ const isMessageCodeBlockEndIndex = line => {
31
+ return RE_MESSAGE_CODE_BLOCK_END.test(line);
32
+ };
33
+ const getMessageCodeBlock = stderr => {
34
+ const lines = splitLines(stderr);
35
+ const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
36
+ const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
37
+ const relevantLines = lines.slice(startIndex, endIndex);
38
+ const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
39
+ return relevantMessage;
40
+ };
41
+ const getNativeModuleErrorMessage = stderr => {
42
+ const message = getMessageCodeBlock(stderr);
43
+ return {
44
+ message: `Incompatible native node module: ${message}`,
45
+ code: E_INCOMPATIBLE_NATIVE_MODULE
46
+ };
47
+ };
48
+ const isModulesSyntaxError = stderr => {
49
+ if (!stderr) {
50
+ return false;
51
+ }
52
+ return stderr.includes('SyntaxError: Cannot use import statement outside a module');
53
+ };
54
+ const getModuleSyntaxError = () => {
55
+ return {
56
+ message: `ES Modules are not supported in electron`,
57
+ code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
58
+ };
59
+ };
60
+ const isModuleNotFoundError = stderr => {
61
+ if (!stderr) {
62
+ return false;
63
+ }
64
+ return stderr.includes('ERR_MODULE_NOT_FOUND');
65
+ };
66
+ const isModuleNotFoundMessage = line => {
67
+ return line.includes('ERR_MODULE_NOT_FOUND');
68
+ };
69
+ const getModuleNotFoundError = stderr => {
70
+ const lines = splitLines(stderr);
71
+ const messageIndex = lines.findIndex(isModuleNotFoundMessage);
72
+ const message = lines[messageIndex];
73
+ return {
74
+ message,
75
+ code: ERR_MODULE_NOT_FOUND
76
+ };
77
+ };
78
+ const isNormalStackLine = line => {
79
+ return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
80
+ };
81
+ const getDetails = lines => {
82
+ const index = lines.findIndex(isNormalStackLine);
83
+ if (index === -1) {
84
+ return {
85
+ actualMessage: joinLines(lines),
86
+ rest: []
87
+ };
88
+ }
89
+ let lastIndex = index - 1;
90
+ while (++lastIndex < lines.length) {
91
+ if (!isNormalStackLine(lines[lastIndex])) {
92
+ break;
93
+ }
94
+ }
95
+ return {
96
+ actualMessage: lines[index - 1],
97
+ rest: lines.slice(index, lastIndex)
98
+ };
99
+ };
100
+ const getHelpfulChildProcessError = (stdout, stderr) => {
101
+ if (isUnhelpfulNativeModuleError(stderr)) {
102
+ return getNativeModuleErrorMessage(stderr);
103
+ }
104
+ if (isModulesSyntaxError(stderr)) {
105
+ return getModuleSyntaxError();
106
+ }
107
+ if (isModuleNotFoundError(stderr)) {
108
+ return getModuleNotFoundError(stderr);
109
+ }
110
+ const lines = splitLines(stderr);
111
+ const {
112
+ actualMessage,
113
+ rest
114
+ } = getDetails(lines);
115
+ return {
116
+ message: `${actualMessage}`,
117
+ code: '',
118
+ stack: rest
119
+ };
120
+ };
121
+
122
+ class IpcError extends VError {
123
+ // @ts-ignore
124
+ constructor(message, stdout = '', stderr = '') {
125
+ if (stdout || stderr) {
126
+ // @ts-ignore
127
+ const {
128
+ message,
129
+ code,
130
+ stack
131
+ } = getHelpfulChildProcessError(stdout, stderr);
132
+ const cause = new Error(message);
133
+ // @ts-ignore
134
+ cause.code = code;
135
+ cause.stack = stack;
136
+ super(cause, message);
137
+ } else {
138
+ super(message);
139
+ }
140
+ // @ts-ignore
141
+ this.name = 'IpcError';
142
+ // @ts-ignore
143
+ this.stdout = stdout;
144
+ // @ts-ignore
145
+ this.stderr = stderr;
146
+ }
147
+ }
148
+
149
+ const isMessagePortMain = value => {
150
+ return value && value.constructor && value.constructor.name === 'MessagePortMain';
151
+ };
152
+
153
+ // @ts-ignore
154
+ const listen$3 = ({
155
+ messagePort
156
+ }) => {
157
+ if (!isMessagePortMain(messagePort)) {
158
+ throw new IpcError('port must be of type MessagePortMain');
159
+ }
160
+ return messagePort;
161
+ };
162
+
163
+ // @ts-ignore
164
+ const getActualData$1 = event => {
165
+ const {
166
+ data,
167
+ ports
168
+ } = event;
169
+ if (ports.length === 0) {
170
+ return data;
171
+ }
172
+ return {
173
+ ...data,
174
+ params: [...ports, ...data.params]
175
+ };
176
+ };
177
+
178
+ // @ts-ignore
179
+ const wrap$6 = messagePort => {
180
+ return {
181
+ messagePort,
182
+ // @ts-ignore
183
+ on(event, listener) {
184
+ if (event === 'message') {
185
+ // @ts-ignore
186
+ const wrappedListener = event => {
187
+ const actualData = getActualData$1(event);
188
+ listener(actualData);
189
+ };
190
+ this.messagePort.on(event, wrappedListener);
191
+ } else if (event === 'close') {
192
+ this.messagePort.on('close', listener);
193
+ } else {
194
+ throw new Error('unsupported event type');
195
+ }
196
+ },
197
+ // @ts-ignore
198
+ off(event, listener) {
199
+ this.messagePort.off(event, listener);
200
+ },
201
+ // @ts-ignore
202
+ send(message) {
203
+ this.messagePort.postMessage(message);
204
+ },
205
+ dispose() {
206
+ this.messagePort.close();
207
+ },
208
+ start() {
209
+ this.messagePort.start();
210
+ }
211
+ };
212
+ };
213
+
214
+ const IpcChildWithElectronMessagePort = {
215
+ __proto__: null,
216
+ listen: listen$3,
217
+ wrap: wrap$6
218
+ };
219
+
220
+ // @ts-ignore
221
+ const getUtilityProcessPortData = event => {
222
+ const {
223
+ data,
224
+ ports
225
+ } = event;
226
+ if (ports.length === 0) {
227
+ return data;
228
+ }
229
+ return {
230
+ ...data,
231
+ params: [...ports, ...data.params]
232
+ };
233
+ };
234
+
235
+ const listen$2 = () => {
236
+ // @ts-ignore
237
+ const {
238
+ parentPort
239
+ } = process;
240
+ if (!parentPort) {
241
+ throw new Error('parent port must be defined');
242
+ }
243
+ return parentPort;
244
+ };
245
+
246
+ // @ts-ignore
247
+ const signal$1 = parentPort => {
248
+ parentPort.postMessage('ready');
249
+ };
250
+
251
+ // @ts-ignore
252
+ const wrap$5 = parentPort => {
253
+ return {
254
+ parentPort,
255
+ // @ts-ignore
256
+ on(event, listener) {
257
+ if (event === 'message') {
258
+ // @ts-ignore
259
+ const wrappedListener = event => {
260
+ const actualData = getUtilityProcessPortData(event);
261
+ listener(actualData);
262
+ };
263
+ this.parentPort.on(event, wrappedListener);
264
+ } else if (event === 'close') {
265
+ this.parentPort.on('close', listener);
266
+ } else {
267
+ throw new Error('unsupported event type');
268
+ }
269
+ },
270
+ // @ts-ignore
271
+ off(event, listener) {
272
+ this.parentPort.off(event, listener);
273
+ },
274
+ // @ts-ignore
275
+ send(message) {
276
+ this.parentPort.postMessage(message);
277
+ },
278
+ // @ts-ignore
279
+ sendAndTransfer(message, transfer) {
280
+ this.parentPort.postMessage(message, transfer);
281
+ },
282
+ dispose() {
283
+ this.parentPort.close();
284
+ }
285
+ };
286
+ };
287
+
288
+ const IpcChildWithElectronUtilityProcess = {
289
+ __proto__: null,
290
+ listen: listen$2,
291
+ signal: signal$1,
292
+ wrap: wrap$5
293
+ };
294
+
295
+ const listen$1 = async () => {
296
+ if (!process.send) {
297
+ throw new Error('process.send must be defined');
298
+ }
299
+ return process;
300
+ };
301
+
302
+ // @ts-ignore
303
+ const signal = process => {
304
+ process.send('ready');
305
+ };
306
+
307
+ // @ts-ignore
308
+ const getActualData = (message, handle) => {
309
+ if (handle) {
310
+ return {
311
+ ...message,
312
+ params: [...message.params, handle]
313
+ };
314
+ }
315
+ return message;
316
+ };
317
+
318
+ // @ts-ignore
319
+ const wrap$4 = process => {
320
+ return {
321
+ process,
322
+ // @ts-ignore
323
+ on(event, listener) {
324
+ if (event === 'message') {
325
+ // @ts-ignore
326
+ const wrappedListener = (event, handle) => {
327
+ const actualData = getActualData(event, handle);
328
+ listener(actualData);
329
+ };
330
+ this.process.on(event, wrappedListener);
331
+ } else if (event === 'close') {
332
+ this.process.on('close', listener);
333
+ } else {
334
+ throw new Error('unsupported event type');
335
+ }
336
+ },
337
+ // @ts-ignore
338
+ off(event, listener) {
339
+ this.process.off(event, listener);
340
+ },
341
+ // @ts-ignore
342
+ send(message) {
343
+ this.process.send(message);
344
+ },
345
+ dispose() {}
346
+ };
347
+ };
348
+
349
+ const IpcChildWithNodeForkedProcess = {
350
+ __proto__: null,
351
+ listen: listen$1,
352
+ signal,
353
+ wrap: wrap$4
354
+ };
355
+
356
+ const Open = 1;
357
+ const Close = 2;
358
+
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
+ // @ts-ignore
371
+ const getFirstEvent = (eventEmitter, eventMap) => {
372
+ const {
373
+ resolve,
374
+ promise
375
+ } = withResolvers();
376
+ const listenerMap = Object.create(null);
377
+ // @ts-ignore
378
+ const cleanup = value => {
379
+ for (const event of Object.keys(eventMap)) {
380
+ eventEmitter.off(event, listenerMap[event]);
381
+ }
382
+ // @ts-ignore
383
+ resolve(value);
384
+ };
385
+ for (const [event, type] of Object.entries(eventMap)) {
386
+ // @ts-ignore
387
+ const listener = event => {
388
+ cleanup({
389
+ type,
390
+ event
391
+ });
392
+ };
393
+ eventEmitter.on(event, listener);
394
+ listenerMap[event] = listener;
395
+ }
396
+ return promise;
397
+ };
398
+
399
+ // @ts-ignore
400
+ const getFirstWebSocketEvent = async webSocket => {
401
+ // @ts-ignore
402
+ const {
403
+ WebSocket
404
+ } = await import('ws');
405
+ switch (webSocket.readyState) {
406
+ case WebSocket.OPEN:
407
+ return {
408
+ type: Open,
409
+ event: undefined
410
+ };
411
+ case WebSocket.CLOSED:
412
+ return {
413
+ type: Close,
414
+ event: undefined
415
+ };
416
+ }
417
+ // @ts-ignore
418
+ const {
419
+ type,
420
+ event
421
+ } = await getFirstEvent(webSocket, {
422
+ open: Open,
423
+ close: Close
424
+ });
425
+ return {
426
+ type,
427
+ event
428
+ };
429
+ };
430
+
431
+ // @ts-ignore
432
+ const isWebSocketOpen = async webSocket => {
433
+ // @ts-ignore
434
+ const {
435
+ WebSocket
436
+ } = await import('ws');
437
+ return webSocket.readyState === WebSocket.OPEN;
438
+ };
439
+
440
+ // @ts-ignore
441
+ const serialize = message => {
442
+ return JSON.stringify(message);
443
+ };
444
+
445
+ // @ts-ignore
446
+ const deserialize = message => {
447
+ return JSON.parse(message.toString());
448
+ };
449
+
450
+ // @ts-ignore
451
+ const handleUpgrade = async (...args) => {
452
+ const module = await import('@lvce-editor/web-socket-server');
453
+ // @ts-ignore
454
+ return module.handleUpgrade(...args);
455
+ };
456
+
457
+ // @ts-ignore
458
+ const listen = async ({
459
+ request,
460
+ handle
461
+ }) => {
462
+ if (!request) {
463
+ throw new IpcError('request must be defined');
464
+ }
465
+ if (!handle) {
466
+ throw new IpcError('handle must be defined');
467
+ }
468
+ const webSocket = await handleUpgrade(request, handle);
469
+ webSocket.pause();
470
+ if (!(await isWebSocketOpen(webSocket))) {
471
+ await getFirstWebSocketEvent(webSocket);
472
+ }
473
+ return webSocket;
474
+ };
475
+
476
+ // @ts-ignore
477
+ const wrap$3 = webSocket => {
478
+ return {
479
+ webSocket,
480
+ /**
481
+ * @type {any}
482
+ */
483
+ wrappedListener: undefined,
484
+ // @ts-ignore
485
+ on(event, listener) {
486
+ switch (event) {
487
+ case 'message':
488
+ // @ts-ignore
489
+ const wrappedListener = message => {
490
+ const data = deserialize(message);
491
+ listener(data);
492
+ };
493
+ webSocket.on('message', wrappedListener);
494
+ break;
495
+ case 'close':
496
+ webSocket.on('close', listener);
497
+ break;
498
+ default:
499
+ throw new Error('unknown event listener type');
500
+ }
501
+ },
502
+ // @ts-ignore
503
+ off(event, listener) {
504
+ this.webSocket.off(event, listener);
505
+ },
506
+ // @ts-ignore
507
+ send(message) {
508
+ const stringifiedMessage = serialize(message);
509
+ this.webSocket.send(stringifiedMessage);
510
+ },
511
+ dispose() {
512
+ this.webSocket.close();
513
+ },
514
+ start() {
515
+ this.webSocket.resume();
516
+ }
517
+ };
518
+ };
519
+
520
+ const IpcChildWithWebSocket = {
521
+ __proto__: null,
522
+ listen,
523
+ wrap: wrap$3
524
+ };
525
+
526
+ const Exit = 1;
527
+ const Error$1 = 2;
528
+ const Message = 3;
529
+
530
+ /**
531
+ *
532
+ * @param {any} utilityProcess
533
+ * @returns
534
+ */
535
+ // @ts-ignore
536
+ const getFirstUtilityProcessEvent = async utilityProcess => {
537
+ const {
538
+ resolve,
539
+ promise
540
+ } = withResolvers();
541
+ let stdout = '';
542
+ let stderr = '';
543
+ // @ts-ignore
544
+ const cleanup = value => {
545
+ // @ts-ignore
546
+ utilityProcess.stderr.off('data', handleStdErrData);
547
+ // @ts-ignore
548
+ utilityProcess.stdout.off('data', handleStdoutData);
549
+ utilityProcess.off('message', handleMessage);
550
+ utilityProcess.off('exit', handleExit);
551
+ // @ts-ignore
552
+ resolve(value);
553
+ };
554
+ // @ts-ignore
555
+ const handleStdErrData = data => {
556
+ stderr += data;
557
+ };
558
+ // @ts-ignore
559
+ const handleStdoutData = data => {
560
+ stdout += data;
561
+ };
562
+ // @ts-ignore
563
+ const handleMessage = event => {
564
+ cleanup({
565
+ type: Message,
566
+ event,
567
+ stdout,
568
+ stderr
569
+ });
570
+ };
571
+ // @ts-ignore
572
+ const handleExit = event => {
573
+ cleanup({
574
+ type: Exit,
575
+ event,
576
+ stdout,
577
+ stderr
578
+ });
579
+ };
580
+ // @ts-ignore
581
+ utilityProcess.stderr.on('data', handleStdErrData);
582
+ // @ts-ignore
583
+ utilityProcess.stdout.on('data', handleStdoutData);
584
+ utilityProcess.on('message', handleMessage);
585
+ utilityProcess.on('exit', handleExit);
586
+ // @ts-ignore
587
+ const {
588
+ type,
589
+ event
590
+ } = await promise;
591
+ return {
592
+ type,
593
+ event,
594
+ stdout,
595
+ stderr
596
+ };
597
+ };
598
+
599
+ // @ts-ignore
600
+ const create$2 = async ({
601
+ path,
602
+ argv = [],
603
+ execArgv = [],
604
+ name
605
+ }) => {
606
+ string(path);
607
+ const actualArgv = ['--ipc-type=electron-utility-process', ...argv];
608
+ // @ts-ignore
609
+ const {
610
+ utilityProcess
611
+ } = await import('electron');
612
+ const childProcess = utilityProcess.fork(path, actualArgv, {
613
+ execArgv,
614
+ stdio: 'pipe',
615
+ serviceName: name
616
+ });
617
+ // @ts-ignore
618
+ childProcess.stdout.pipe(process.stdout);
619
+ const {
620
+ type,
621
+ event,
622
+ stdout,
623
+ stderr
624
+ } = await getFirstUtilityProcessEvent(childProcess);
625
+ if (type === Exit) {
626
+ throw new IpcError(`Utility process exited before ipc connection was established`, stdout, stderr);
627
+ }
628
+ // @ts-ignore
629
+ childProcess.stderr.pipe(process.stderr);
630
+ return childProcess;
631
+ };
632
+
633
+ // @ts-ignore
634
+ const wrap$2 = process => {
635
+ return {
636
+ process,
637
+ // @ts-ignore
638
+ on(event, listener) {
639
+ this.process.on(event, listener);
640
+ },
641
+ // @ts-ignore
642
+ send(message) {
643
+ this.process.postMessage(message);
644
+ },
645
+ // @ts-ignore
646
+ sendAndTransfer(message, transfer) {
647
+ array(transfer);
648
+ this.process.postMessage(message, transfer);
649
+ },
650
+ dispose() {
651
+ this.process.kill();
652
+ }
653
+ };
654
+ };
655
+
656
+ const IpcParentWithElectronUtilityProcess = {
657
+ __proto__: null,
658
+ create: create$2,
659
+ wrap: wrap$2
660
+ };
661
+
662
+ class ChildProcessError extends Error {
663
+ // @ts-ignore
664
+ constructor(stderr) {
665
+ // @ts-ignore
666
+ const {
667
+ message,
668
+ code,
669
+ stack
670
+ } = getHelpfulChildProcessError('', stderr);
671
+ super(message || 'child process error');
672
+ this.name = 'ChildProcessError';
673
+ if (code) {
674
+ // @ts-ignore
675
+ this.code = code;
676
+ }
677
+ if (stack) {
678
+ // @ts-ignore
679
+ const lines = splitLines(this.stack);
680
+ const [firstLine, ...stackLines] = lines;
681
+ const newStackLines = [firstLine, ...stack, ...stackLines];
682
+ const newStack = joinLines(newStackLines);
683
+ this.stack = newStack;
684
+ }
685
+ }
686
+ }
687
+
688
+ // @ts-ignore
689
+ const getFirstNodeChildProcessEvent = async childProcess => {
690
+ // @ts-ignore
691
+ const {
692
+ type,
693
+ event,
694
+ stdout,
695
+ stderr
696
+ } = await new Promise((resolve, reject) => {
697
+ let stderr = '';
698
+ let stdout = '';
699
+ // @ts-ignore
700
+ const cleanup = value => {
701
+ if (childProcess.stdout && childProcess.stderr) {
702
+ childProcess.stderr.off('data', handleStdErrData);
703
+ childProcess.stdout.off('data', handleStdoutData);
704
+ }
705
+ childProcess.off('message', handleMessage);
706
+ childProcess.off('exit', handleExit);
707
+ childProcess.off('error', handleError);
708
+ resolve(value);
709
+ };
710
+ // @ts-ignore
711
+ const handleStdErrData = data => {
712
+ stderr += data;
713
+ };
714
+ // @ts-ignore
715
+ const handleStdoutData = data => {
716
+ stdout += data;
717
+ };
718
+ // @ts-ignore
719
+ const handleMessage = event => {
720
+ cleanup({
721
+ type: Message,
722
+ event,
723
+ stdout,
724
+ stderr
725
+ });
726
+ };
727
+ // @ts-ignore
728
+ const handleExit = event => {
729
+ cleanup({
730
+ type: Exit,
731
+ event,
732
+ stdout,
733
+ stderr
734
+ });
735
+ };
736
+ // @ts-ignore
737
+ const handleError = event => {
738
+ cleanup({
739
+ type: Error$1,
740
+ event,
741
+ stdout,
742
+ stderr
743
+ });
744
+ };
745
+ if (childProcess.stdout && childProcess.stderr) {
746
+ childProcess.stderr.on('data', handleStdErrData);
747
+ childProcess.stdout.on('data', handleStdoutData);
748
+ }
749
+ childProcess.on('message', handleMessage);
750
+ childProcess.on('exit', handleExit);
751
+ childProcess.on('error', handleError);
752
+ });
753
+ return {
754
+ type,
755
+ event,
756
+ stdout,
757
+ stderr
758
+ };
759
+ };
760
+
761
+ // @ts-ignore
762
+ const create$1 = async ({
763
+ path,
764
+ argv = [],
765
+ env,
766
+ execArgv = [],
767
+ stdio = 'inherit',
768
+ name = 'child process'
769
+ }) => {
770
+ // @ts-ignore
771
+ try {
772
+ string(path);
773
+ const actualArgv = ['--ipc-type=node-forked-process', ...argv];
774
+ const {
775
+ fork
776
+ } = await import('node:child_process');
777
+ const childProcess = fork(path, actualArgv, {
778
+ env,
779
+ execArgv,
780
+ stdio: 'pipe'
781
+ });
782
+ const {
783
+ type,
784
+ event,
785
+ stdout,
786
+ stderr
787
+ } = await getFirstNodeChildProcessEvent(childProcess);
788
+ if (type === Exit) {
789
+ throw new ChildProcessError(stderr);
790
+ }
791
+ if (type === Error$1) {
792
+ throw new Error(`child process had an error ${event}`);
793
+ }
794
+ if (stdio === 'inherit' && childProcess.stdout && childProcess.stderr) {
795
+ childProcess.stdout.pipe(process.stdout);
796
+ childProcess.stderr.pipe(process.stderr);
797
+ }
798
+ return childProcess;
799
+ } catch (error) {
800
+ throw new VError(error, `Failed to launch ${name}`);
801
+ }
802
+ };
803
+
804
+ // @ts-ignore
805
+ const wrap$1 = childProcess => {
806
+ return {
807
+ childProcess,
808
+ // @ts-ignore
809
+ on(event, listener) {
810
+ this.childProcess.on(event, listener);
811
+ },
812
+ // @ts-ignore
813
+ off(event, listener) {
814
+ this.childProcess.off(event, listener);
815
+ },
816
+ // @ts-ignore
817
+ send(message) {
818
+ this.childProcess.send(message);
819
+ },
820
+ // @ts-ignore
821
+ sendAndTransfer(message, handle) {
822
+ this.childProcess.send(message, handle);
823
+ },
824
+ dispose() {
825
+ this.childProcess.kill();
826
+ },
827
+ pid: childProcess.pid
828
+ };
829
+ };
830
+
831
+ const IpcParentWithNodeForkedProcess = {
832
+ __proto__: null,
833
+ create: create$1,
834
+ wrap: wrap$1
835
+ };
836
+
837
+ // @ts-ignore
838
+ const getFirstNodeWorkerEvent = worker => {
839
+ return getFirstEvent(worker, {
840
+ exit: Exit,
841
+ error: Error$1
842
+ });
843
+ };
844
+
845
+ // @ts-ignore
846
+ const create = async ({
847
+ path,
848
+ argv = [],
849
+ env = process.env,
850
+ execArgv = []
851
+ }) => {
852
+ // @ts-ignore
853
+ string(path);
854
+ const actualArgv = ['--ipc-type=node-worker', ...argv];
855
+ const actualEnv = {
856
+ ...env,
857
+ ELECTRON_RUN_AS_NODE: '1'
858
+ };
859
+ const {
860
+ Worker
861
+ } = await import('node:worker_threads');
862
+ const worker = new Worker(path, {
863
+ argv: actualArgv,
864
+ env: actualEnv,
865
+ execArgv
866
+ });
867
+ // @ts-ignore
868
+ const {
869
+ type,
870
+ event
871
+ } = await getFirstNodeWorkerEvent(worker);
872
+ if (type === Exit) {
873
+ throw new IpcError(`Worker exited before ipc connection was established`);
874
+ }
875
+ if (type === Error$1) {
876
+ throw new IpcError(`Worker threw an error before ipc connection was established: ${event}`);
877
+ }
878
+ if (event !== 'ready') {
879
+ throw new IpcError('unexpected first message from worker');
880
+ }
881
+ return worker;
882
+ };
883
+
884
+ // @ts-ignore
885
+ const wrap = worker => {
886
+ return {
887
+ worker,
888
+ // @ts-ignore
889
+ on(event, listener) {
890
+ this.worker.on(event, listener);
891
+ },
892
+ // @ts-ignore
893
+ send(message) {
894
+ this.worker.postMessage(message);
895
+ },
896
+ // @ts-ignore
897
+ sendAndTransfer(message, transfer) {
898
+ array(transfer);
899
+ this.worker.postMessage(message, transfer);
900
+ },
901
+ dispose() {
902
+ this.worker.terminate();
903
+ }
904
+ };
905
+ };
906
+
907
+ const IpcParentWithNodeWorker = {
908
+ __proto__: null,
909
+ create,
910
+ wrap
911
+ };
912
+
913
+ export { IpcChildWithElectronMessagePort, IpcChildWithElectronUtilityProcess, IpcChildWithNodeForkedProcess, IpcChildWithWebSocket, IpcParentWithElectronUtilityProcess, IpcParentWithNodeForkedProcess, IpcParentWithNodeWorker };