@dxos/rpc 0.8.3 → 0.8.4-main.84f28bd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,934 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var node_exports = {};
20
- __export(node_exports, {
21
- PortTracer: () => PortTracer,
22
- ProtoRpcPeer: () => ProtoRpcPeer,
23
- RpcPeer: () => RpcPeer,
24
- createBundledRpcClient: () => createBundledRpcClient,
25
- createBundledRpcServer: () => createBundledRpcServer,
26
- createLinkedPorts: () => createLinkedPorts,
27
- createProtoRpcPeer: () => createProtoRpcPeer,
28
- createRpcClient: () => createRpcClient,
29
- createRpcServer: () => createRpcServer,
30
- createServiceBundle: () => createServiceBundle,
31
- decodeRpcError: () => decodeRpcError,
32
- encodeMessage: () => encodeMessage,
33
- parseMethodName: () => parseMethodName
34
- });
35
- module.exports = __toCommonJS(node_exports);
36
- var import_async = require("@dxos/async");
37
- var import_codec_protobuf = require("@dxos/codec-protobuf");
38
- var import_debug = require("@dxos/debug");
39
- var import_invariant = require("@dxos/invariant");
40
- var import_log = require("@dxos/log");
41
- var import_protocols = require("@dxos/protocols");
42
- var import_proto = require("@dxos/protocols/proto");
43
- var import_util = require("@dxos/util");
44
- var import_debug2 = require("@dxos/debug");
45
- var import_protocols2 = require("@dxos/protocols");
46
- var import_invariant2 = require("@dxos/invariant");
47
- var import_util2 = require("@dxos/util");
48
- var import_async2 = require("@dxos/async");
49
- var import_rpc = require("@dxos/protocols/proto/dxos/rpc");
50
- var decodeRpcError = (err, rpcMethod) => (0, import_protocols2.decodeError)(err, {
51
- appendStack: `
52
- at RPC ${rpcMethod}
53
- ` + new import_debug2.StackTrace().getStack(1)
54
- });
55
- function _ts_decorate(decorators, target, key, desc) {
56
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
57
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
58
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
59
- return c > 3 && r && Object.defineProperty(target, key, r), r;
60
- }
61
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/rpc/src/rpc.ts";
62
- var DEFAULT_TIMEOUT = 3e3;
63
- var BYE_SEND_TIMEOUT = 2e3;
64
- var DEBUG_CALLS = true;
65
- var CLOSE_TIMEOUT = 3e3;
66
- var PendingRpcRequest = class {
67
- constructor(resolve, reject, stream) {
68
- this.resolve = resolve;
69
- this.reject = reject;
70
- this.stream = stream;
71
- }
72
- };
73
- var RpcMessageCodec;
74
- var getRpcMessageCodec = () => RpcMessageCodec ??= import_proto.schema.getCodecForType("dxos.rpc.RpcMessage");
75
- var RpcPeer = class {
76
- constructor(params) {
77
- this._outgoingRequests = /* @__PURE__ */ new Map();
78
- this._localStreams = /* @__PURE__ */ new Map();
79
- this._remoteOpenTrigger = new import_async.Trigger();
80
- this._closingTrigger = new import_async.Trigger();
81
- this._byeTrigger = new import_async.Trigger();
82
- this._nextId = 0;
83
- this._state = "INITIAL";
84
- this._unsubscribeFromPort = void 0;
85
- this._clearOpenInterval = void 0;
86
- this._params = {
87
- timeout: void 0,
88
- streamHandler: void 0,
89
- noHandshake: false,
90
- ...params
91
- };
92
- }
93
- /**
94
- * Open the peer. Required before making any calls.
95
- *
96
- * Will block before the other peer calls `open`.
97
- */
98
- async open() {
99
- if (this._state !== "INITIAL") {
100
- return;
101
- }
102
- this._unsubscribeFromPort = this._params.port.subscribe(async (msg) => {
103
- try {
104
- await this._receive(msg);
105
- } catch (err) {
106
- import_log.log.catch(err, void 0, {
107
- F: __dxlog_file,
108
- L: 156,
109
- S: this,
110
- C: (f, a) => f(...a)
111
- });
112
- }
113
- });
114
- this._state = "OPENING";
115
- if (this._params.noHandshake) {
116
- this._state = "OPENED";
117
- this._remoteOpenTrigger.wake();
118
- return;
119
- }
120
- (0, import_log.log)("sending open message", {
121
- state: this._state
122
- }, {
123
- F: __dxlog_file,
124
- L: 168,
125
- S: this,
126
- C: (f, a) => f(...a)
127
- });
128
- await this._sendMessage({
129
- open: true
130
- });
131
- if (this._state !== "OPENING") {
132
- return;
133
- }
134
- this._clearOpenInterval = (0, import_util.exponentialBackoffInterval)(() => {
135
- void this._sendMessage({
136
- open: true
137
- }).catch((err) => import_log.log.warn(err, void 0, {
138
- F: __dxlog_file,
139
- L: 177,
140
- S: this,
141
- C: (f, a) => f(...a)
142
- }));
143
- }, 50);
144
- await Promise.race([
145
- this._remoteOpenTrigger.wait(),
146
- this._closingTrigger.wait()
147
- ]);
148
- this._clearOpenInterval?.();
149
- if (this._state !== "OPENED") {
150
- return;
151
- }
152
- (0, import_log.log)("resending open message", {
153
- state: this._state
154
- }, {
155
- F: __dxlog_file,
156
- L: 191,
157
- S: this,
158
- C: (f, a) => f(...a)
159
- });
160
- await this._sendMessage({
161
- openAck: true
162
- });
163
- }
164
- /**
165
- * Close the peer.
166
- * Stop taking or making requests.
167
- * Will wait for confirmation from the other side.
168
- * Any responses for RPC calls made before close will be delivered.
169
- */
170
- async close({ timeout = CLOSE_TIMEOUT } = {}) {
171
- if (this._state === "CLOSED") {
172
- return;
173
- }
174
- this._abortRequests();
175
- if (this._state === "OPENED" && !this._params.noHandshake) {
176
- try {
177
- this._state = "CLOSING";
178
- await this._sendMessage({
179
- bye: {}
180
- }, BYE_SEND_TIMEOUT);
181
- } catch (err) {
182
- (0, import_log.log)("error closing peer, sending bye", {
183
- err
184
- }, {
185
- F: __dxlog_file,
186
- L: 213,
187
- S: this,
188
- C: (f, a) => f(...a)
189
- });
190
- }
191
- try {
192
- (0, import_log.log)("closing waiting on bye", void 0, {
193
- F: __dxlog_file,
194
- L: 216,
195
- S: this,
196
- C: (f, a) => f(...a)
197
- });
198
- await this._byeTrigger.wait({
199
- timeout
200
- });
201
- } catch (err) {
202
- (0, import_log.log)("error closing peer", {
203
- err
204
- }, {
205
- F: __dxlog_file,
206
- L: 219,
207
- S: this,
208
- C: (f, a) => f(...a)
209
- });
210
- return;
211
- }
212
- }
213
- this._disposeAndClose();
214
- }
215
- /**
216
- * Dispose the connection without waiting for the other side.
217
- */
218
- async abort() {
219
- if (this._state === "CLOSED") {
220
- return;
221
- }
222
- this._abortRequests();
223
- this._disposeAndClose();
224
- }
225
- _abortRequests() {
226
- this._clearOpenInterval?.();
227
- this._closingTrigger.wake();
228
- for (const req of this._outgoingRequests.values()) {
229
- req.reject(new import_protocols.RpcClosedError());
230
- }
231
- this._outgoingRequests.clear();
232
- }
233
- _disposeAndClose() {
234
- this._unsubscribeFromPort?.();
235
- this._unsubscribeFromPort = void 0;
236
- this._clearOpenInterval?.();
237
- this._state = "CLOSED";
238
- }
239
- /**
240
- * Handle incoming message. Should be called as the result of other peer's `send` callback.
241
- */
242
- async _receive(msg) {
243
- const decoded = getRpcMessageCodec().decode(msg, {
244
- preserveAny: true
245
- });
246
- DEBUG_CALLS && (0, import_log.log)("received message", {
247
- type: Object.keys(decoded)[0]
248
- }, {
249
- F: __dxlog_file,
250
- L: 263,
251
- S: this,
252
- C: (f, a) => f(...a)
253
- });
254
- if (decoded.request) {
255
- if (this._state !== "OPENED" && this._state !== "OPENING") {
256
- (0, import_log.log)("received request while closed", void 0, {
257
- F: __dxlog_file,
258
- L: 267,
259
- S: this,
260
- C: (f, a) => f(...a)
261
- });
262
- await this._sendMessage({
263
- response: {
264
- id: decoded.request.id,
265
- error: (0, import_protocols.encodeError)(new import_protocols.RpcClosedError())
266
- }
267
- });
268
- return;
269
- }
270
- const req = decoded.request;
271
- if (req.stream) {
272
- (0, import_log.log)("stream request", {
273
- method: req.method
274
- }, {
275
- F: __dxlog_file,
276
- L: 279,
277
- S: this,
278
- C: (f, a) => f(...a)
279
- });
280
- this._callStreamHandler(req, (response) => {
281
- (0, import_log.log)("sending stream response", {
282
- method: req.method,
283
- response: response.payload?.type_url,
284
- error: response.error,
285
- close: response.close
286
- }, {
287
- F: __dxlog_file,
288
- L: 281,
289
- S: this,
290
- C: (f, a) => f(...a)
291
- });
292
- void this._sendMessage({
293
- response
294
- }).catch((err) => {
295
- import_log.log.warn("failed during close", err, {
296
- F: __dxlog_file,
297
- L: 289,
298
- S: this,
299
- C: (f, a) => f(...a)
300
- });
301
- });
302
- });
303
- } else {
304
- DEBUG_CALLS && (0, import_log.log)("requesting...", {
305
- method: req.method
306
- }, {
307
- F: __dxlog_file,
308
- L: 293,
309
- S: this,
310
- C: (f, a) => f(...a)
311
- });
312
- const response = await this._callHandler(req);
313
- DEBUG_CALLS && (0, import_log.log)("sending response", {
314
- method: req.method,
315
- response: response.payload?.type_url,
316
- error: response.error
317
- }, {
318
- F: __dxlog_file,
319
- L: 296,
320
- S: this,
321
- C: (f, a) => f(...a)
322
- });
323
- await this._sendMessage({
324
- response
325
- });
326
- }
327
- } else if (decoded.response) {
328
- if (this._state !== "OPENED") {
329
- (0, import_log.log)("received response while closed", void 0, {
330
- F: __dxlog_file,
331
- L: 305,
332
- S: this,
333
- C: (f, a) => f(...a)
334
- });
335
- return;
336
- }
337
- const responseId = decoded.response.id;
338
- (0, import_invariant.invariant)(typeof responseId === "number", void 0, {
339
- F: __dxlog_file,
340
- L: 310,
341
- S: this,
342
- A: [
343
- "typeof responseId === 'number'",
344
- ""
345
- ]
346
- });
347
- if (!this._outgoingRequests.has(responseId)) {
348
- (0, import_log.log)("received response with invalid id", {
349
- responseId
350
- }, {
351
- F: __dxlog_file,
352
- L: 312,
353
- S: this,
354
- C: (f, a) => f(...a)
355
- });
356
- return;
357
- }
358
- const item = this._outgoingRequests.get(responseId);
359
- if (!item.stream) {
360
- this._outgoingRequests.delete(responseId);
361
- }
362
- DEBUG_CALLS && (0, import_log.log)("response", {
363
- type_url: decoded.response.payload?.type_url
364
- }, {
365
- F: __dxlog_file,
366
- L: 322,
367
- S: this,
368
- C: (f, a) => f(...a)
369
- });
370
- item.resolve(decoded.response);
371
- } else if (decoded.open) {
372
- (0, import_log.log)("received open message", {
373
- state: this._state
374
- }, {
375
- F: __dxlog_file,
376
- L: 325,
377
- S: this,
378
- C: (f, a) => f(...a)
379
- });
380
- if (this._params.noHandshake) {
381
- return;
382
- }
383
- await this._sendMessage({
384
- openAck: true
385
- });
386
- } else if (decoded.openAck) {
387
- (0, import_log.log)("received openAck message", {
388
- state: this._state
389
- }, {
390
- F: __dxlog_file,
391
- L: 332,
392
- S: this,
393
- C: (f, a) => f(...a)
394
- });
395
- if (this._params.noHandshake) {
396
- return;
397
- }
398
- this._state = "OPENED";
399
- this._remoteOpenTrigger.wake();
400
- } else if (decoded.streamClose) {
401
- if (this._state !== "OPENED") {
402
- (0, import_log.log)("received stream close while closed", void 0, {
403
- F: __dxlog_file,
404
- L: 341,
405
- S: this,
406
- C: (f, a) => f(...a)
407
- });
408
- return;
409
- }
410
- (0, import_log.log)("received stream close", {
411
- id: decoded.streamClose.id
412
- }, {
413
- F: __dxlog_file,
414
- L: 345,
415
- S: this,
416
- C: (f, a) => f(...a)
417
- });
418
- (0, import_invariant.invariant)(typeof decoded.streamClose.id === "number", void 0, {
419
- F: __dxlog_file,
420
- L: 346,
421
- S: this,
422
- A: [
423
- "typeof decoded.streamClose.id === 'number'",
424
- ""
425
- ]
426
- });
427
- const stream = this._localStreams.get(decoded.streamClose.id);
428
- if (!stream) {
429
- (0, import_log.log)("no local stream", {
430
- id: decoded.streamClose.id
431
- }, {
432
- F: __dxlog_file,
433
- L: 349,
434
- S: this,
435
- C: (f, a) => f(...a)
436
- });
437
- return;
438
- }
439
- this._localStreams.delete(decoded.streamClose.id);
440
- await stream.close();
441
- } else if (decoded.bye) {
442
- this._byeTrigger.wake();
443
- if (this._state !== "CLOSING" && this._state !== "CLOSED") {
444
- (0, import_log.log)("replying to bye", void 0, {
445
- F: __dxlog_file,
446
- L: 359,
447
- S: this,
448
- C: (f, a) => f(...a)
449
- });
450
- this._state = "CLOSING";
451
- await this._sendMessage({
452
- bye: {}
453
- });
454
- this._abortRequests();
455
- this._disposeAndClose();
456
- }
457
- } else {
458
- import_log.log.error("received malformed message", {
459
- msg
460
- }, {
461
- F: __dxlog_file,
462
- L: 367,
463
- S: this,
464
- C: (f, a) => f(...a)
465
- });
466
- throw new Error("Malformed message.");
467
- }
468
- }
469
- /**
470
- * Make RPC call. Will trigger a handler on the other side.
471
- * Peer should be open before making this call.
472
- */
473
- async call(method, request, options) {
474
- DEBUG_CALLS && (0, import_log.log)("calling...", {
475
- method
476
- }, {
477
- F: __dxlog_file,
478
- L: 377,
479
- S: this,
480
- C: (f, a) => f(...a)
481
- });
482
- throwIfNotOpen(this._state);
483
- let response;
484
- try {
485
- const id = this._nextId++;
486
- const responseReceived = new Promise((resolve, reject) => {
487
- this._outgoingRequests.set(id, new PendingRpcRequest(resolve, reject, false));
488
- });
489
- const sending = this._sendMessage({
490
- request: {
491
- id,
492
- method,
493
- payload: request,
494
- stream: false
495
- }
496
- });
497
- const timeout = options?.timeout ?? this._params.timeout;
498
- const waiting = timeout === 0 ? responseReceived : (0, import_async.asyncTimeout)(responseReceived, timeout ?? DEFAULT_TIMEOUT);
499
- await Promise.race([
500
- sending,
501
- waiting
502
- ]);
503
- response = await waiting;
504
- (0, import_invariant.invariant)(response.id === id, void 0, {
505
- F: __dxlog_file,
506
- L: 405,
507
- S: this,
508
- A: [
509
- "response.id === id",
510
- ""
511
- ]
512
- });
513
- } catch (err) {
514
- if (err instanceof import_protocols.RpcClosedError) {
515
- const error = new import_protocols.RpcClosedError();
516
- error.stack += `
517
-
518
- info: RPC client was closed at:
519
- ${err.stack?.split("\n").slice(1).join("\n")}`;
520
- throw error;
521
- }
522
- throw err;
523
- }
524
- if (response.payload) {
525
- return response.payload;
526
- } else if (response.error) {
527
- throw decodeRpcError(response.error, method);
528
- } else {
529
- throw new Error("Malformed response.");
530
- }
531
- }
532
- /**
533
- * Make RPC call with a streaming response.
534
- * Will trigger a handler on the other side.
535
- * Peer should be open before making this call.
536
- */
537
- callStream(method, request, options) {
538
- throwIfNotOpen(this._state);
539
- const id = this._nextId++;
540
- return new import_codec_protobuf.Stream(({ ready, next, close }) => {
541
- const onResponse = (response) => {
542
- if (response.streamReady) {
543
- ready();
544
- } else if (response.close) {
545
- close();
546
- } else if (response.error) {
547
- close(decodeRpcError(response.error, method));
548
- } else if (response.payload) {
549
- next(response.payload);
550
- } else {
551
- throw new Error("Malformed response.");
552
- }
553
- };
554
- const stack = new import_debug.StackTrace();
555
- const closeStream = (err) => {
556
- if (!err) {
557
- close();
558
- } else {
559
- err.stack += `
560
-
561
- Error happened in the stream at:
562
- ${stack.getStack()}`;
563
- close(err);
564
- }
565
- };
566
- this._outgoingRequests.set(id, new PendingRpcRequest(onResponse, closeStream, true));
567
- this._sendMessage({
568
- request: {
569
- id,
570
- method,
571
- payload: request,
572
- stream: true
573
- }
574
- }).catch((err) => {
575
- close(err);
576
- });
577
- return () => {
578
- this._sendMessage({
579
- streamClose: {
580
- id
581
- }
582
- }).catch((err) => {
583
- import_log.log.catch(err, void 0, {
584
- F: __dxlog_file,
585
- L: 478,
586
- S: this,
587
- C: (f, a) => f(...a)
588
- });
589
- });
590
- this._outgoingRequests.delete(id);
591
- };
592
- });
593
- }
594
- async _sendMessage(message, timeout) {
595
- DEBUG_CALLS && (0, import_log.log)("sending message", {
596
- type: Object.keys(message)[0]
597
- }, {
598
- F: __dxlog_file,
599
- L: 486,
600
- S: this,
601
- C: (f, a) => f(...a)
602
- });
603
- await this._params.port.send(getRpcMessageCodec().encode(message, {
604
- preserveAny: true
605
- }), timeout);
606
- }
607
- async _callHandler(req) {
608
- try {
609
- (0, import_invariant.invariant)(typeof req.id === "number", void 0, {
610
- F: __dxlog_file,
611
- L: 492,
612
- S: this,
613
- A: [
614
- "typeof req.id === 'number'",
615
- ""
616
- ]
617
- });
618
- (0, import_invariant.invariant)(req.payload, void 0, {
619
- F: __dxlog_file,
620
- L: 493,
621
- S: this,
622
- A: [
623
- "req.payload",
624
- ""
625
- ]
626
- });
627
- (0, import_invariant.invariant)(req.method, void 0, {
628
- F: __dxlog_file,
629
- L: 494,
630
- S: this,
631
- A: [
632
- "req.method",
633
- ""
634
- ]
635
- });
636
- const response = await this._params.callHandler(req.method, req.payload, this._params.handlerRpcOptions);
637
- return {
638
- id: req.id,
639
- payload: response
640
- };
641
- } catch (err) {
642
- return {
643
- id: req.id,
644
- error: (0, import_protocols.encodeError)(err)
645
- };
646
- }
647
- }
648
- _callStreamHandler(req, callback) {
649
- try {
650
- (0, import_invariant.invariant)(this._params.streamHandler, "Requests with streaming responses are not supported.", {
651
- F: __dxlog_file,
652
- L: 511,
653
- S: this,
654
- A: [
655
- "this._params.streamHandler",
656
- "'Requests with streaming responses are not supported.'"
657
- ]
658
- });
659
- (0, import_invariant.invariant)(typeof req.id === "number", void 0, {
660
- F: __dxlog_file,
661
- L: 512,
662
- S: this,
663
- A: [
664
- "typeof req.id === 'number'",
665
- ""
666
- ]
667
- });
668
- (0, import_invariant.invariant)(req.payload, void 0, {
669
- F: __dxlog_file,
670
- L: 513,
671
- S: this,
672
- A: [
673
- "req.payload",
674
- ""
675
- ]
676
- });
677
- (0, import_invariant.invariant)(req.method, void 0, {
678
- F: __dxlog_file,
679
- L: 514,
680
- S: this,
681
- A: [
682
- "req.method",
683
- ""
684
- ]
685
- });
686
- const responseStream = this._params.streamHandler(req.method, req.payload, this._params.handlerRpcOptions);
687
- responseStream.onReady(() => {
688
- callback({
689
- id: req.id,
690
- streamReady: true
691
- });
692
- });
693
- responseStream.subscribe((msg) => {
694
- callback({
695
- id: req.id,
696
- payload: msg
697
- });
698
- }, (error) => {
699
- if (error) {
700
- callback({
701
- id: req.id,
702
- error: (0, import_protocols.encodeError)(error)
703
- });
704
- } else {
705
- callback({
706
- id: req.id,
707
- close: true
708
- });
709
- }
710
- });
711
- this._localStreams.set(req.id, responseStream);
712
- } catch (err) {
713
- callback({
714
- id: req.id,
715
- error: (0, import_protocols.encodeError)(err)
716
- });
717
- }
718
- }
719
- };
720
- _ts_decorate([
721
- import_async.synchronized
722
- ], RpcPeer.prototype, "open", null);
723
- var throwIfNotOpen = (state) => {
724
- switch (state) {
725
- case "OPENED": {
726
- return;
727
- }
728
- case "INITIAL": {
729
- throw new import_protocols.RpcNotOpenError();
730
- }
731
- case "CLOSED": {
732
- throw new import_protocols.RpcClosedError();
733
- }
734
- }
735
- };
736
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/rpc/src/service.ts";
737
- var createServiceBundle = (services) => services;
738
- var ProtoRpcPeer = class {
739
- constructor(rpc, _peer) {
740
- this.rpc = rpc;
741
- this._peer = _peer;
742
- }
743
- async open() {
744
- await this._peer.open();
745
- }
746
- async close() {
747
- await this._peer.close();
748
- }
749
- async abort() {
750
- await this._peer.abort();
751
- }
752
- };
753
- var createProtoRpcPeer = ({ requested, exposed, handlers, encodingOptions, ...rest }) => {
754
- const exposedRpcs = {};
755
- if (exposed) {
756
- (0, import_invariant2.invariant)(handlers, void 0, {
757
- F: __dxlog_file2,
758
- L: 93,
759
- S: void 0,
760
- A: [
761
- "handlers",
762
- ""
763
- ]
764
- });
765
- for (const serviceName of Object.keys(exposed)) {
766
- const serviceFqn = exposed[serviceName].serviceProto.fullName.slice(1);
767
- const serviceProvider = handlers[serviceName];
768
- exposedRpcs[serviceFqn] = exposed[serviceName].createServer(serviceProvider, encodingOptions);
769
- }
770
- }
771
- const peer = new RpcPeer({
772
- ...rest,
773
- callHandler: (method, request, options) => {
774
- const [serviceName, methodName] = parseMethodName(method);
775
- if (!exposedRpcs[serviceName]) {
776
- throw new Error(`Service not supported: ${serviceName}`);
777
- }
778
- return exposedRpcs[serviceName].call(methodName, request, options);
779
- },
780
- streamHandler: (method, request, options) => {
781
- const [serviceName, methodName] = parseMethodName(method);
782
- if (!exposedRpcs[serviceName]) {
783
- throw new Error(`Service not supported: ${serviceName}`);
784
- }
785
- return exposedRpcs[serviceName].callStream(methodName, request, options);
786
- }
787
- });
788
- const requestedRpcs = {};
789
- if (requested) {
790
- for (const serviceName of Object.keys(requested)) {
791
- const serviceFqn = requested[serviceName].serviceProto.fullName.slice(1);
792
- requestedRpcs[serviceName] = requested[serviceName].createClient({
793
- call: (method, req, options) => peer.call(`${serviceFqn}.${method}`, req, options),
794
- callStream: (method, req, options) => peer.callStream(`${serviceFqn}.${method}`, req, options)
795
- }, encodingOptions);
796
- }
797
- }
798
- return new ProtoRpcPeer(requestedRpcs, peer);
799
- };
800
- var parseMethodName = (method) => {
801
- const separator = method.lastIndexOf(".");
802
- const serviceName = method.slice(0, separator);
803
- const methodName = method.slice(separator + 1);
804
- if (serviceName.length === 0 || methodName.length === 0) {
805
- throw new Error(`Invalid method: ${method}`);
806
- }
807
- return [
808
- serviceName,
809
- methodName
810
- ];
811
- };
812
- var createRpcClient = (serviceDef, options) => {
813
- const peer = new RpcPeer({
814
- ...options,
815
- callHandler: () => {
816
- throw new Error("Requests to client are not supported.");
817
- }
818
- });
819
- const client = serviceDef.createClient({
820
- call: peer.call.bind(peer),
821
- callStream: peer.callStream.bind(peer)
822
- });
823
- return new ProtoRpcPeer(client, peer);
824
- };
825
- var createRpcServer = ({ service, handlers, ...rest }) => {
826
- const server = service.createServer(handlers);
827
- return new RpcPeer({
828
- ...rest,
829
- callHandler: server.call.bind(server),
830
- streamHandler: server.callStream.bind(server)
831
- });
832
- };
833
- var createBundledRpcClient = (descriptors, options) => {
834
- return createProtoRpcPeer({
835
- requested: descriptors,
836
- ...options
837
- });
838
- };
839
- var createBundledRpcServer = ({ services, handlers, ...rest }) => {
840
- const rpc = {};
841
- for (const serviceName of Object.keys(services)) {
842
- const serviceFqn = services[serviceName].serviceProto.fullName.slice(1);
843
- rpc[serviceFqn] = services[serviceName].createServer(handlers[serviceName]);
844
- }
845
- return new RpcPeer({
846
- ...rest,
847
- callHandler: (method, request) => {
848
- const [serviceName, methodName] = parseMethodName(method);
849
- if (!rpc[serviceName]) {
850
- throw new Error(`Service not supported: ${serviceName}`);
851
- }
852
- return rpc[serviceName].call(methodName, request);
853
- },
854
- streamHandler: (method, request) => {
855
- const [serviceName, methodName] = parseMethodName(method);
856
- if (!rpc[serviceName]) {
857
- throw new Error(`Service not supported: ${serviceName}`);
858
- }
859
- return rpc[serviceName].callStream(methodName, request);
860
- }
861
- });
862
- };
863
- var createLinkedPorts = ({ delay } = {}) => {
864
- let port1Received;
865
- let port2Received;
866
- const send = (handler, msg) => {
867
- if (delay) {
868
- setTimeout(() => handler?.(msg), delay);
869
- } else {
870
- void handler?.(msg);
871
- }
872
- };
873
- const port1 = {
874
- send: (msg) => send(port2Received, msg),
875
- subscribe: (cb) => {
876
- port1Received = cb;
877
- }
878
- };
879
- const port2 = {
880
- send: (msg) => send(port1Received, msg),
881
- subscribe: (cb) => {
882
- port2Received = cb;
883
- }
884
- };
885
- return [
886
- port1,
887
- port2
888
- ];
889
- };
890
- var encodeMessage = (msg) => (0, import_util2.isNode)() ? Buffer.from(msg) : new TextEncoder().encode(msg);
891
- var PortTracer = class {
892
- constructor(_wrappedPort) {
893
- this._wrappedPort = _wrappedPort;
894
- this.message = new import_async2.Event();
895
- this._port = {
896
- send: (msg) => {
897
- this.message.emit({
898
- direction: import_rpc.MessageTrace.Direction.OUTGOING,
899
- data: msg
900
- });
901
- return this._wrappedPort.send(msg);
902
- },
903
- subscribe: (cb) => {
904
- return this._wrappedPort.subscribe((msg) => {
905
- this.message.emit({
906
- direction: import_rpc.MessageTrace.Direction.INCOMING,
907
- data: msg
908
- });
909
- cb(msg);
910
- });
911
- }
912
- };
913
- }
914
- get port() {
915
- return this._port;
916
- }
917
- };
918
- // Annotate the CommonJS export names for ESM import in node:
919
- 0 && (module.exports = {
920
- PortTracer,
921
- ProtoRpcPeer,
922
- RpcPeer,
923
- createBundledRpcClient,
924
- createBundledRpcServer,
925
- createLinkedPorts,
926
- createProtoRpcPeer,
927
- createRpcClient,
928
- createRpcServer,
929
- createServiceBundle,
930
- decodeRpcError,
931
- encodeMessage,
932
- parseMethodName
933
- });
934
- //# sourceMappingURL=index.cjs.map