@dxos/teleport 0.1.23 → 0.1.24

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,734 +1,135 @@
1
1
  import "@dxos/node-std/globals"
2
+ import {
3
+ Teleport,
4
+ TestExtension
5
+ } from "../chunk-F3DXMBSX.mjs";
2
6
 
3
7
  // packages/core/mesh/teleport/src/testing/test-builder.ts
8
+ import assert from "@dxos/node-std/assert";
4
9
  import { pipeline } from "@dxos/node-std/stream";
5
- import { PublicKey as PublicKey2 } from "@dxos/keys";
6
- import { log as log3 } from "@dxos/log";
7
-
8
- // packages/core/mesh/teleport/src/teleport.ts
9
- import assert3 from "@dxos/node-std/assert";
10
- import { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask } from "@dxos/async";
11
- import { Context } from "@dxos/context";
12
- import { failUndefined as failUndefined2 } from "@dxos/debug";
13
10
  import { PublicKey } from "@dxos/keys";
14
- import { log as log2 } from "@dxos/log";
15
- import { schema as schema2 } from "@dxos/protocols";
16
- import { createProtoRpcPeer, RpcClosedError } from "@dxos/rpc";
17
- import { Callback } from "@dxos/util";
18
-
19
- // packages/core/mesh/teleport/src/muxing/framer.ts
20
- import assert from "@dxos/node-std/assert";
21
- import { Duplex } from "@dxos/node-std/stream";
22
- import * as varint from "varint";
23
- var Framer = class {
24
- constructor() {
25
- this._stream = new Duplex({
26
- objectMode: false,
27
- read: () => {
28
- },
29
- write: (chunk, encoding, callback) => {
30
- assert(!this._subscribeCb, "Internal Framer bug. Concurrent writes detected.");
31
- if (this._buffer && this._buffer.length > 0) {
32
- this._buffer = Buffer.concat([
33
- this._buffer,
34
- chunk
35
- ]);
36
- } else {
37
- this._buffer = chunk;
38
- }
39
- if (this._messageCb) {
40
- this._popFrames();
41
- callback();
42
- } else {
43
- this._subscribeCb = () => {
44
- this._popFrames();
45
- this._subscribeCb = void 0;
46
- callback();
47
- };
48
- }
49
- }
50
- });
51
- this.port = {
52
- send: (message) => {
53
- this._stream.push(encodeFrame(message));
54
- },
55
- subscribe: (callback) => {
56
- var _a;
57
- assert(!this._messageCb, "Rpc port already has a message listener.");
58
- this._messageCb = callback;
59
- (_a = this._subscribeCb) == null ? void 0 : _a.call(this);
60
- return () => {
61
- this._messageCb = void 0;
62
- };
63
- }
64
- };
65
- }
66
- get stream() {
67
- return this._stream;
68
- }
69
- /**
70
- * Attempts to pop frames from the buffer and call the message callback.
71
- */
72
- _popFrames() {
73
- let offset = 0;
74
- while (offset < this._buffer.length) {
75
- const frame = decodeFrame(this._buffer, offset);
76
- if (!frame) {
77
- break;
78
- }
79
- offset += frame.bytesConsumed;
80
- this._messageCb(frame.payload);
81
- }
82
- if (offset < this._buffer.length) {
83
- this._buffer = this._buffer.subarray(offset);
84
- } else {
85
- this._buffer = void 0;
86
- }
87
- }
88
- destroy() {
89
- this._stream.destroy();
90
- }
91
- };
92
- var decodeFrame = (buffer, offset) => {
93
- try {
94
- const frameLength = varint.decode(buffer, offset);
95
- const tagLength = varint.decode.bytes;
96
- if (buffer.length < offset + tagLength + frameLength) {
97
- return void 0;
98
- }
99
- const payload = buffer.subarray(offset + tagLength, offset + tagLength + frameLength);
100
- return {
101
- payload,
102
- bytesConsumed: tagLength + frameLength
103
- };
104
- } catch (err) {
105
- if (err instanceof RangeError) {
106
- return void 0;
107
- } else {
108
- throw err;
109
- }
110
- }
111
- };
112
- var encodeFrame = (payload) => {
113
- const tagLength = varint.encodingLength(payload.length);
114
- const frame = Buffer.allocUnsafe(tagLength + payload.length);
115
- varint.encode(payload.length, frame);
116
- frame.set(payload, tagLength);
117
- return frame;
118
- };
119
-
120
- // packages/core/mesh/teleport/src/muxing/muxer.ts
121
- import assert2 from "@dxos/node-std/assert";
122
- import { Duplex as Duplex2 } from "@dxos/node-std/stream";
123
- import { Event } from "@dxos/async";
124
- import { failUndefined } from "@dxos/debug";
125
11
  import { log } from "@dxos/log";
126
- import { schema } from "@dxos/protocols";
127
- var codec = schema.getCodecForType("dxos.mesh.muxer.Command");
128
- var Muxer = class {
129
- constructor() {
130
- this._framer = new Framer();
131
- this.stream = this._framer.stream;
132
- this._channelsByLocalId = /* @__PURE__ */ new Map();
133
- this._channelsByTag = /* @__PURE__ */ new Map();
134
- this._nextId = 0;
135
- this._destroyed = false;
136
- this._destroying = false;
137
- this.close = new Event();
138
- this._framer.port.subscribe((msg) => {
139
- this._handleCommand(codec.decode(msg));
140
- });
141
- }
142
- /**
143
- * Creates a duplex Node.js-style stream.
144
- * The remote peer is expected to call `createStream` with the same tag.
145
- * The stream is immediately readable and writable.
146
- * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
147
- */
148
- createStream(tag, opts = {}) {
149
- const channel = this._getOrCreateStream({
150
- tag,
151
- contentType: opts.contentType
152
- });
153
- assert2(!channel.push, `Channel already open: ${tag}`);
154
- const stream = new Duplex2({
155
- write: (data, encoding, callback) => {
156
- this._sendData(channel, data);
157
- callback();
158
- },
159
- read: () => {
160
- }
161
- // No-op. We will push data when we receive it.
162
- });
163
- channel.push = (data) => {
164
- stream.push(data);
165
- };
166
- channel.destroy = (err) => {
167
- stream.destroy(err);
168
- };
169
- this._sendCommand({
170
- openChannel: {
171
- id: channel.id,
172
- tag: channel.tag,
173
- contentType: channel.contentType
174
- }
175
- });
176
- return stream;
177
- }
178
- /**
179
- * Creates an RPC port.
180
- * The remote peer is expected to call `createPort` with the same tag.
181
- * The port is immediately usable.
182
- * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).
183
- */
184
- createPort(tag, opts = {}) {
185
- const channel = this._getOrCreateStream({
186
- tag,
187
- contentType: opts.contentType
188
- });
189
- assert2(!channel.push, `Channel already open: ${tag}`);
190
- let inboundBuffer = [];
191
- let callback;
192
- channel.push = (data) => {
193
- if (callback) {
194
- callback(data);
195
- } else {
196
- inboundBuffer.push(data);
197
- }
198
- };
199
- const port = {
200
- send: (data) => {
201
- this._sendData(channel, data);
202
- },
203
- subscribe: (cb) => {
204
- assert2(!callback, "Only one subscriber is allowed");
205
- callback = cb;
206
- for (const data of inboundBuffer) {
207
- cb(data);
208
- }
209
- inboundBuffer = [];
210
- }
211
- };
212
- this._sendCommand({
213
- openChannel: {
214
- id: channel.id,
215
- tag: channel.tag,
216
- contentType: channel.contentType
217
- }
218
- });
219
- return port;
220
- }
221
- /**
222
- * Force-close with optional error.
223
- */
224
- destroy(err) {
225
- if (this._destroying) {
226
- return;
227
- }
228
- this._destroying = true;
229
- this._sendCommand({
230
- destroy: {
231
- error: err == null ? void 0 : err.message
232
- }
233
- });
234
- this._dispose();
235
- }
236
- _dispose(err) {
237
- var _a;
238
- if (this._destroyed) {
239
- return;
240
- }
241
- this._destroyed = true;
242
- this._framer.destroy();
243
- for (const channel of this._channelsByTag.values()) {
244
- (_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
245
- }
246
- this.close.emit(err);
247
- this._channelsByLocalId.clear();
248
- this._channelsByTag.clear();
249
- }
250
- _handleCommand(cmd) {
251
- var _a;
252
- log("Received command", {
253
- cmd
254
- }, {
255
- file: "muxer.ts",
256
- line: 194,
257
- scope: this,
258
- callSite: (f, a) => f(...a)
259
- });
260
- if (this._destroyed || this._destroying) {
261
- log.warn("Received command after destroy", {}, {
262
- file: "muxer.ts",
263
- line: 197,
264
- scope: this,
265
- callSite: (f, a) => f(...a)
266
- });
267
- return;
268
- }
269
- if (cmd.openChannel) {
270
- const channel = this._getOrCreateStream({
271
- tag: cmd.openChannel.tag,
272
- contentType: cmd.openChannel.contentType
273
- });
274
- channel.remoteId = cmd.openChannel.id;
275
- for (const data of channel.buffer) {
276
- this._sendCommand({
277
- data: {
278
- channelId: channel.remoteId,
279
- data
280
- }
281
- });
282
- }
283
- channel.buffer = [];
284
- } else if (cmd.data) {
285
- const stream = (_a = this._channelsByLocalId.get(cmd.data.channelId)) != null ? _a : failUndefined();
286
- if (!stream.push) {
287
- log.warn("Received data for channel before it was opened", {
288
- tag: stream.tag
289
- }, {
290
- file: "muxer.ts",
291
- line: 221,
292
- scope: this,
293
- callSite: (f, a) => f(...a)
294
- });
295
- return;
296
- }
297
- stream.push(cmd.data.data);
298
- } else if (cmd.destroy) {
299
- this._dispose();
300
- }
301
- }
302
- _sendCommand(cmd) {
303
- Promise.resolve(this._framer.port.send(codec.encode(cmd))).catch((err) => {
304
- this.destroy(err);
305
- });
306
- }
307
- _getOrCreateStream(params) {
308
- let channel = this._channelsByTag.get(params.tag);
309
- if (!channel) {
310
- channel = {
311
- id: this._nextId++,
312
- remoteId: null,
313
- tag: params.tag,
314
- contentType: params.contentType,
315
- buffer: [],
316
- push: null,
317
- destroy: null
318
- };
319
- this._channelsByTag.set(channel.tag, channel);
320
- this._channelsByLocalId.set(channel.id, channel);
321
- }
322
- return channel;
323
- }
324
- _sendData(channel, data) {
325
- if (channel.remoteId === null) {
326
- channel.buffer.push(data);
327
- } else {
328
- this._sendCommand({
329
- data: {
330
- channelId: channel.remoteId,
331
- data
332
- }
333
- });
334
- }
335
- }
336
- };
337
-
338
- // packages/core/mesh/teleport/src/teleport.ts
339
- var __decorate = function(decorators, target, key, desc) {
340
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
341
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
342
- r = Reflect.decorate(decorators, target, key, desc);
343
- else
344
- for (var i = decorators.length - 1; i >= 0; i--)
345
- if (d = decorators[i])
346
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
347
- return c > 3 && r && Object.defineProperty(target, key, r), r;
348
- };
349
- var Teleport = class {
350
- constructor({ initiator, localPeerId, remotePeerId }) {
351
- this._ctx = new Context({
352
- onError: (err) => {
353
- void this.destroy(err).catch(() => {
354
- log2.error("Error during destroy", err, {
355
- file: "teleport.ts",
356
- line: 34,
357
- scope: this,
358
- callSite: (f, a) => f(...a)
359
- });
360
- });
361
- }
362
- });
363
- this._muxer = new Muxer();
364
- this._control = new ControlExtension({
365
- heartbeatInterval: 3e3,
366
- heartbeatTimeout: 3e3,
367
- onTimeout: () => {
368
- this.destroy(new Error("Connection timed out")).catch((err) => log2.catch(err, {}, {
369
- file: "teleport.ts",
370
- line: 45,
371
- scope: this,
372
- callSite: (f, a) => f(...a)
373
- }));
374
- }
375
- });
376
- this._extensions = /* @__PURE__ */ new Map();
377
- this._remoteExtensions = /* @__PURE__ */ new Set();
378
- this._open = false;
379
- assert3(typeof initiator === "boolean");
380
- assert3(PublicKey.isPublicKey(localPeerId));
381
- assert3(PublicKey.isPublicKey(remotePeerId));
382
- assert3(typeof initiator === "boolean");
383
- this.initiator = initiator;
384
- this.localPeerId = localPeerId;
385
- this.remotePeerId = remotePeerId;
386
- this._control.onExtensionRegistered.set(async (name) => {
387
- log2("remote extension", {
388
- name
389
- }, {
390
- file: "teleport.ts",
391
- line: 64,
392
- scope: this,
393
- callSite: (f, a) => f(...a)
394
- });
395
- assert3(!this._remoteExtensions.has(name), "Remote extension already exists");
396
- this._remoteExtensions.add(name);
397
- if (this._extensions.has(name)) {
398
- try {
399
- await this._openExtension(name);
400
- } catch (err) {
401
- await this.destroy(err);
402
- }
403
- }
404
- });
405
- {
406
- this._muxer.stream.on("close", async () => {
407
- await this.destroy();
408
- });
409
- this._muxer.stream.on("error", async (err) => {
410
- await this.destroy(err);
411
- });
412
- }
413
- }
414
- get stream() {
415
- return this._muxer.stream;
416
- }
417
- /**
418
- * Blocks until the handshake is complete.
419
- */
420
- async open() {
421
- this._setExtension("dxos.mesh.teleport.control", this._control);
422
- await this._openExtension("dxos.mesh.teleport.control");
423
- this._open = true;
424
- }
425
- async close(err) {
426
- await this.destroy(err);
427
- }
428
- async destroy(err) {
429
- if (this._ctx.disposed) {
430
- return;
431
- }
432
- await this._ctx.dispose();
433
- for (const extension of this._extensions.values()) {
434
- try {
435
- await extension.onClose(err);
436
- } catch (err1) {
437
- log2.catch(err1, {}, {
438
- file: "teleport.ts",
439
- line: 120,
440
- scope: this,
441
- callSite: (f, a) => f(...a)
442
- });
443
- }
444
- }
445
- this._muxer.destroy(err);
446
- }
447
- addExtension(name, extension) {
448
- if (!this._open) {
449
- throw new Error("Not open");
450
- }
451
- log2("addExtension", {
452
- name
453
- }, {
454
- file: "teleport.ts",
455
- line: 132,
456
- scope: this,
457
- callSite: (f, a) => f(...a)
458
- });
459
- this._setExtension(name, extension);
460
- scheduleTask(this._ctx, async () => {
461
- try {
462
- await this._control.registerExtension(name);
463
- } catch (err) {
464
- if (err instanceof RpcClosedError) {
465
- return;
466
- }
467
- throw err;
468
- }
469
- });
470
- if (this._remoteExtensions.has(name)) {
471
- scheduleTask(this._ctx, async () => {
472
- await this._openExtension(name);
473
- });
474
- }
475
- }
476
- _setExtension(extensionName, extension) {
477
- assert3(!extensionName.includes("/"), "Invalid extension name");
478
- assert3(!this._extensions.has(extensionName), "Extension already exists");
479
- this._extensions.set(extensionName, extension);
480
- }
481
- async _openExtension(extensionName) {
482
- var _a;
483
- log2("open extension", {
484
- extensionName
485
- }, {
486
- file: "teleport.ts",
487
- line: 162,
488
- scope: this,
489
- callSite: (f, a) => f(...a)
490
- });
491
- const extension = (_a = this._extensions.get(extensionName)) != null ? _a : failUndefined2();
492
- const context = {
493
- initiator: this.initiator,
494
- localPeerId: this.localPeerId,
495
- remotePeerId: this.remotePeerId,
496
- createPort: (channelName, opts) => {
497
- assert3(!channelName.includes("/"), "Invalid channel name");
498
- return this._muxer.createPort(`${extensionName}/${channelName}`, opts);
499
- },
500
- createStream: (channelName, opts) => {
501
- assert3(!channelName.includes("/"), "Invalid channel name");
502
- return this._muxer.createStream(`${extensionName}/${channelName}`, opts);
503
- },
504
- close: (err) => {
505
- void runInContextAsync(this._ctx, async () => {
506
- await this.close(err);
507
- });
508
- }
509
- };
510
- await extension.onOpen(context);
511
- log2("extension opened", {
512
- extensionName
513
- }, {
514
- file: "teleport.ts",
515
- line: 185,
516
- scope: this,
517
- callSite: (f, a) => f(...a)
518
- });
519
- }
520
- };
521
- __decorate([
522
- synchronized
523
- ], Teleport.prototype, "destroy", null);
524
- var ControlExtension = class {
525
- constructor(opts) {
526
- this.opts = opts;
527
- this._ctx = new Context({
528
- onError: (err) => {
529
- this._extensionContext.close(err);
530
- }
531
- });
532
- this.onExtensionRegistered = new Callback();
533
- }
534
- async onOpen(extensionContext) {
535
- this._extensionContext = extensionContext;
536
- this._rpc = createProtoRpcPeer({
537
- requested: {
538
- Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
539
- },
540
- exposed: {
541
- Control: schema2.getService("dxos.mesh.teleport.control.ControlService")
542
- },
543
- handlers: {
544
- Control: {
545
- registerExtension: async (request) => {
546
- this.onExtensionRegistered.call(request.name);
547
- },
548
- heartbeat: async (request) => {
549
- }
550
- }
551
- },
552
- port: extensionContext.createPort("rpc", {
553
- contentType: 'application/x-protobuf; messagType="dxos.rpc.Message"'
554
- })
555
- });
556
- await this._rpc.open();
557
- scheduleTaskInterval(this._ctx, async () => {
558
- try {
559
- await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);
560
- } catch (err) {
561
- this.opts.onTimeout();
562
- }
563
- }, this.opts.heartbeatInterval);
564
- }
565
- async onClose(err) {
566
- await this._ctx.dispose();
567
- await this._rpc.close();
568
- }
569
- async registerExtension(name) {
570
- await this._rpc.rpc.Control.registerExtension({
571
- name
572
- });
573
- }
574
- };
575
-
576
- // packages/core/mesh/teleport/src/testing/test-builder.ts
577
12
  var TestBuilder = class {
578
13
  constructor() {
579
- this._peers = new Array();
14
+ this._peers = /* @__PURE__ */ new Set();
580
15
  }
581
- createPeer(peerId) {
582
- const peer = new TestPeer(peerId);
583
- this._peers.push(peer);
16
+ createPeer(opts) {
17
+ const peer = opts.factory();
18
+ this._peers.add(peer);
584
19
  return peer;
585
20
  }
21
+ *createPeers(opts) {
22
+ while (true) {
23
+ yield this.createPeer(opts);
24
+ }
25
+ }
586
26
  async destroy() {
587
- await Promise.all(this._peers.map((agent) => agent.destroy()));
27
+ await Promise.all(Array.from(this._peers).map((agent) => agent.destroy()));
588
28
  }
589
- /**
590
- * Simulates two peers connected via P2P network.
591
- */
592
- async createPipedPeers({ peerId1, peerId2 } = {}) {
593
- const peer1 = this.createPeer(peerId1);
594
- const peer2 = this.createPeer(peerId2);
595
- peer1.initializeTeleport({
29
+ async connect(peer1, peer2) {
30
+ assert(peer1 !== peer2);
31
+ assert(this._peers.has(peer1));
32
+ assert(this._peers.has(peer1));
33
+ const connection1 = peer1.createConnection({
596
34
  initiator: true,
597
35
  remotePeerId: peer2.peerId
598
36
  });
599
- peer2.initializeTeleport({
37
+ const connection2 = peer2.createConnection({
600
38
  initiator: false,
601
39
  remotePeerId: peer1.peerId
602
40
  });
603
- peer1.pipeline(peer2);
604
- peer2.pipeline(peer1);
41
+ pipeStreams(connection1.teleport.stream, connection2.teleport.stream);
42
+ await Promise.all([
43
+ peer1.openConnection(connection1),
44
+ peer2.openConnection(connection2)
45
+ ]);
46
+ return [
47
+ connection1,
48
+ connection2
49
+ ];
50
+ }
51
+ async disconnect(peer1, peer2) {
52
+ assert(peer1 !== peer2);
53
+ assert(this._peers.has(peer1));
54
+ assert(this._peers.has(peer1));
55
+ const connection1 = Array.from(peer1.connections).find((connection) => connection.remotePeerId.equals(peer2.peerId));
56
+ const connection2 = Array.from(peer2.connections).find((connection) => connection.remotePeerId.equals(peer1.peerId));
57
+ assert(connection1);
58
+ assert(connection2);
605
59
  await Promise.all([
606
- peer1.teleport.open(),
607
- peer2.teleport.open()
60
+ peer1.closeConnection(connection1),
61
+ peer2.closeConnection(connection2)
608
62
  ]);
609
- return {
610
- peer1,
611
- peer2
612
- };
613
63
  }
614
64
  };
615
65
  var TestPeer = class {
616
- constructor(peerId = PublicKey2.random()) {
66
+ constructor(peerId = PublicKey.random()) {
617
67
  this.peerId = peerId;
68
+ this.connections = /* @__PURE__ */ new Set();
618
69
  }
619
- initializeTeleport({ initiator, remotePeerId }) {
620
- if (this.teleport) {
621
- return this;
622
- }
623
- this.teleport = new Teleport({
624
- initiator,
625
- localPeerId: this.peerId,
626
- remotePeerId
627
- });
628
- return this;
629
- }
630
- pipeline(peer) {
631
- if (!this.teleport || !peer.teleport) {
632
- throw new Error("Teleport not initialized");
633
- }
634
- pipeline(this.teleport.stream, peer.teleport.stream, (err) => {
635
- if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
636
- log3.catch(err, {}, {
637
- file: "test-builder.ts",
638
- line: 67,
639
- scope: this,
640
- callSite: (f, a) => f(...a)
641
- });
642
- }
643
- });
70
+ async onOpen(connection) {
644
71
  }
645
- async destroy() {
646
- var _a;
647
- await ((_a = this.teleport) == null ? void 0 : _a.destroy());
72
+ async onClose(connection) {
648
73
  }
649
- };
650
-
651
- // packages/core/mesh/teleport/src/testing/test-extension.ts
652
- import assert4 from "@dxos/node-std/assert";
653
- import { asyncTimeout as asyncTimeout2, Trigger } from "@dxos/async";
654
- import { log as log4 } from "@dxos/log";
655
- import { schema as schema3 } from "@dxos/protocols";
656
- import { createProtoRpcPeer as createProtoRpcPeer2 } from "@dxos/rpc";
657
- var TestExtension = class {
658
- constructor(callbacks = {}) {
659
- this.callbacks = callbacks;
660
- this.open = new Trigger();
661
- this.closed = new Trigger();
74
+ createConnection({ initiator, remotePeerId }) {
75
+ const connection = new TestConnection(this.peerId, remotePeerId, initiator);
76
+ this.connections.add(connection);
77
+ return connection;
662
78
  }
663
- get remotePeerId() {
664
- var _a;
665
- return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
79
+ async openConnection(connection) {
80
+ assert(this.connections.has(connection));
81
+ await connection.teleport.open();
82
+ await this.onOpen(connection);
666
83
  }
667
- async onOpen(context) {
668
- var _a, _b;
669
- log4("onOpen", {
670
- localPeerId: context.localPeerId,
671
- remotePeerId: context.remotePeerId
672
- }, {
673
- file: "test-extension.ts",
674
- line: 33,
675
- scope: this,
676
- callSite: (f, a) => f(...a)
677
- });
678
- this.extensionContext = context;
679
- this._rpc = createProtoRpcPeer2({
680
- port: context.createPort("rpc", {
681
- contentType: 'application/x-protobuf; messageType="dxos.rpc.Message"'
682
- }),
683
- requested: {
684
- TestService: schema3.getService("example.testing.rpc.TestService")
685
- },
686
- exposed: {
687
- TestService: schema3.getService("example.testing.rpc.TestService")
688
- },
689
- handlers: {
690
- TestService: {
691
- voidCall: async (request) => {
692
- },
693
- testCall: async (request) => {
694
- return {
695
- data: request.data
696
- };
697
- }
698
- }
699
- },
700
- timeout: 1e3
701
- });
702
- await this._rpc.open();
703
- await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
704
- this.open.wake();
84
+ async closeConnection(connection) {
85
+ assert(this.connections.has(connection));
86
+ await this.onClose(connection);
87
+ await connection.teleport.close();
88
+ this.connections.delete(connection);
705
89
  }
706
- async onClose(err) {
707
- var _a, _b, _c;
708
- log4("onClose", {
709
- err
710
- }, {
711
- file: "test-extension.ts",
712
- line: 67,
713
- scope: this,
714
- callSite: (f, a) => f(...a)
715
- });
716
- await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
717
- this.closed.wake();
718
- await ((_c = this._rpc) == null ? void 0 : _c.close());
90
+ async destroy() {
91
+ for (const teleport of this.connections) {
92
+ await this.closeConnection(teleport);
93
+ }
719
94
  }
720
- async test() {
721
- await this.open.wait({
722
- timeout: 500
95
+ };
96
+ var pipeStreams = (stream1, stream2) => {
97
+ pipeline(stream1, stream2, (err) => {
98
+ if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
99
+ log.catch(err, {}, {
100
+ file: "test-builder.ts",
101
+ line: 106,
102
+ scope: void 0,
103
+ callSite: (f, a) => f(...a)
104
+ });
105
+ }
106
+ });
107
+ pipeline(stream2, stream1, (err) => {
108
+ if (err && err.code !== "ERR_STREAM_PREMATURE_CLOSE") {
109
+ log.catch(err, {}, {
110
+ file: "test-builder.ts",
111
+ line: 111,
112
+ scope: void 0,
113
+ callSite: (f, a) => f(...a)
114
+ });
115
+ }
116
+ });
117
+ };
118
+ var TestConnection = class {
119
+ constructor(localPeerId, remotePeerId, initiator) {
120
+ this.localPeerId = localPeerId;
121
+ this.remotePeerId = remotePeerId;
122
+ this.initiator = initiator;
123
+ this.teleport = new Teleport({
124
+ initiator,
125
+ localPeerId,
126
+ remotePeerId
723
127
  });
724
- const res = await asyncTimeout2(this._rpc.rpc.TestService.testCall({
725
- data: "test"
726
- }), 500);
727
- assert4(res.data === "test");
728
128
  }
729
129
  };
730
130
  export {
731
131
  TestBuilder,
132
+ TestConnection,
732
133
  TestExtension,
733
134
  TestPeer
734
135
  };