@comake/skl-js-engine 1.0.9 → 1.1.1
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.
- package/dist/JsExecutor/jsExecutor.d.ts +1 -1
- package/dist/JsExecutor/jsExecutor.js.map +1 -1
- package/dist/JsExecutor/transport/StdioTransport.d.ts +0 -226
- package/dist/JsExecutor/transport/StdioTransport.js +639 -632
- package/dist/JsExecutor/transport/StdioTransport.js.map +1 -1
- package/dist/JsExecutor/transport/Transport.d.ts +2 -0
- package/dist/JsExecutor/transport/process/ProcessManager.js +27 -22
- package/dist/JsExecutor/transport/process/ProcessManager.js.map +1 -1
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.js +15 -21
- package/dist/JsExecutor/transport/stdio/ParentStdioTransport.js.map +1 -1
- package/dist/JsExecutor/transport/utils/PollingUtils.d.ts +52 -0
- package/dist/JsExecutor/transport/utils/PollingUtils.js +92 -0
- package/dist/JsExecutor/transport/utils/PollingUtils.js.map +1 -0
- package/dist/SklEngine.d.ts +0 -1
- package/dist/SklEngine.js +5 -1
- package/dist/SklEngine.js.map +1 -1
- package/dist/customCapabilities.d.ts +21 -0
- package/dist/customCapabilities.js +45 -0
- package/dist/customCapabilities.js.map +1 -0
- package/dist/examples/customCapabilitiesExample.d.ts +1 -0
- package/dist/examples/customCapabilitiesExample.js +57 -0
- package/dist/examples/customCapabilitiesExample.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/util/safeJsonStringify.d.ts +0 -5
- package/dist/util/safeJsonStringify.js +17 -17
- package/dist/util/safeJsonStringify.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,634 +1,641 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
|
|
2
|
+
// /* eslint-disable indent */
|
|
3
|
+
// /* eslint-disable no-void */
|
|
4
|
+
// /* eslint-disable @typescript-eslint/no-use-before-define */
|
|
5
|
+
// /* eslint-disable no-inline-comments */
|
|
6
|
+
// /* eslint-disable line-comment-position */
|
|
7
|
+
// /* eslint-disable @typescript-eslint/explicit-function-return-type */
|
|
8
|
+
// import type { ChildProcess } from 'child_process';
|
|
9
|
+
// import { EventEmitter } from 'node:events';
|
|
10
|
+
// import type { Readable, Writable } from 'stream';
|
|
11
|
+
// import { Logger } from '../../logger';
|
|
12
|
+
// import { DEFAULT_EXECUTION_OPTIONS, EXECUTION_CONSTANTS } from '../constants';
|
|
13
|
+
// import { spawnDenoProcess } from '../denoUtils';
|
|
14
|
+
// import { ProcessSpawnError } from '../errors';
|
|
15
|
+
// import type { ClientTransport } from '../jsonRpc/JsonRpcClient';
|
|
16
|
+
// import { JsonRpcClient } from '../jsonRpc/JsonRpcClient';
|
|
17
|
+
// import { JsonRpcServer } from '../jsonRpc/JsonRpcServer';
|
|
18
|
+
// import type {
|
|
19
|
+
// LogNotification,
|
|
20
|
+
// StatusRequest,
|
|
21
|
+
// StatusResponse
|
|
22
|
+
// } from '../jsonRpc/types';
|
|
23
|
+
// import {
|
|
24
|
+
// STANDARD_METHODS
|
|
25
|
+
// } from '../jsonRpc/types';
|
|
26
|
+
// import { buildDenoPermissions, validatePermissionConfig } from '../PermissionBuilder';
|
|
27
|
+
// import type { ExecutionOptions, PermissionConfig } from '../types';
|
|
28
|
+
// import { BaseTransport } from './base/BaseTransport';
|
|
29
|
+
// import type { Transport, TransportConfig } from './Transport';
|
|
30
|
+
// import { TransportStatus } from './Transport';
|
|
31
|
+
// /**
|
|
32
|
+
// * StdioTransport implementation using stdin/stdout for JSON-RPC communication
|
|
33
|
+
// * This is the parent-side transport that manages a child process
|
|
34
|
+
// */
|
|
35
|
+
// export class StdioTransport extends BaseTransport {
|
|
36
|
+
// private childProcess?: ChildProcess;
|
|
37
|
+
// private readonly server: JsonRpcServer;
|
|
38
|
+
// private readonly client: JsonRpcClient;
|
|
39
|
+
// private readonly clientTransport: StdioClientTransport;
|
|
40
|
+
// private readonly executorScriptPath: string;
|
|
41
|
+
// public constructor(executorScriptPath: string, server: JsonRpcServer) {
|
|
42
|
+
// super();
|
|
43
|
+
// this.executorScriptPath = executorScriptPath;
|
|
44
|
+
// this.server = server;
|
|
45
|
+
// this.client = new JsonRpcClient();
|
|
46
|
+
// this.clientTransport = new StdioClientTransport();
|
|
47
|
+
// this.setupServerMethods();
|
|
48
|
+
// this.setupEventHandlers();
|
|
49
|
+
// }
|
|
50
|
+
// /**
|
|
51
|
+
// * Initialize the transport connection
|
|
52
|
+
// */
|
|
53
|
+
// public async initialize(config?: TransportConfig, executionOptions?: ExecutionOptions): Promise<void> {
|
|
54
|
+
// if (this.status !== TransportStatus.disconnected) {
|
|
55
|
+
// throw new Error(`Cannot initialize transport in ${this.status} state`);
|
|
56
|
+
// }
|
|
57
|
+
// try {
|
|
58
|
+
// this.setStatus(TransportStatus.connecting);
|
|
59
|
+
// const normalizedOptions = this.normalizeOptions(executionOptions);
|
|
60
|
+
// const permissionConfig = this.extractPermissionConfig(normalizedOptions);
|
|
61
|
+
// // Validate permissions before proceeding
|
|
62
|
+
// validatePermissionConfig(permissionConfig);
|
|
63
|
+
// const permissions = buildDenoPermissions(permissionConfig);
|
|
64
|
+
// const mergedPermissions: string[] = [ ...EXECUTION_CONSTANTS.denoFlags ];
|
|
65
|
+
// permissions.forEach(permission => {
|
|
66
|
+
// if (!mergedPermissions.includes(permission)) {
|
|
67
|
+
// mergedPermissions.push(permission);
|
|
68
|
+
// }
|
|
69
|
+
// });
|
|
70
|
+
// // Build command arguments (will be updated when we have permission support)
|
|
71
|
+
// const commandArgs = [ ...mergedPermissions, this.executorScriptPath ];
|
|
72
|
+
// // Spawn the Deno process
|
|
73
|
+
// this.childProcess = spawnDenoProcess(commandArgs);
|
|
74
|
+
// // Set up client transport
|
|
75
|
+
// this.clientTransport.setProcess(this.childProcess.stdout!, this.childProcess.stdin!);
|
|
76
|
+
// this.client.setTransport(this.clientTransport);
|
|
77
|
+
// // Set up process communication
|
|
78
|
+
// this.setupProcessCommunication();
|
|
79
|
+
// // Wait for process to be ready
|
|
80
|
+
// await this.waitForReady(config?.timeout ?? 5000);
|
|
81
|
+
// this.setStatus(TransportStatus.connected);
|
|
82
|
+
// } catch (error: unknown) {
|
|
83
|
+
// this.setStatus(TransportStatus.error);
|
|
84
|
+
// throw error;
|
|
85
|
+
// }
|
|
86
|
+
// }
|
|
87
|
+
// /**
|
|
88
|
+
// * Normalizes execution options with defaults
|
|
89
|
+
// * @param options - Raw execution options
|
|
90
|
+
// * @returns Normalized options with all required fields
|
|
91
|
+
// */
|
|
92
|
+
// private normalizeOptions(options?: ExecutionOptions): Required<ExecutionOptions> {
|
|
93
|
+
// return {
|
|
94
|
+
// timeout: options?.timeout ?? DEFAULT_EXECUTION_OPTIONS.timeout,
|
|
95
|
+
// functionName: options?.functionName ?? DEFAULT_EXECUTION_OPTIONS.functionName,
|
|
96
|
+
// allowNetwork: options?.allowNetwork ?? DEFAULT_EXECUTION_OPTIONS.allowNetwork,
|
|
97
|
+
// allowedDomains: options?.allowedDomains ?? [ ...DEFAULT_EXECUTION_OPTIONS.allowedDomains ],
|
|
98
|
+
// allowEnv: options?.allowEnv ?? DEFAULT_EXECUTION_OPTIONS.allowEnv,
|
|
99
|
+
// allowRead: options?.allowRead ?? DEFAULT_EXECUTION_OPTIONS.allowRead,
|
|
100
|
+
// debugMode: options?.debugMode ?? DEFAULT_EXECUTION_OPTIONS.debugMode,
|
|
101
|
+
// retries: options?.retries ?? DEFAULT_EXECUTION_OPTIONS.retries
|
|
102
|
+
// };
|
|
103
|
+
// }
|
|
104
|
+
// /**
|
|
105
|
+
// * Extracts permission configuration from execution options
|
|
106
|
+
// * @param options - Normalized execution options
|
|
107
|
+
// * @returns Permission configuration object
|
|
108
|
+
// */
|
|
109
|
+
// private extractPermissionConfig(options: Required<ExecutionOptions>): PermissionConfig {
|
|
110
|
+
// return {
|
|
111
|
+
// allowNetwork: options.allowNetwork,
|
|
112
|
+
// allowedDomains: options.allowedDomains,
|
|
113
|
+
// allowEnv: options.allowEnv,
|
|
114
|
+
// allowRead: options.allowRead
|
|
115
|
+
// };
|
|
116
|
+
// }
|
|
117
|
+
// /**
|
|
118
|
+
// * Send a message through the transport
|
|
119
|
+
// */
|
|
120
|
+
// public async send<TRequest, TResponse>(message: TRequest): Promise<TResponse> {
|
|
121
|
+
// if (!this.isReady()) {
|
|
122
|
+
// throw new Error('Transport is not ready');
|
|
123
|
+
// }
|
|
124
|
+
// // Expect message to have method and params for direct RPC calls
|
|
125
|
+
// const rpcMessage = message as any;
|
|
126
|
+
// if (rpcMessage.method) {
|
|
127
|
+
// return this.client.request(rpcMessage.method, rpcMessage.params);
|
|
128
|
+
// }
|
|
129
|
+
// throw new Error('Message must have a method property for RPC calls');
|
|
130
|
+
// }
|
|
131
|
+
// /**
|
|
132
|
+
// * Make a direct RPC request to the child process
|
|
133
|
+
// */
|
|
134
|
+
// public async request<TParams = any, TResult = any>(
|
|
135
|
+
// method: string,
|
|
136
|
+
// params?: TParams,
|
|
137
|
+
// options?: { timeout?: number; retries?: number }
|
|
138
|
+
// ): Promise<TResult> {
|
|
139
|
+
// if (!this.isReady()) {
|
|
140
|
+
// throw new Error('Transport is not ready');
|
|
141
|
+
// }
|
|
142
|
+
// return this.client.request<TParams, TResult>(method, params, options);
|
|
143
|
+
// }
|
|
144
|
+
// /**
|
|
145
|
+
// * Send a notification to the child process (no response expected)
|
|
146
|
+
// */
|
|
147
|
+
// public async notify<TParams = any>(method: string, params?: TParams): Promise<void> {
|
|
148
|
+
// if (!this.isReady()) {
|
|
149
|
+
// throw new Error('Transport is not ready');
|
|
150
|
+
// }
|
|
151
|
+
// return this.client.notify(method, params);
|
|
152
|
+
// }
|
|
153
|
+
// /**
|
|
154
|
+
// * Close the transport connection
|
|
155
|
+
// */
|
|
156
|
+
// public async close(): Promise<void> {
|
|
157
|
+
// if (this.status === TransportStatus.disconnected) {
|
|
158
|
+
// return;
|
|
159
|
+
// }
|
|
160
|
+
// this.setStatus(TransportStatus.disconnected);
|
|
161
|
+
// // Close JSON-RPC client
|
|
162
|
+
// await this.client.close();
|
|
163
|
+
// // Close child process
|
|
164
|
+
// if (this.childProcess && !this.childProcess.killed) {
|
|
165
|
+
// this.childProcess.kill(EXECUTION_CONSTANTS.processSignals.term);
|
|
166
|
+
// // Wait for process to exit gracefully
|
|
167
|
+
// await new Promise<void>(resolve => {
|
|
168
|
+
// const timeout = setTimeout(() => {
|
|
169
|
+
// if (this.childProcess && !this.childProcess.killed) {
|
|
170
|
+
// this.childProcess.kill('SIGKILL');
|
|
171
|
+
// }
|
|
172
|
+
// resolve();
|
|
173
|
+
// }, 3000);
|
|
174
|
+
// this.childProcess!.on('exit', () => {
|
|
175
|
+
// clearTimeout(timeout);
|
|
176
|
+
// resolve();
|
|
177
|
+
// });
|
|
178
|
+
// });
|
|
179
|
+
// }
|
|
180
|
+
// this.childProcess = undefined;
|
|
181
|
+
// }
|
|
182
|
+
// /**
|
|
183
|
+
// * Check if the transport is ready for communication
|
|
184
|
+
// */
|
|
185
|
+
// public isReady(): boolean {
|
|
186
|
+
// return this.status === TransportStatus.connected && this.childProcess !== undefined && !this.childProcess.killed;
|
|
187
|
+
// }
|
|
188
|
+
// /**
|
|
189
|
+
// * Set up server methods for handling incoming requests from Deno process
|
|
190
|
+
// */
|
|
191
|
+
// private setupServerMethods(): void {
|
|
192
|
+
// // Handle status requests
|
|
193
|
+
// this.server.registerMethod<StatusRequest, StatusResponse>(STANDARD_METHODS.getStatus, async() => ({
|
|
194
|
+
// status: 'ready',
|
|
195
|
+
// uptime: process.uptime() * 1000,
|
|
196
|
+
// memoryUsage: {
|
|
197
|
+
// used: process.memoryUsage().heapUsed,
|
|
198
|
+
// total: process.memoryUsage().heapTotal
|
|
199
|
+
// }
|
|
200
|
+
// }));
|
|
201
|
+
// // Handle ping requests
|
|
202
|
+
// this.server.registerMethod(STANDARD_METHODS.ping, async() => 'pong');
|
|
203
|
+
// // Handle log notifications
|
|
204
|
+
// this.server.registerMethod<LogNotification, void>(STANDARD_METHODS.log, async params => {
|
|
205
|
+
// if (this.messageHandler) {
|
|
206
|
+
// await this.messageHandler(params);
|
|
207
|
+
// }
|
|
208
|
+
// });
|
|
209
|
+
// }
|
|
210
|
+
// /**
|
|
211
|
+
// * Set up event handlers
|
|
212
|
+
// */
|
|
213
|
+
// private setupEventHandlers(): void {
|
|
214
|
+
// this.server.on('error', error => {
|
|
215
|
+
// this.handleError(error, 'Server error');
|
|
216
|
+
// });
|
|
217
|
+
// this.client.on('error', error => {
|
|
218
|
+
// this.handleError(error, 'Client error');
|
|
219
|
+
// });
|
|
220
|
+
// // Add fallback error handler to prevent process crashes
|
|
221
|
+
// this.on('error', (error: Error) => {
|
|
222
|
+
// // If no one else handles the error, at least log it instead of crashing
|
|
223
|
+
// if (this.listenerCount('error') === 1) {
|
|
224
|
+
// this.logger.error('Unhandled transport error', error);
|
|
225
|
+
// }
|
|
226
|
+
// });
|
|
227
|
+
// }
|
|
228
|
+
// /**
|
|
229
|
+
// * Set up process communication handlers
|
|
230
|
+
// */
|
|
231
|
+
// private setupProcessCommunication(): void {
|
|
232
|
+
// if (!this.childProcess) {
|
|
233
|
+
// throw new Error('Child process not available');
|
|
234
|
+
// }
|
|
235
|
+
// let buffer = '';
|
|
236
|
+
// // Handle stdout data (responses from Deno process)
|
|
237
|
+
// this.childProcess.stdout?.on('data', (data: Buffer) => {
|
|
238
|
+
// buffer += data.toString();
|
|
239
|
+
// // Process complete JSON messages
|
|
240
|
+
// const lines = buffer.split('\n');
|
|
241
|
+
// buffer = lines.pop() ?? ''; // Keep incomplete line in buffer
|
|
242
|
+
// for (const line of lines) {
|
|
243
|
+
// if (line.trim()) {
|
|
244
|
+
// this.logger.log('Received message', line.trim());
|
|
245
|
+
// this.handleIncomingMessage(line.trim()).catch(error => {
|
|
246
|
+
// this.emit('error', error);
|
|
247
|
+
// });
|
|
248
|
+
// }
|
|
249
|
+
// }
|
|
250
|
+
// });
|
|
251
|
+
// // Handle stderr data (log messages and errors from Deno process)
|
|
252
|
+
// this.childProcess.stderr?.on('data', (data: Buffer) => {
|
|
253
|
+
// const stderrOutput = data.toString().trim();
|
|
254
|
+
// // Only treat messages starting with "ERROR:" as actual errors
|
|
255
|
+
// if (stderrOutput.startsWith('ERROR:')) {
|
|
256
|
+
// this.emit('error', new Error(`Deno process error: ${stderrOutput}`));
|
|
257
|
+
// } else {
|
|
258
|
+
// // Log normal stderr output as debug information
|
|
259
|
+
// this.logger.log('Child process log', stderrOutput);
|
|
260
|
+
// }
|
|
261
|
+
// });
|
|
262
|
+
// // Handle process exit
|
|
263
|
+
// this.childProcess.on('exit', (code, signal) => {
|
|
264
|
+
// if (this.status === TransportStatus.connected) {
|
|
265
|
+
// const error = new Error(`Process exited unexpectedly (code: ${code}, signal: ${signal})`);
|
|
266
|
+
// this.setStatus(TransportStatus.error);
|
|
267
|
+
// this.emit('error', error);
|
|
268
|
+
// }
|
|
269
|
+
// });
|
|
270
|
+
// // Handle process errors
|
|
271
|
+
// this.childProcess.on('error', error => {
|
|
272
|
+
// this.setStatus(TransportStatus.error);
|
|
273
|
+
// this.emit('error', new ProcessSpawnError(error));
|
|
274
|
+
// });
|
|
275
|
+
// }
|
|
276
|
+
// /**
|
|
277
|
+
// * Handle incoming message from Deno process with bidirectional routing
|
|
278
|
+
// */
|
|
279
|
+
// private async handleIncomingMessage(messageData: string): Promise<void> {
|
|
280
|
+
// try {
|
|
281
|
+
// const message = this.safeParse(messageData);
|
|
282
|
+
// if (!message) {
|
|
283
|
+
// return;
|
|
284
|
+
// }
|
|
285
|
+
// // Check if this is a response to our request (has 'result' or 'error' and 'id')
|
|
286
|
+
// if (this.isResponse(message)) {
|
|
287
|
+
// // This is a response to a request we made - route to client
|
|
288
|
+
// this.logger.log('Routing response to parent client', { id: message.id });
|
|
289
|
+
// await this.client.handleIncomingMessage(messageData);
|
|
290
|
+
// } else {
|
|
291
|
+
// // This is a request or notification for us - route to server
|
|
292
|
+
// this.logger.log('Routing request to parent server', { method: message.method, id: message.id });
|
|
293
|
+
// const response = await this.server.processMessage(messageData);
|
|
294
|
+
// this.logger.log('Sending response to parent process', response);
|
|
295
|
+
// // Only send response if there is one (requests get responses, notifications don't)
|
|
296
|
+
// if (response && this.childProcess?.stdin) {
|
|
297
|
+
// const responseData = `${JSON.stringify(response)}\n`;
|
|
298
|
+
// this.childProcess.stdin.write(responseData);
|
|
299
|
+
// }
|
|
300
|
+
// }
|
|
301
|
+
// } catch (error: unknown) {
|
|
302
|
+
// this.emit('error', new Error(`Failed to handle incoming message: ${(error as Error).message}`));
|
|
303
|
+
// }
|
|
304
|
+
// }
|
|
305
|
+
// private safeParse(message: string): any {
|
|
306
|
+
// try {
|
|
307
|
+
// return JSON.parse(message);
|
|
308
|
+
// } catch {
|
|
309
|
+
// return undefined;
|
|
310
|
+
// }
|
|
311
|
+
// }
|
|
312
|
+
// /**
|
|
313
|
+
// * Check if a message is a JSON-RPC response
|
|
314
|
+
// */
|
|
315
|
+
// private isResponse(message: any): boolean {
|
|
316
|
+
// return message &&
|
|
317
|
+
// typeof message === 'object' &&
|
|
318
|
+
// ('result' in message || 'error' in message) &&
|
|
319
|
+
// 'id' in message &&
|
|
320
|
+
// !('method' in message);
|
|
321
|
+
// }
|
|
322
|
+
// /**
|
|
323
|
+
// * Wait for the process to be ready
|
|
324
|
+
// */
|
|
325
|
+
// private async waitForReady(timeout: number): Promise<void> {
|
|
326
|
+
// return new Promise((resolve, reject) => {
|
|
327
|
+
// const timeoutId = setTimeout(() => {
|
|
328
|
+
// reject(new Error(`Transport initialization timed out after ${timeout}ms`));
|
|
329
|
+
// }, timeout);
|
|
330
|
+
// // Try to ping the process to check if it's ready
|
|
331
|
+
// const checkReady = async(): Promise<void> => {
|
|
332
|
+
// try {
|
|
333
|
+
// await this.client.request(STANDARD_METHODS.ping, undefined, { timeout: 1000 });
|
|
334
|
+
// clearTimeout(timeoutId);
|
|
335
|
+
// resolve();
|
|
336
|
+
// } catch {
|
|
337
|
+
// // Process not ready yet, try again
|
|
338
|
+
// setTimeout(checkReady, 100);
|
|
339
|
+
// }
|
|
340
|
+
// };
|
|
341
|
+
// // Start checking after a short delay to let process start
|
|
342
|
+
// setTimeout(checkReady, 100);
|
|
343
|
+
// });
|
|
344
|
+
// }
|
|
345
|
+
// }
|
|
346
|
+
// /**
|
|
347
|
+
// * Client transport implementation for stdio communication
|
|
348
|
+
// */
|
|
349
|
+
// export class StdioClientTransport implements ClientTransport {
|
|
350
|
+
// private stdout?: Readable;
|
|
351
|
+
// private stdin?: Writable;
|
|
352
|
+
// private messageHandler?: (message: string) => void;
|
|
353
|
+
// private name?: string;
|
|
354
|
+
// private readonly logger = Logger.getInstance();
|
|
355
|
+
// public setProcess(stdout: Readable, stdin: Writable): void {
|
|
356
|
+
// this.stdout = stdout;
|
|
357
|
+
// this.stdin = stdin;
|
|
358
|
+
// }
|
|
359
|
+
// public setName(name: string): void {
|
|
360
|
+
// this.name = name;
|
|
361
|
+
// this.logger.setMetadata({ name, transport: 'StdioClientTransport' });
|
|
362
|
+
// }
|
|
363
|
+
// public async send(message: string): Promise<void> {
|
|
364
|
+
// if (!this.stdin) {
|
|
365
|
+
// throw new Error('Process stdin not available');
|
|
366
|
+
// }
|
|
367
|
+
// this.logger.log('Sending message', message);
|
|
368
|
+
// this.stdin.write(`${message}\n`);
|
|
369
|
+
// }
|
|
370
|
+
// public onMessage(handler: (message: string) => void): void {
|
|
371
|
+
// this.messageHandler = handler;
|
|
372
|
+
// // Note: Message handling is done in the main StdioTransport class
|
|
373
|
+
// // This is here for interface compliance
|
|
374
|
+
// }
|
|
375
|
+
// public async close(): Promise<void> {
|
|
376
|
+
// this.stdout = undefined;
|
|
377
|
+
// this.stdin = undefined;
|
|
378
|
+
// this.messageHandler = undefined;
|
|
379
|
+
// }
|
|
380
|
+
// }
|
|
381
|
+
// /**
|
|
382
|
+
// * Bidirectional StdioTransport for child processes
|
|
383
|
+
// * This class handles both server (receiving requests) and client (sending requests) functionality
|
|
384
|
+
// * over a single stdio channel with proper message routing.
|
|
385
|
+
// *
|
|
386
|
+
// * Usage in child process:
|
|
387
|
+
// * ```typescript
|
|
388
|
+
// * const transport = new BidirectionalStdioTransport();
|
|
389
|
+
// *
|
|
390
|
+
// * // Register methods that parent can call
|
|
391
|
+
// * transport.registerMethod('ping', async () => 'pong');
|
|
392
|
+
// *
|
|
393
|
+
// * // Make requests to parent
|
|
394
|
+
// * const result = await transport.request('getTime');
|
|
395
|
+
// * ```
|
|
396
|
+
// */
|
|
397
|
+
// export class BidirectionalStdioTransport extends EventEmitter {
|
|
398
|
+
// private readonly server: JsonRpcServer;
|
|
399
|
+
// private readonly client: JsonRpcClient;
|
|
400
|
+
// private readonly logger = Logger.getInstance();
|
|
401
|
+
// private buffer = '';
|
|
402
|
+
// private name?: string;
|
|
403
|
+
// private initialized = false;
|
|
404
|
+
// public constructor() {
|
|
405
|
+
// super();
|
|
406
|
+
// this.server = new JsonRpcServer();
|
|
407
|
+
// this.client = new JsonRpcClient();
|
|
408
|
+
// // Set up the client transport that routes through our stdio
|
|
409
|
+
// const clientTransport: ClientTransport = {
|
|
410
|
+
// send: async(message: string): Promise<void> => {
|
|
411
|
+
// this.sendMessage(message);
|
|
412
|
+
// },
|
|
413
|
+
// onMessage(): void {
|
|
414
|
+
// // The message routing will handle client responses automatically
|
|
415
|
+
// },
|
|
416
|
+
// async close(): Promise<void> {
|
|
417
|
+
// // Nothing to close for stdio
|
|
418
|
+
// }
|
|
419
|
+
// };
|
|
420
|
+
// this.client.setTransport(clientTransport);
|
|
421
|
+
// this.setupEventHandlers();
|
|
422
|
+
// }
|
|
423
|
+
// /**
|
|
424
|
+
// * Set a name for this transport (used in logging)
|
|
425
|
+
// */
|
|
426
|
+
// public setName(name: string): void {
|
|
427
|
+
// this.name = name;
|
|
428
|
+
// this.logger.setMetadata({ name, transport: 'BidirectionalStdioTransport' });
|
|
429
|
+
// }
|
|
430
|
+
// /**
|
|
431
|
+
// * Initialize the bidirectional transport
|
|
432
|
+
// * This should be called once after setting up all methods
|
|
433
|
+
// */
|
|
434
|
+
// public async initialize(): Promise<void> {
|
|
435
|
+
// if (this.initialized) {
|
|
436
|
+
// throw new Error('Transport already initialized');
|
|
437
|
+
// }
|
|
438
|
+
// this.initialized = true;
|
|
439
|
+
// this.setupStdioCommunication();
|
|
440
|
+
// // Log to stderr to avoid contaminating stdout
|
|
441
|
+
// this.logger.log('Transport initialized');
|
|
442
|
+
// }
|
|
443
|
+
// /**
|
|
444
|
+
// * Register a method that the parent can call
|
|
445
|
+
// * @param method - Method name
|
|
446
|
+
// * @param handler - Method handler function
|
|
447
|
+
// */
|
|
448
|
+
// public registerMethod<TParams = any, TResult = any>(
|
|
449
|
+
// method: string,
|
|
450
|
+
// handler: (params: TParams) => Promise<TResult> | TResult
|
|
451
|
+
// ): void {
|
|
452
|
+
// this.server.registerMethod(method, handler);
|
|
453
|
+
// }
|
|
454
|
+
// /**
|
|
455
|
+
// * Send a request to the parent process
|
|
456
|
+
// * @param method - Method name
|
|
457
|
+
// * @param params - Method parameters
|
|
458
|
+
// * @param options - Request options
|
|
459
|
+
// * @returns Promise resolving to the response
|
|
460
|
+
// */
|
|
461
|
+
// public async request<TParams = any, TResult = any>(
|
|
462
|
+
// method: string,
|
|
463
|
+
// params?: TParams,
|
|
464
|
+
// options?: { timeout?: number }
|
|
465
|
+
// ): Promise<TResult> {
|
|
466
|
+
// if (!this.initialized) {
|
|
467
|
+
// throw new Error('Transport not initialized. Call initialize() first.');
|
|
468
|
+
// }
|
|
469
|
+
// return this.client.request<TParams, TResult>(method, params, options);
|
|
470
|
+
// }
|
|
471
|
+
// /**
|
|
472
|
+
// * Send a notification to the parent process (no response expected)
|
|
473
|
+
// * @param method - Method name
|
|
474
|
+
// * @param params - Method parameters
|
|
475
|
+
// */
|
|
476
|
+
// public async notify<TParams = any>(method: string, params?: TParams): Promise<void> {
|
|
477
|
+
// if (!this.initialized) {
|
|
478
|
+
// throw new Error('Transport not initialized. Call initialize() first.');
|
|
479
|
+
// }
|
|
480
|
+
// return this.client.notify(method, params);
|
|
481
|
+
// }
|
|
482
|
+
// /**
|
|
483
|
+
// * Get transport statistics
|
|
484
|
+
// */
|
|
485
|
+
// public getStats(): {
|
|
486
|
+
// serverMethods: number;
|
|
487
|
+
// pendingRequests: number;
|
|
488
|
+
// initialized: boolean;
|
|
489
|
+
// } {
|
|
490
|
+
// return {
|
|
491
|
+
// serverMethods: 0, // Server methods count not accessible due to private property
|
|
492
|
+
// pendingRequests: this.client.getStats().pendingRequests,
|
|
493
|
+
// initialized: this.initialized
|
|
494
|
+
// };
|
|
495
|
+
// }
|
|
496
|
+
// /**
|
|
497
|
+
// * Close the transport and cleanup resources
|
|
498
|
+
// */
|
|
499
|
+
// public async close(): Promise<void> {
|
|
500
|
+
// await this.client.close();
|
|
501
|
+
// this.initialized = false;
|
|
502
|
+
// this.removeAllListeners();
|
|
503
|
+
// }
|
|
504
|
+
// /**
|
|
505
|
+
// * Set up stdio communication handlers
|
|
506
|
+
// */
|
|
507
|
+
// private setupStdioCommunication(): void {
|
|
508
|
+
// // Handle incoming data from parent
|
|
509
|
+
// process.stdin.on('data', async(data: Buffer) => {
|
|
510
|
+
// this.buffer += data.toString();
|
|
511
|
+
// // Process complete JSON messages
|
|
512
|
+
// const lines = this.buffer.split('\n');
|
|
513
|
+
// this.buffer = lines.pop() ?? ''; // Keep incomplete line in buffer
|
|
514
|
+
// for (const line of lines) {
|
|
515
|
+
// if (line.trim()) {
|
|
516
|
+
// await this.handleIncomingMessage(line.trim());
|
|
517
|
+
// }
|
|
518
|
+
// }
|
|
519
|
+
// });
|
|
520
|
+
// // Handle process termination gracefully
|
|
521
|
+
// process.on('SIGTERM', () => {
|
|
522
|
+
// this.close().finally(() => process.exit(0));
|
|
523
|
+
// });
|
|
524
|
+
// process.on('SIGINT', () => {
|
|
525
|
+
// this.close().finally(() => process.exit(0));
|
|
526
|
+
// });
|
|
527
|
+
// }
|
|
528
|
+
// /**
|
|
529
|
+
// * Handle incoming message and route to appropriate handler
|
|
530
|
+
// */
|
|
531
|
+
// private async handleIncomingMessage(messageData: string): Promise<void> {
|
|
532
|
+
// try {
|
|
533
|
+
// const message = this.safeParse(messageData);
|
|
534
|
+
// if (!message) {
|
|
535
|
+
// return;
|
|
536
|
+
// }
|
|
537
|
+
// // Check if this is a response to our request (has 'result' or 'error' and 'id')
|
|
538
|
+
// if (this.isResponse(message)) {
|
|
539
|
+
// // This is a response to a request we made - route to client
|
|
540
|
+
// this.logger.log(`Routing response to client: ${message.id}`);
|
|
541
|
+
// // Manually trigger client's handleIncomingMessage
|
|
542
|
+
// await this.client.handleIncomingMessage(messageData);
|
|
543
|
+
// } else {
|
|
544
|
+
// // This is a request or notification for us - route to server
|
|
545
|
+
// this.logger.log(`Routing request to server: ${message.method}`);
|
|
546
|
+
// const response = await this.server.processMessage(messageData);
|
|
547
|
+
// this.logger.log('Sending response to parent process', response);
|
|
548
|
+
// // Only send response if there is one (requests get responses, notifications don't)
|
|
549
|
+
// if (response) {
|
|
550
|
+
// this.sendMessage(JSON.stringify(response));
|
|
551
|
+
// }
|
|
552
|
+
// }
|
|
553
|
+
// } catch (error: unknown) {
|
|
554
|
+
// process.stderr.write(`Error processing message: ${(error as Error).message}\n`);
|
|
555
|
+
// this.emit('error', error);
|
|
556
|
+
// }
|
|
557
|
+
// }
|
|
558
|
+
// private safeParse(message: string): any {
|
|
559
|
+
// try {
|
|
560
|
+
// return JSON.parse(message);
|
|
561
|
+
// } catch {
|
|
562
|
+
// return undefined;
|
|
563
|
+
// }
|
|
564
|
+
// }
|
|
565
|
+
// /**
|
|
566
|
+
// * Check if a message is a JSON-RPC response
|
|
567
|
+
// */
|
|
568
|
+
// private isResponse(message: any): boolean {
|
|
569
|
+
// return message &&
|
|
570
|
+
// typeof message === 'object' &&
|
|
571
|
+
// ('result' in message || 'error' in message) &&
|
|
572
|
+
// 'id' in message &&
|
|
573
|
+
// !('method' in message);
|
|
574
|
+
// }
|
|
575
|
+
// /**
|
|
576
|
+
// * Send a message to the parent process
|
|
577
|
+
// */
|
|
578
|
+
// private sendMessage(message: string): void {
|
|
579
|
+
// // Log to stderr to avoid contaminating stdout JSON-RPC channel
|
|
580
|
+
// this.logger.log(`Sending: ${message}`);
|
|
581
|
+
// process.stdout.write(`${message}\n`);
|
|
582
|
+
// }
|
|
583
|
+
// /**
|
|
584
|
+
// * Set up event handlers
|
|
585
|
+
// */
|
|
586
|
+
// private setupEventHandlers(): void {
|
|
587
|
+
// this.server.on('error', (error: Error) => {
|
|
588
|
+
// this.logger.error('Server error', error);
|
|
589
|
+
// this.emit('error', error);
|
|
590
|
+
// });
|
|
591
|
+
// this.client.on('error', (error: Error) => {
|
|
592
|
+
// this.logger.error('Client error', error);
|
|
593
|
+
// this.emit('error', error);
|
|
594
|
+
// });
|
|
595
|
+
// }
|
|
596
|
+
// }
|
|
597
|
+
// export class StdioServerTransport implements Transport {
|
|
598
|
+
// private readonly server: JsonRpcServer;
|
|
599
|
+
// private name?: string;
|
|
600
|
+
// private readonly logger = Logger.getInstance();
|
|
601
|
+
// public constructor(private readonly stdio: Readable, private readonly stdout: Writable, server: JsonRpcServer) {
|
|
602
|
+
// this.server = server;
|
|
603
|
+
// }
|
|
604
|
+
// public setName(name: string): void {
|
|
605
|
+
// this.name = name;
|
|
606
|
+
// this.logger.setMetadata({ name });
|
|
607
|
+
// }
|
|
608
|
+
// public get status(): TransportStatus {
|
|
609
|
+
// return TransportStatus.connected;
|
|
610
|
+
// }
|
|
611
|
+
// public isReady(): boolean {
|
|
612
|
+
// return true;
|
|
613
|
+
// }
|
|
614
|
+
// public async initialize(): Promise<void> {
|
|
615
|
+
// this.logger.log('Initializing transport');
|
|
616
|
+
// this.stdio.on('data', async(data: Buffer) => {
|
|
617
|
+
// this.logger.log('Received message', data.toString());
|
|
618
|
+
// const response = await this.server.processMessage(data.toString());
|
|
619
|
+
// await this.send(JSON.stringify(response));
|
|
620
|
+
// });
|
|
621
|
+
// }
|
|
622
|
+
// public async send<TRequest, TResponse>(message: TRequest): Promise<TResponse> {
|
|
623
|
+
// this.logger.log('Sending message', message);
|
|
624
|
+
// return new Promise<any>(resolve => {
|
|
625
|
+
// const json = JSON.stringify(message);
|
|
626
|
+
// if (this.stdout.write(json)) {
|
|
627
|
+
// resolve(undefined as unknown as TResponse);
|
|
628
|
+
// } else {
|
|
629
|
+
// this.stdout.once('drain', resolve);
|
|
630
|
+
// }
|
|
631
|
+
// });
|
|
632
|
+
// }
|
|
633
|
+
// public onMessage<T>(): void {
|
|
634
|
+
// return void 0;
|
|
635
|
+
// }
|
|
636
|
+
// public async close(): Promise<void> {
|
|
637
|
+
// this.logger.log('Closing transport');
|
|
638
|
+
// this.stdio.destroy();
|
|
639
|
+
// }
|
|
640
|
+
// }
|
|
634
641
|
//# sourceMappingURL=StdioTransport.js.map
|