@dxos/teleport 0.1.56-main.c19b7cd → 0.1.56-main.c277f68

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.
@@ -77,7 +77,6 @@ var Framer = class {
77
77
  });
78
78
  },
79
79
  subscribe: (callback) => {
80
- var _a;
81
80
  invariant(!this._messageCb, "Rpc port already has a message listener.", {
82
81
  F: __dxlog_file,
83
82
  L: 73,
@@ -88,7 +87,7 @@ var Framer = class {
88
87
  ]
89
88
  });
90
89
  this._messageCb = callback;
91
- (_a = this._subscribeCb) == null ? void 0 : _a.call(this);
90
+ this._subscribeCb?.();
92
91
  return () => {
93
92
  this._messageCb = void 0;
94
93
  };
@@ -277,16 +276,15 @@ var Balancer = class {
277
276
  return chunk;
278
277
  }
279
278
  async _sendChunks() {
280
- var _a, _b;
281
279
  if (this._sendBuffers.size === 0) {
282
280
  return;
283
281
  }
284
282
  const chunk = this._getNextChunk();
285
283
  try {
286
284
  await this._framer.port.send(chunk.msg);
287
- (_a = chunk.trigger) == null ? void 0 : _a.wake();
285
+ chunk.trigger?.wake();
288
286
  } catch (err) {
289
- (_b = chunk.trigger) == null ? void 0 : _b.throw(err);
287
+ chunk.trigger?.throw(err);
290
288
  }
291
289
  await this._sendChunks();
292
290
  }
@@ -336,6 +334,7 @@ var Muxer = class {
336
334
  this.close = new Event2();
337
335
  this.statsUpdated = new Event2();
338
336
  this.stream = this._balancer.stream;
337
+ this._lastChannelStats = /* @__PURE__ */ new Map();
339
338
  this._balancer.incomingData.on(async (msg) => {
340
339
  await this._handleCommand(Command.decode(msg));
341
340
  });
@@ -354,7 +353,7 @@ var Muxer = class {
354
353
  });
355
354
  invariant2(!channel.push, `Channel already open: ${tag}`, {
356
355
  F: __dxlog_file3,
357
- L: 91,
356
+ L: 131,
358
357
  S: this,
359
358
  A: [
360
359
  "!channel.push",
@@ -402,7 +401,7 @@ var Muxer = class {
402
401
  });
403
402
  invariant2(!channel.push, `Channel already open: ${tag}`, {
404
403
  F: __dxlog_file3,
405
- L: 143,
404
+ L: 183,
406
405
  S: this,
407
406
  A: [
408
407
  "!channel.push",
@@ -426,7 +425,7 @@ var Muxer = class {
426
425
  subscribe: (cb) => {
427
426
  invariant2(!callback, "Only one subscriber is allowed", {
428
427
  F: __dxlog_file3,
429
- L: 165,
428
+ L: 205,
430
429
  S: this,
431
430
  A: [
432
431
  "!callback",
@@ -464,7 +463,7 @@ var Muxer = class {
464
463
  this._destroying = true;
465
464
  this._sendCommand({
466
465
  destroy: {
467
- error: err == null ? void 0 : err.message
466
+ error: err?.message
468
467
  }
469
468
  }, SYSTEM_CHANNEL_ID).then(() => {
470
469
  this._dispose();
@@ -474,26 +473,24 @@ var Muxer = class {
474
473
  void this._ctx.dispose();
475
474
  }
476
475
  _dispose(err) {
477
- var _a;
478
476
  if (this._destroyed) {
479
477
  return;
480
478
  }
481
479
  this._destroyed = true;
482
480
  this._balancer.destroy();
483
481
  for (const channel of this._channelsByTag.values()) {
484
- (_a = channel.destroy) == null ? void 0 : _a.call(channel, err);
482
+ channel.destroy?.(err);
485
483
  }
486
484
  this.close.emit(err);
487
485
  this._channelsByLocalId.clear();
488
486
  this._channelsByTag.clear();
489
487
  }
490
488
  async _handleCommand(cmd) {
491
- var _a;
492
489
  log2("Received command", {
493
490
  cmd
494
491
  }, {
495
492
  F: __dxlog_file3,
496
- L: 240,
493
+ L: 280,
497
494
  S: this,
498
495
  C: (f, a) => f(...a)
499
496
  });
@@ -505,7 +502,7 @@ var Muxer = class {
505
502
  cmd
506
503
  }, {
507
504
  F: __dxlog_file3,
508
- L: 247,
505
+ L: 287,
509
506
  S: this,
510
507
  C: (f, a) => f(...a)
511
508
  });
@@ -527,13 +524,13 @@ var Muxer = class {
527
524
  }
528
525
  channel.buffer = [];
529
526
  } else if (cmd.data) {
530
- const stream = (_a = this._channelsByLocalId.get(cmd.data.channelId)) != null ? _a : failUndefined();
527
+ const stream = this._channelsByLocalId.get(cmd.data.channelId) ?? failUndefined();
531
528
  if (!stream.push) {
532
529
  log2.warn("Received data for channel before it was opened", {
533
530
  tag: stream.tag
534
531
  }, {
535
532
  F: __dxlog_file3,
536
- L: 274,
533
+ L: 314,
537
534
  S: this,
538
535
  C: (f, a) => f(...a)
539
536
  });
@@ -582,7 +579,7 @@ var Muxer = class {
582
579
  threshold: MAX_SAFE_FRAME_SIZE
583
580
  }, {
584
581
  F: __dxlog_file3,
585
- L: 318,
582
+ L: 359,
586
583
  S: this,
587
584
  C: (f, a) => f(...a)
588
585
  });
@@ -608,21 +605,40 @@ var Muxer = class {
608
605
  }
609
606
  async _emitStats() {
610
607
  if (this._destroyed || this._destroying) {
608
+ this._lastStats = void 0;
609
+ this._lastChannelStats.clear();
611
610
  return;
612
611
  }
613
612
  const bytesSent = this._balancer.bytesSent;
614
613
  const bytesReceived = this._balancer.bytesReceived;
615
- this.statsUpdated.emit({
616
- channels: Array.from(this._channelsByTag.values()).map((channel) => ({
617
- id: channel.id,
618
- tag: channel.tag,
619
- contentType: channel.contentType,
620
- bytesSent: channel.stats.bytesSent,
621
- bytesReceived: channel.stats.bytesReceived
622
- })),
614
+ const now = Date.now();
615
+ const interval = this._lastStats ? (now - this._lastStats.timestamp) / 1e3 : 0;
616
+ const calculateThroughput = (current, last) => last ? {
617
+ bytesSentRate: interval ? (current.bytesSent - last.bytesSent) / interval : void 0,
618
+ bytesReceivedRate: interval ? (current.bytesReceived - last.bytesReceived) / interval : void 0
619
+ } : {};
620
+ this._lastStats = {
621
+ timestamp: now,
622
+ channels: Array.from(this._channelsByTag.values()).map((channel) => {
623
+ const stats = {
624
+ id: channel.id,
625
+ tag: channel.tag,
626
+ contentType: channel.contentType,
627
+ bytesSent: channel.stats.bytesSent,
628
+ bytesReceived: channel.stats.bytesReceived,
629
+ ...calculateThroughput(channel.stats, this._lastChannelStats.get(channel.id))
630
+ };
631
+ this._lastChannelStats.set(channel.id, stats);
632
+ return stats;
633
+ }),
623
634
  bytesSent,
624
- bytesReceived
625
- });
635
+ bytesReceived,
636
+ ...calculateThroughput({
637
+ bytesSent,
638
+ bytesReceived
639
+ }, this._lastStats)
640
+ };
641
+ this.statsUpdated.emit(this._lastStats);
626
642
  }
627
643
  };
628
644
 
@@ -738,11 +754,13 @@ var Teleport = class {
738
754
  localPeerId,
739
755
  remotePeerId,
740
756
  bytesSent: stats.bytesSent,
757
+ bytesSentRate: stats.bytesSentRate,
741
758
  bytesReceived: stats.bytesReceived,
759
+ bytesReceivedRate: stats.bytesReceivedRate,
742
760
  channels: stats.channels
743
761
  }, {
744
762
  F: __dxlog_file4,
745
- L: 88,
763
+ L: 89,
746
764
  S: this,
747
765
  C: (f, a) => f(...a)
748
766
  });
@@ -776,7 +794,7 @@ var Teleport = class {
776
794
  } catch (err2) {
777
795
  log3.catch(err2, void 0, {
778
796
  F: __dxlog_file4,
779
- L: 132,
797
+ L: 137,
780
798
  S: this,
781
799
  C: (f, a) => f(...a)
782
800
  });
@@ -792,7 +810,7 @@ var Teleport = class {
792
810
  name
793
811
  }, {
794
812
  F: __dxlog_file4,
795
- L: 144,
813
+ L: 149,
796
814
  S: this,
797
815
  C: (f, a) => f(...a)
798
816
  });
@@ -816,7 +834,7 @@ var Teleport = class {
816
834
  _setExtension(extensionName, extension) {
817
835
  invariant3(!extensionName.includes("/"), "Invalid extension name", {
818
836
  F: __dxlog_file4,
819
- L: 168,
837
+ L: 173,
820
838
  S: this,
821
839
  A: [
822
840
  "!extensionName.includes('/')",
@@ -825,7 +843,7 @@ var Teleport = class {
825
843
  });
826
844
  invariant3(!this._extensions.has(extensionName), "Extension already exists", {
827
845
  F: __dxlog_file4,
828
- L: 169,
846
+ L: 174,
829
847
  S: this,
830
848
  A: [
831
849
  "!this._extensions.has(extensionName)",
@@ -835,16 +853,15 @@ var Teleport = class {
835
853
  this._extensions.set(extensionName, extension);
836
854
  }
837
855
  async _openExtension(extensionName) {
838
- var _a;
839
856
  log3("open extension", {
840
857
  extensionName
841
858
  }, {
842
859
  F: __dxlog_file4,
843
- L: 174,
860
+ L: 179,
844
861
  S: this,
845
862
  C: (f, a) => f(...a)
846
863
  });
847
- const extension = (_a = this._extensions.get(extensionName)) != null ? _a : failUndefined2();
864
+ const extension = this._extensions.get(extensionName) ?? failUndefined2();
848
865
  const context = {
849
866
  initiator: this.initiator,
850
867
  localPeerId: this.localPeerId,
@@ -852,7 +869,7 @@ var Teleport = class {
852
869
  createPort: async (channelName, opts) => {
853
870
  invariant3(!channelName.includes("/"), "Invalid channel name", {
854
871
  F: __dxlog_file4,
855
- L: 182,
872
+ L: 187,
856
873
  S: this,
857
874
  A: [
858
875
  "!channelName.includes('/')",
@@ -864,7 +881,7 @@ var Teleport = class {
864
881
  createStream: async (channelName, opts) => {
865
882
  invariant3(!channelName.includes("/"), "Invalid channel name", {
866
883
  F: __dxlog_file4,
867
- L: 186,
884
+ L: 191,
868
885
  S: this,
869
886
  A: [
870
887
  "!channelName.includes('/')",
@@ -884,7 +901,7 @@ var Teleport = class {
884
901
  extensionName
885
902
  }, {
886
903
  F: __dxlog_file4,
887
- L: 197,
904
+ L: 202,
888
905
  S: this,
889
906
  C: (f, a) => f(...a)
890
907
  });
@@ -1160,11 +1177,9 @@ var TestExtension = class {
1160
1177
  this.closed = new Trigger2();
1161
1178
  }
1162
1179
  get remotePeerId() {
1163
- var _a;
1164
- return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
1180
+ return this.extensionContext?.remotePeerId;
1165
1181
  }
1166
1182
  async onOpen(context) {
1167
- var _a, _b;
1168
1183
  log5("onOpen", {
1169
1184
  localPeerId: context.localPeerId,
1170
1185
  remotePeerId: context.remotePeerId
@@ -1199,11 +1214,10 @@ var TestExtension = class {
1199
1214
  timeout: 2e3
1200
1215
  });
1201
1216
  await this._rpc.open();
1202
- await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
1217
+ await this.callbacks.onOpen?.();
1203
1218
  this.open.wake();
1204
1219
  }
1205
1220
  async onClose(err) {
1206
- var _a, _b, _c;
1207
1221
  log5("onClose", {
1208
1222
  err
1209
1223
  }, {
@@ -1212,9 +1226,9 @@ var TestExtension = class {
1212
1226
  S: this,
1213
1227
  C: (f, a) => f(...a)
1214
1228
  });
1215
- await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
1229
+ await this.callbacks.onClose?.();
1216
1230
  this.closed.wake();
1217
- await ((_c = this._rpc) == null ? void 0 : _c.close());
1231
+ await this._rpc?.close();
1218
1232
  }
1219
1233
  async test(message = "test") {
1220
1234
  await this.open.wait({
@@ -1237,8 +1251,7 @@ var TestExtension = class {
1237
1251
  * Force-close the connection.
1238
1252
  */
1239
1253
  async closeConnection(err) {
1240
- var _a;
1241
- (_a = this.extensionContext) == null ? void 0 : _a.close(err);
1254
+ this.extensionContext?.close(err);
1242
1255
  }
1243
1256
  };
1244
1257
 
@@ -1258,8 +1271,7 @@ var TestExtensionWithStreams = class {
1258
1271
  this._streams = /* @__PURE__ */ new Map();
1259
1272
  }
1260
1273
  get remotePeerId() {
1261
- var _a;
1262
- return (_a = this.extensionContext) == null ? void 0 : _a.remotePeerId;
1274
+ return this.extensionContext?.remotePeerId;
1263
1275
  }
1264
1276
  async _openStream(streamTag, interval = 5, chunkSize = 2048) {
1265
1277
  invariant6(!this._streams.has(streamTag), `Stream already exists: ${streamTag}`, {
@@ -1310,7 +1322,6 @@ var TestExtensionWithStreams = class {
1310
1322
  networkStream.removeAllListeners();
1311
1323
  });
1312
1324
  streamEntry.reportingTimer = setInterval(() => {
1313
- var _a, _b;
1314
1325
  const { bytesSent, bytesReceived, sendErrors, receiveErrors } = streamEntry;
1315
1326
  log6.trace("dxos.test.stream-stats", {
1316
1327
  streamTag,
@@ -1318,8 +1329,8 @@ var TestExtensionWithStreams = class {
1318
1329
  bytesReceived,
1319
1330
  sendErrors,
1320
1331
  receiveErrors,
1321
- from: (_a = this.extensionContext) == null ? void 0 : _a.localPeerId,
1322
- to: (_b = this.extensionContext) == null ? void 0 : _b.remotePeerId
1332
+ from: this.extensionContext?.localPeerId,
1333
+ to: this.extensionContext?.remotePeerId
1323
1334
  }, {
1324
1335
  F: __dxlog_file7,
1325
1336
  L: 91,
@@ -1349,11 +1360,10 @@ var TestExtensionWithStreams = class {
1349
1360
  bytesReceived,
1350
1361
  sendErrors,
1351
1362
  receiveErrors,
1352
- runningTime: Date.now() - (startTimestamp != null ? startTimestamp : 0)
1363
+ runningTime: Date.now() - (startTimestamp ?? 0)
1353
1364
  };
1354
1365
  }
1355
1366
  async onOpen(context) {
1356
- var _a, _b;
1357
1367
  log6("onOpen", {
1358
1368
  localPeerId: context.localPeerId,
1359
1369
  remotePeerId: context.remotePeerId
@@ -1400,11 +1410,10 @@ var TestExtensionWithStreams = class {
1400
1410
  timeout: 2e3
1401
1411
  });
1402
1412
  await this._rpc.open();
1403
- await ((_b = (_a = this.callbacks).onOpen) == null ? void 0 : _b.call(_a));
1413
+ await this.callbacks.onOpen?.();
1404
1414
  this.open.wake();
1405
1415
  }
1406
1416
  async onClose(err) {
1407
- var _a, _b, _c;
1408
1417
  log6("onClose", {
1409
1418
  err
1410
1419
  }, {
@@ -1413,7 +1422,7 @@ var TestExtensionWithStreams = class {
1413
1422
  S: this,
1414
1423
  C: (f, a) => f(...a)
1415
1424
  });
1416
- await ((_b = (_a = this.callbacks).onClose) == null ? void 0 : _b.call(_a));
1425
+ await this.callbacks.onClose?.();
1417
1426
  this.closed.wake();
1418
1427
  for (const [streamTag, stream] of Object.entries(this._streams)) {
1419
1428
  log6("closing stream", {
@@ -1427,7 +1436,7 @@ var TestExtensionWithStreams = class {
1427
1436
  clearTimeout(stream.interval);
1428
1437
  stream.networkStream.destroy();
1429
1438
  }
1430
- await ((_c = this._rpc) == null ? void 0 : _c.close());
1439
+ await this._rpc?.close();
1431
1440
  }
1432
1441
  async addNewStream(streamLoadInterval, streamLoadChunkSize, streamTag) {
1433
1442
  await this.open.wait({
@@ -1488,8 +1497,7 @@ var TestExtensionWithStreams = class {
1488
1497
  * Force-close the connection.
1489
1498
  */
1490
1499
  async closeConnection(err) {
1491
- var _a;
1492
- (_a = this.extensionContext) == null ? void 0 : _a.close(err);
1500
+ this.extensionContext?.close(err);
1493
1501
  }
1494
1502
  };
1495
1503
 
@@ -1505,4 +1513,4 @@ export {
1505
1513
  TestExtension,
1506
1514
  TestExtensionWithStreams
1507
1515
  };
1508
- //# sourceMappingURL=chunk-3FNN6ZOF.mjs.map
1516
+ //# sourceMappingURL=chunk-2MN5W64H.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/testing/test-builder.ts", "../../../src/teleport.ts", "../../../src/muxing/framer.ts", "../../../src/muxing/muxer.ts", "../../../src/muxing/balancer.ts", "../../../src/testing/test-extension.ts", "../../../src/testing/test-extension-with-streams.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex, pipeline } from 'node:stream';\n\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { Teleport } from '../teleport';\n\ntype CreatePeerOpts<T extends TestPeer> = {\n factory: () => T;\n};\n\nexport class TestBuilder {\n private readonly _peers = new Set<TestPeer>();\n\n createPeer<T extends TestPeer>(opts: CreatePeerOpts<T>): T {\n const peer = opts.factory();\n this._peers.add(peer);\n return peer;\n }\n\n *createPeers<T extends TestPeer>(opts: CreatePeerOpts<T>): Generator<T> {\n while (true) {\n yield this.createPeer(opts);\n }\n }\n\n async destroy() {\n await Promise.all(Array.from(this._peers).map((agent) => agent.destroy()));\n }\n\n async connect(peer1: TestPeer, peer2: TestPeer) {\n invariant(peer1 !== peer2);\n invariant(this._peers.has(peer1));\n invariant(this._peers.has(peer1));\n\n const connection1 = peer1.createConnection({ initiator: true, remotePeerId: peer2.peerId });\n const connection2 = peer2.createConnection({ initiator: false, remotePeerId: peer1.peerId });\n\n pipeStreams(connection1.teleport.stream, connection2.teleport.stream);\n await Promise.all([peer1.openConnection(connection1), peer2.openConnection(connection2)]);\n\n return [connection1, connection2];\n }\n\n async disconnect(peer1: TestPeer, peer2: TestPeer) {\n invariant(peer1 !== peer2);\n invariant(this._peers.has(peer1));\n invariant(this._peers.has(peer1));\n\n const connection1 = Array.from(peer1.connections).find((connection) =>\n connection.remotePeerId.equals(peer2.peerId),\n );\n const connection2 = Array.from(peer2.connections).find((connection) =>\n connection.remotePeerId.equals(peer1.peerId),\n );\n\n invariant(connection1);\n invariant(connection2);\n\n await Promise.all([peer1.closeConnection(connection1), peer2.closeConnection(connection2)]);\n }\n}\n\nexport class TestPeer {\n public readonly connections = new Set<TestConnection>();\n\n constructor(public readonly peerId: PublicKey = PublicKey.random()) {}\n\n protected async onOpen(connection: TestConnection) {}\n protected async onClose(connection: TestConnection) {}\n\n createConnection({ initiator, remotePeerId }: { initiator: boolean; remotePeerId: PublicKey }) {\n const connection = new TestConnection(this.peerId, remotePeerId, initiator);\n this.connections.add(connection);\n return connection;\n }\n\n async openConnection(connection: TestConnection) {\n invariant(this.connections.has(connection));\n await connection.teleport.open();\n await this.onOpen(connection);\n }\n\n async closeConnection(connection: TestConnection) {\n invariant(this.connections.has(connection));\n await this.onClose(connection);\n await connection.teleport.close();\n this.connections.delete(connection);\n }\n\n async destroy() {\n for (const teleport of this.connections) {\n await this.closeConnection(teleport);\n }\n }\n}\n\nconst pipeStreams = (stream1: Duplex, stream2: Duplex) => {\n pipeline(stream1, stream2, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n pipeline(stream2, stream1, (err) => {\n if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {\n log.catch(err);\n }\n });\n};\n\nexport class TestConnection {\n public teleport: Teleport;\n\n constructor(\n public readonly localPeerId: PublicKey,\n public readonly remotePeerId: PublicKey,\n public readonly initiator: boolean,\n ) {\n this.teleport = new Teleport({\n initiator,\n localPeerId,\n remotePeerId,\n });\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { asyncTimeout, scheduleTaskInterval, runInContextAsync, synchronized, scheduleTask, Event } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\nimport { schema, RpcClosedError } from '@dxos/protocols';\nimport { ControlService } from '@dxos/protocols/proto/dxos/mesh/teleport/control';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\nimport { Callback } from '@dxos/util';\n\nimport { CreateChannelOpts, Muxer, MuxerStats, RpcPort } from './muxing';\n\nexport type TeleportParams = {\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n};\n\nexport class Teleport {\n public readonly initiator: boolean;\n public readonly localPeerId: PublicKey;\n public readonly remotePeerId: PublicKey;\n\n private readonly _ctx = new Context({\n onError: (err) => {\n void this.destroy(err).catch(() => {\n log.error('Error during destroy', err);\n });\n },\n });\n\n private readonly _muxer = new Muxer();\n\n private readonly _control = new ControlExtension({\n heartbeatInterval: 10_000,\n heartbeatTimeout: 10_000,\n onTimeout: () => {\n this.destroy(new Error('Connection timed out')).catch((err) => log.catch(err));\n },\n });\n\n private readonly _extensions = new Map<string, TeleportExtension>();\n private readonly _remoteExtensions = new Set<string>();\n\n private _open = false;\n\n constructor({ initiator, localPeerId, remotePeerId }: TeleportParams) {\n invariant(typeof initiator === 'boolean');\n invariant(PublicKey.isPublicKey(localPeerId));\n invariant(PublicKey.isPublicKey(remotePeerId));\n this.initiator = initiator;\n this.localPeerId = localPeerId;\n this.remotePeerId = remotePeerId;\n\n this._control.onExtensionRegistered.set(async (name) => {\n log('remote extension', { name });\n invariant(!this._remoteExtensions.has(name), 'Remote extension already exists');\n this._remoteExtensions.add(name);\n\n if (this._extensions.has(name)) {\n try {\n await this._openExtension(name);\n } catch (err: any) {\n await this.destroy(err);\n }\n }\n });\n\n {\n // Destroy Teleport when the stream is closed.\n this._muxer.stream.on('close', async () => {\n await this.destroy();\n });\n\n this._muxer.stream.on('error', async (err) => {\n await this.destroy(err);\n });\n }\n\n // let last: MuxerStats | undefined;\n this._muxer.statsUpdated.on((stats) => {\n log.trace('dxos.mesh.teleport.stats', {\n localPeerId,\n remotePeerId,\n bytesSent: stats.bytesSent,\n bytesSentRate: stats.bytesSentRate,\n bytesReceived: stats.bytesReceived,\n bytesReceivedRate: stats.bytesReceivedRate,\n channels: stats.channels,\n });\n\n // last = stats;\n });\n }\n\n get stream(): Duplex {\n return this._muxer.stream;\n }\n\n get stats(): Event<MuxerStats> {\n return this._muxer.statsUpdated;\n }\n\n /**\n * Blocks until the handshake is complete.\n */\n async open() {\n this._setExtension('dxos.mesh.teleport.control', this._control);\n await this._openExtension('dxos.mesh.teleport.control');\n this._open = true;\n }\n\n async close(err?: Error) {\n // TODO(dmaretskyi): Try soft close.\n await this.destroy(err);\n }\n\n @synchronized\n async destroy(err?: Error) {\n if (this._ctx.disposed) {\n return;\n }\n\n await this._ctx.dispose();\n\n for (const extension of this._extensions.values()) {\n try {\n await extension.onClose(err);\n } catch (err: any) {\n log.catch(err);\n }\n }\n\n this._muxer.destroy(err);\n }\n\n addExtension(name: string, extension: TeleportExtension) {\n if (!this._open) {\n throw new Error('Not open');\n }\n\n log('addExtension', { name });\n this._setExtension(name, extension);\n\n // Perform the registration in a separate tick as this might block while the remote side is opening the extension.\n scheduleTask(this._ctx, async () => {\n try {\n await this._control.registerExtension(name);\n } catch (err) {\n if (err instanceof RpcClosedError) {\n return;\n }\n throw err;\n }\n });\n\n if (this._remoteExtensions.has(name)) {\n // Open the extension in a separate tick.\n scheduleTask(this._ctx, async () => {\n await this._openExtension(name);\n });\n }\n }\n\n private _setExtension(extensionName: string, extension: TeleportExtension) {\n invariant(!extensionName.includes('/'), 'Invalid extension name');\n invariant(!this._extensions.has(extensionName), 'Extension already exists');\n this._extensions.set(extensionName, extension);\n }\n\n private async _openExtension(extensionName: string) {\n log('open extension', { extensionName });\n const extension = this._extensions.get(extensionName) ?? failUndefined();\n\n const context: ExtensionContext = {\n initiator: this.initiator,\n localPeerId: this.localPeerId,\n remotePeerId: this.remotePeerId,\n createPort: async (channelName: string, opts?: CreateChannelOpts) => {\n invariant(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createPort(`${extensionName}/${channelName}`, opts);\n },\n createStream: async (channelName: string, opts?: CreateChannelOpts) => {\n invariant(!channelName.includes('/'), 'Invalid channel name');\n return this._muxer.createStream(`${extensionName}/${channelName}`, opts);\n },\n close: (err) => {\n void runInContextAsync(this._ctx, async () => {\n await this.close(err);\n });\n },\n };\n\n await extension.onOpen(context);\n log('extension opened', { extensionName });\n }\n}\n\nexport type ExtensionContext = {\n /**\n * One of the peers will be designated an initiator.\n */\n initiator: boolean;\n localPeerId: PublicKey;\n remotePeerId: PublicKey;\n createStream(tag: string, opts?: CreateChannelOpts): Promise<Duplex>;\n createPort(tag: string, opts?: CreateChannelOpts): Promise<RpcPort>;\n close(err?: Error): void;\n};\n\nexport interface TeleportExtension {\n onOpen(context: ExtensionContext): Promise<void>;\n onClose(err?: Error): Promise<void>;\n}\n\ntype ControlRpcBundle = {\n Control: ControlService;\n};\n\ntype ControlExtensionOpts = {\n heartbeatInterval: number;\n heartbeatTimeout: number;\n onTimeout: () => void;\n};\n\nclass ControlExtension implements TeleportExtension {\n private readonly _ctx = new Context({\n onError: (err) => {\n this._extensionContext.close(err);\n },\n });\n\n public readonly onExtensionRegistered = new Callback<(extensionName: string) => void>();\n\n private _extensionContext!: ExtensionContext;\n private _rpc!: ProtoRpcPeer<{ Control: ControlService }>;\n\n constructor(private readonly opts: ControlExtensionOpts) {}\n\n async registerExtension(name: string) {\n await this._rpc.rpc.Control.registerExtension({ name });\n }\n\n async onOpen(extensionContext: ExtensionContext): Promise<void> {\n this._extensionContext = extensionContext;\n\n // NOTE: Make sure that RPC timeout is greater than the heartbeat timeout.\n // TODO(dmaretskyi): Allow overwriting the timeout on individual RPC calls?\n this._rpc = createProtoRpcPeer<ControlRpcBundle, ControlRpcBundle>({\n requested: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService'),\n },\n exposed: {\n Control: schema.getService('dxos.mesh.teleport.control.ControlService'),\n },\n handlers: {\n Control: {\n registerExtension: async (request) => {\n this.onExtensionRegistered.call(request.name);\n },\n heartbeat: async (request) => {\n // Ok.\n },\n },\n },\n port: await extensionContext.createPort('rpc', {\n contentType: 'application/x-protobuf; messagType=\"dxos.rpc.Message\"',\n }),\n });\n\n await this._rpc.open();\n\n scheduleTaskInterval(\n this._ctx,\n async () => {\n try {\n await asyncTimeout(this._rpc.rpc.Control.heartbeat(), this.opts.heartbeatTimeout);\n } catch (err: any) {\n this.opts.onTimeout();\n }\n },\n this.opts.heartbeatInterval,\n );\n }\n\n async onClose(err?: Error): Promise<void> {\n await this._ctx.dispose();\n await this._rpc.close();\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { invariant } from '@dxos/invariant';\n\nimport { RpcPort } from './rpc-port';\n\nconst FRAME_LENGTH_SIZE = 2;\n\n/**\n * Framer that turns a stream of binary messages into a framed RpcPort.\n *\n * Buffers are written prefixed by their length encoded as a varint.\n */\nexport class Framer {\n // private readonly _tagBuffer = Buffer.alloc(4)\n private _messageCb?: (msg: Uint8Array) => void;\n private _subscribeCb?: () => void;\n private _buffer?: Buffer; // The rest of the bytes from the previous write call.\n private _sendCallbacks: (() => void)[] = [];\n\n private _bytesSent = 0;\n private _bytesReceived = 0;\n\n private readonly _stream = new Duplex({\n objectMode: false,\n read: () => {\n this._processResponseQueue();\n },\n write: (chunk, encoding, callback) => {\n invariant(!this._subscribeCb, 'Internal Framer bug. Concurrent writes detected.');\n\n this._bytesReceived += chunk.length;\n\n if (this._buffer && this._buffer.length > 0) {\n this._buffer = Buffer.concat([this._buffer, chunk]);\n } else {\n this._buffer = chunk;\n }\n\n if (this._messageCb) {\n this._popFrames();\n callback();\n } else {\n this._subscribeCb = () => {\n // Schedule the processing of the chunk after the peer subscribes to the messages.\n this._popFrames();\n this._subscribeCb = undefined;\n callback();\n };\n }\n },\n });\n\n public readonly port: RpcPort = {\n send: (message) => {\n // log('write', { len: message.length, frame: Buffer.from(message).toString('hex') })\n return new Promise<void>((resolve) => {\n const frame = encodeFrame(message);\n this._bytesSent += frame.length;\n const canContinue = this._stream.push(frame);\n if (!canContinue) {\n this._sendCallbacks.push(resolve);\n } else {\n resolve();\n }\n });\n },\n subscribe: (callback) => {\n invariant(!this._messageCb, 'Rpc port already has a message listener.');\n this._messageCb = callback;\n this._subscribeCb?.();\n return () => {\n this._messageCb = undefined;\n };\n },\n };\n\n get stream(): Duplex {\n return this._stream;\n }\n\n get bytesSent() {\n return this._bytesSent;\n }\n\n get bytesReceived() {\n return this._bytesReceived;\n }\n\n private _processResponseQueue() {\n const responseQueue = this._sendCallbacks;\n this._sendCallbacks = [];\n responseQueue.forEach((cb) => cb());\n }\n\n /**\n * Attempts to pop frames from the buffer and call the message callback.\n */\n private _popFrames() {\n let offset = 0;\n while (offset < this._buffer!.length) {\n const frame = decodeFrame(this._buffer!, offset);\n\n if (!frame) {\n break; // Couldn't read frame but there are still bytes left in the buffer.\n }\n offset += frame.bytesConsumed;\n // TODO(dmaretskyi): Possible bug if the peer unsubscribes while we're reading frames.\n // log('read', { len: frame.payload.length, frame: Buffer.from(frame.payload).toString('hex') })\n this._messageCb!(frame.payload);\n }\n\n if (offset < this._buffer!.length) {\n // Save the rest of the bytes for the next write call.\n this._buffer = this._buffer!.subarray(offset);\n } else {\n this._buffer = undefined;\n }\n }\n\n destroy() {\n // TODO(dmaretskyi): Call stream.end() instead?\n this._stream.destroy();\n }\n}\n\n/**\n * Attempts to read a frame from the input buffer.\n */\nexport const decodeFrame = (buffer: Buffer, offset: number): { payload: Buffer; bytesConsumed: number } | undefined => {\n if (buffer.length < offset + FRAME_LENGTH_SIZE) {\n // Not enough bytes to read the frame length.\n return undefined;\n }\n\n const frameLength = buffer.readUInt16BE(offset);\n const bytesConsumed = FRAME_LENGTH_SIZE + frameLength;\n\n if (buffer.length < offset + bytesConsumed) {\n // Not enough bytes to read the frame.\n return undefined;\n }\n\n const payload = buffer.subarray(offset + FRAME_LENGTH_SIZE, offset + bytesConsumed);\n\n return {\n payload,\n bytesConsumed,\n };\n};\n\nexport const encodeFrame = (payload: Uint8Array): Buffer => {\n const frame = Buffer.allocUnsafe(FRAME_LENGTH_SIZE + payload.length);\n frame.writeUInt16BE(payload.length, 0);\n frame.set(payload, FRAME_LENGTH_SIZE);\n return frame;\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { Duplex } from 'node:stream';\n\nimport { scheduleTaskInterval, Event, Trigger } from '@dxos/async';\nimport { Context } from '@dxos/context';\nimport { failUndefined } from '@dxos/debug';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';\nimport { Command } from '@dxos/protocols/proto/dxos/mesh/muxer';\n\nimport { Balancer } from './balancer';\nimport { RpcPort } from './rpc-port';\n\nconst Command = schema.getCodecForType('dxos.mesh.muxer.Command');\n\nexport type CleanupCb = void | (() => void);\n\nexport type CreateChannelOpts = {\n /**\n * MIME type of the wire content.\n *\n * Examples:\n * - application/octet-stream\n * - application/x-protobuf; messageType=\"dxos.rpc.Message\"\n */\n contentType?: string;\n};\n\nexport type MuxerStats = {\n timestamp: number;\n channels: ConnectionInfo.StreamStats[];\n bytesSent: number;\n bytesReceived: number;\n bytesSentRate?: number;\n bytesReceivedRate?: number;\n};\n\nconst STATS_INTERVAL = 1_000;\nconst MAX_SAFE_FRAME_SIZE = 1_000_000;\nconst SYSTEM_CHANNEL_ID = 0;\n\ntype Channel = {\n /**\n * Our local channel ID.\n * Incoming Data commands will have this ID.\n */\n id: number;\n tag: string;\n\n /**\n * Remote id is set when we receive an OpenChannel command.\n * The originating Data commands should carry this id.\n */\n remoteId: null | number;\n\n contentType?: string;\n\n /**\n * Send buffer.\n */\n buffer: Uint8Array[];\n\n /**\n * Set when we initialize a NodeJS stream or an RPC port consuming the channel.\n */\n push: null | ((data: Uint8Array) => void);\n\n destroy: null | ((err?: Error) => void);\n\n stats: {\n bytesSent: number;\n bytesReceived: number;\n };\n};\n\ntype CreateChannelInternalParams = {\n tag: string;\n contentType?: string;\n};\n\n/**\n * Channel based multiplexer.\n *\n * Can be used to open a number of channels represented by streams or RPC ports.\n * Performs framing for RPC ports.\n * Will buffer data until the remote peer opens the channel.\n *\n * The API will not advertise channels that as they are opened by the remote peer.\n * A higher level API (could be build on top of this muxer) for channel discovery is required.\n */\nexport class Muxer {\n private readonly _balancer = new Balancer(SYSTEM_CHANNEL_ID);\n private readonly _channelsByLocalId = new Map<number, Channel>();\n private readonly _channelsByTag = new Map<string, Channel>();\n private readonly _ctx = new Context();\n\n private _nextId = 1;\n private _destroyed = false;\n private _destroying = false;\n\n public close = new Event<Error | undefined>();\n public statsUpdated = new Event<MuxerStats>();\n\n public readonly stream = this._balancer.stream;\n\n constructor() {\n // Add a channel for control messages.\n this._balancer.incomingData.on(async (msg) => {\n await this._handleCommand(Command.decode(msg));\n });\n\n scheduleTaskInterval(this._ctx, async () => this._emitStats(), STATS_INTERVAL);\n }\n\n /**\n * Creates a duplex Node.js-style stream.\n * The remote peer is expected to call `createStream` with the same tag.\n * The stream is immediately readable and writable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n async createStream(tag: string, opts: CreateChannelOpts = {}): Promise<Duplex> {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType,\n });\n invariant(!channel.push, `Channel already open: ${tag}`);\n\n const stream = new Duplex({\n write: (data, encoding, callback) => {\n this._sendData(channel, data)\n .then(() => callback())\n .catch(callback);\n // TODO(dmaretskyi): Should we error if sending data has errored?\n },\n read: () => {}, // No-op. We will push data when we receive it.\n });\n\n channel.push = (data) => {\n channel.stats.bytesReceived += data.length;\n stream.push(data);\n };\n channel.destroy = (err) => {\n // TODO(dmaretskyi): Call stream.end() instead?\n stream.destroy(err);\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n try {\n await this._sendCommand(\n {\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n },\n },\n SYSTEM_CHANNEL_ID,\n );\n } catch (err: any) {\n this._destroyChannel(channel, err);\n throw err;\n }\n\n return stream;\n }\n\n /**\n * Creates an RPC port.\n * The remote peer is expected to call `createPort` with the same tag.\n * The port is immediately usable.\n * NOTE: The data will be buffered until the stream is opened remotely with the same tag (may cause a memory leak).\n */\n async createPort(tag: string, opts: CreateChannelOpts = {}): Promise<RpcPort> {\n const channel = this._getOrCreateStream({\n tag,\n contentType: opts.contentType,\n });\n invariant(!channel.push, `Channel already open: ${tag}`);\n\n // We need to buffer incoming data until the port is subscribed to.\n let inboundBuffer: Uint8Array[] = [];\n let callback: ((data: Uint8Array) => void) | undefined;\n\n channel.push = (data) => {\n channel.stats.bytesReceived += data.length;\n if (callback) {\n callback(data);\n } else {\n inboundBuffer.push(data);\n }\n };\n\n const port: RpcPort = {\n send: async (data: Uint8Array) => {\n await this._sendData(channel, data);\n // TODO(dmaretskyi): Debugging.\n // appendFileSync('log.json', JSON.stringify(schema.getCodecForType('dxos.rpc.RpcMessage').decode(data), null, 2) + '\\n')\n },\n subscribe: (cb: (data: Uint8Array) => void) => {\n invariant(!callback, 'Only one subscriber is allowed');\n callback = cb;\n for (const data of inboundBuffer) {\n cb(data);\n }\n inboundBuffer = [];\n },\n };\n\n // NOTE: Make sure channel.push is set before sending the command.\n try {\n await this._sendCommand(\n {\n openChannel: {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n },\n },\n SYSTEM_CHANNEL_ID,\n );\n } catch (err: any) {\n this._destroyChannel(channel, err);\n throw err;\n }\n\n return port;\n }\n\n /**\n * Force-close with optional error.\n */\n destroy(err?: Error) {\n if (this._destroying) {\n return;\n }\n this._destroying = true;\n\n this._sendCommand(\n {\n destroy: {\n error: err?.message,\n },\n },\n SYSTEM_CHANNEL_ID,\n )\n .then(() => {\n this._dispose();\n })\n .catch((err: any) => {\n this._dispose(err);\n });\n void this._ctx.dispose();\n }\n\n private _dispose(err?: Error) {\n if (this._destroyed) {\n return;\n }\n\n this._destroyed = true;\n this._balancer.destroy();\n\n for (const channel of this._channelsByTag.values()) {\n channel.destroy?.(err);\n }\n\n this.close.emit(err);\n\n // Make it easy for GC.\n this._channelsByLocalId.clear();\n this._channelsByTag.clear();\n }\n\n private async _handleCommand(cmd: Command) {\n log('Received command', { cmd });\n\n if (this._destroyed || this._destroying) {\n if (cmd.destroy) {\n return;\n }\n\n log.warn('Received command after destroy', { cmd });\n return;\n }\n\n if (cmd.openChannel) {\n const channel = this._getOrCreateStream({\n tag: cmd.openChannel.tag,\n contentType: cmd.openChannel.contentType,\n });\n channel.remoteId = cmd.openChannel.id;\n\n // Flush any buffered data.\n for (const data of channel.buffer) {\n await this._sendCommand(\n {\n data: {\n channelId: channel.remoteId!,\n data,\n },\n },\n channel.id,\n );\n }\n channel.buffer = [];\n } else if (cmd.data) {\n const stream = this._channelsByLocalId.get(cmd.data.channelId) ?? failUndefined();\n if (!stream.push) {\n log.warn('Received data for channel before it was opened', { tag: stream.tag });\n return;\n }\n stream.push(cmd.data.data);\n } else if (cmd.destroy) {\n this._dispose();\n }\n }\n\n private async _sendCommand(cmd: Command, channelId = -1) {\n try {\n const trigger = new Trigger<void>();\n this._balancer.pushData(Command.encode(cmd), trigger, channelId);\n await trigger.wait();\n } catch (err: any) {\n this.destroy(err);\n }\n }\n\n private _getOrCreateStream(params: CreateChannelInternalParams): Channel {\n let channel = this._channelsByTag.get(params.tag);\n if (!channel) {\n channel = {\n id: this._nextId++,\n remoteId: null,\n tag: params.tag,\n contentType: params.contentType,\n buffer: [],\n push: null,\n destroy: null,\n stats: {\n bytesSent: 0,\n bytesReceived: 0,\n },\n };\n this._channelsByTag.set(channel.tag, channel);\n this._channelsByLocalId.set(channel.id, channel);\n this._balancer.addChannel(channel.id);\n }\n\n return channel;\n }\n\n private async _sendData(channel: Channel, data: Uint8Array): Promise<void> {\n if (data.length > MAX_SAFE_FRAME_SIZE) {\n log.warn('frame size exceeds maximum safe value', { size: data.length, threshold: MAX_SAFE_FRAME_SIZE });\n }\n\n channel.stats.bytesSent += data.length;\n if (channel.remoteId === null) {\n // Remote side has not opened the channel yet.\n channel.buffer.push(data);\n return;\n }\n await this._sendCommand(\n {\n data: {\n channelId: channel.remoteId,\n data,\n },\n },\n channel.id,\n );\n }\n\n private _destroyChannel(channel: Channel, err?: Error) {\n if (channel.destroy) {\n channel.destroy(err);\n }\n\n this._channelsByLocalId.delete(channel.id);\n this._channelsByTag.delete(channel.tag);\n }\n\n private _lastStats?: MuxerStats;\n private readonly _lastChannelStats = new Map<number, Channel['stats']>();\n\n private async _emitStats() {\n if (this._destroyed || this._destroying) {\n this._lastStats = undefined;\n this._lastChannelStats.clear();\n return;\n }\n\n const bytesSent = this._balancer.bytesSent;\n const bytesReceived = this._balancer.bytesReceived;\n\n const now = Date.now();\n const interval = this._lastStats ? (now - this._lastStats.timestamp) / 1_000 : 0;\n const calculateThroughput = (current: Channel['stats'], last: Channel['stats'] | undefined) =>\n last\n ? {\n bytesSentRate: interval ? (current.bytesSent - last.bytesSent) / interval : undefined,\n bytesReceivedRate: interval ? (current.bytesReceived - last.bytesReceived) / interval : undefined,\n }\n : {};\n\n this._lastStats = {\n timestamp: now,\n channels: Array.from(this._channelsByTag.values()).map((channel) => {\n const stats: ConnectionInfo.StreamStats = {\n id: channel.id,\n tag: channel.tag,\n contentType: channel.contentType,\n bytesSent: channel.stats.bytesSent,\n bytesReceived: channel.stats.bytesReceived,\n ...calculateThroughput(channel.stats, this._lastChannelStats.get(channel.id)),\n };\n\n this._lastChannelStats.set(channel.id, stats);\n return stats;\n }),\n bytesSent,\n bytesReceived,\n ...calculateThroughput({ bytesSent, bytesReceived }, this._lastStats),\n };\n\n this.statsUpdated.emit(this._lastStats);\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as varint from 'varint';\n\nimport { Trigger, Event } from '@dxos/async';\nimport { log } from '@dxos/log';\n\nimport { Framer } from './framer';\n\nconst MAX_CHUNK_SIZE = 8192;\n\ntype Chunk = {\n chunk: Uint8Array;\n channelId: number;\n dataLength?: number;\n};\n\ntype ChunkEnvelope = {\n msg: Buffer;\n trigger?: Trigger;\n};\n\ntype ChannelBuffer = {\n buffer: Buffer;\n msgLength: number;\n};\n\n/**\n * Load balancer for handling asynchronous calls from multiple channels.\n *\n * Manages a queue of calls from different channels and ensures that the calls\n * are processed in a balanced manner in a round-robin fashion.\n */\nexport class Balancer {\n private _lastCallerIndex = 0;\n private _channels: number[] = [];\n\n private readonly _framer = new Framer();\n // TODO(egorgripasov): Will cause a memory leak if channels do not appreciate the backpressure.\n private readonly _sendBuffers: Map<number, ChunkEnvelope[]> = new Map();\n private readonly _receiveBuffers = new Map<number, ChannelBuffer>();\n\n public incomingData = new Event<Uint8Array>();\n public readonly stream = this._framer.stream;\n\n constructor(private readonly _sysChannelId: number) {\n this._channels.push(_sysChannelId);\n\n // Handle incoming messages.\n this._framer.port.subscribe(this._processIncomingMessage.bind(this));\n }\n\n get bytesSent() {\n return this._framer.bytesSent;\n }\n\n get bytesReceived() {\n return this._framer.bytesReceived;\n }\n\n addChannel(channel: number) {\n this._channels.push(channel);\n }\n\n pushData(data: Uint8Array, trigger: Trigger, channelId: number) {\n const noCalls = this._sendBuffers.size === 0;\n\n if (!this._channels.includes(channelId)) {\n throw new Error(`Unknown channel ${channelId}`);\n }\n\n if (!this._sendBuffers.has(channelId)) {\n this._sendBuffers.set(channelId, []);\n }\n\n const sendBuffer = this._sendBuffers.get(channelId)!;\n\n const chunks = [];\n for (let idx = 0; idx < data.length; idx += MAX_CHUNK_SIZE) {\n chunks.push(data.subarray(idx, idx + MAX_CHUNK_SIZE));\n }\n\n chunks.forEach((chunk, index) => {\n const msg = encodeChunk({\n chunk,\n channelId,\n dataLength: index === 0 ? data.length : undefined,\n });\n sendBuffer.push({ msg, trigger: index === chunks.length - 1 ? trigger : undefined });\n });\n\n // Start processing calls if this is the first call.\n if (noCalls) {\n this._sendChunks().catch((err) => log.catch(err));\n }\n }\n\n destroy() {\n this._sendBuffers.clear();\n this._framer.destroy();\n }\n\n private _processIncomingMessage(msg: Uint8Array) {\n const { channelId, dataLength, chunk } = decodeChunk(msg, (channelId) => !this._receiveBuffers.has(channelId));\n if (!this._receiveBuffers.has(channelId)) {\n if (chunk.length < dataLength!) {\n this._receiveBuffers.set(channelId, {\n buffer: Buffer.from(chunk),\n msgLength: dataLength!,\n });\n } else {\n this.incomingData.emit(chunk);\n }\n } else {\n const channelBuffer = this._receiveBuffers.get(channelId)!;\n channelBuffer.buffer = Buffer.concat([channelBuffer.buffer, chunk]);\n if (channelBuffer.buffer.length < channelBuffer.msgLength) {\n return;\n }\n const msg = channelBuffer.buffer;\n this._receiveBuffers.delete(channelId);\n this.incomingData.emit(msg);\n }\n }\n\n private _getNextCallerId() {\n if (this._sendBuffers.has(this._sysChannelId)) {\n return this._sysChannelId;\n }\n\n const index = this._lastCallerIndex;\n this._lastCallerIndex = (this._lastCallerIndex + 1) % this._channels.length;\n\n return this._channels[index];\n }\n\n private _getNextChunk(): ChunkEnvelope {\n let chunk;\n while (!chunk) {\n const channelId = this._getNextCallerId();\n const sendBuffer = this._sendBuffers.get(channelId);\n if (!sendBuffer) {\n continue;\n }\n\n chunk = sendBuffer.shift();\n if (sendBuffer.length === 0) {\n this._sendBuffers.delete(channelId);\n }\n }\n return chunk;\n }\n\n private async _sendChunks() {\n if (this._sendBuffers.size === 0) {\n return;\n }\n\n const chunk = this._getNextChunk();\n\n try {\n await this._framer.port.send(chunk.msg);\n chunk.trigger?.wake();\n } catch (err: any) {\n chunk.trigger?.throw(err);\n }\n\n await this._sendChunks();\n }\n}\n\nexport const encodeChunk = ({ channelId, dataLength, chunk }: Chunk): Buffer => {\n const channelTagLength = varint.encodingLength(channelId);\n const dataLengthLength = dataLength ? varint.encodingLength(dataLength) : 0;\n const message = Buffer.allocUnsafe(channelTagLength + dataLengthLength + chunk.length);\n varint.encode(channelId, message);\n if (dataLength) {\n varint.encode(dataLength, message, channelTagLength);\n }\n message.set(chunk, channelTagLength + dataLengthLength);\n return message;\n};\n\nexport const decodeChunk = (data: Uint8Array, withLength: (channelId: number) => boolean): Chunk => {\n const channelId = varint.decode(data);\n let dataLength: number | undefined;\n let offset = varint.decode.bytes;\n\n if (withLength(channelId)) {\n dataLength = varint.decode(data, offset);\n offset += varint.decode.bytes;\n }\n\n const chunk = data.subarray(offset);\n\n return { channelId, dataLength, chunk };\n};\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { asyncTimeout, Trigger } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { TestService } from '@dxos/protocols/proto/example/testing/rpc';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from '../teleport';\n\ninterface TestExtensionCallbacks {\n onOpen?: () => Promise<void>;\n onClose?: () => Promise<void>;\n}\n\nexport class TestExtension implements TeleportExtension {\n public readonly open = new Trigger();\n public readonly closed = new Trigger();\n public extensionContext: ExtensionContext | undefined;\n private _rpc!: ProtoRpcPeer<{ TestService: TestService }>;\n\n constructor(public readonly callbacks: TestExtensionCallbacks = {}) {}\n\n get remotePeerId() {\n return this.extensionContext?.remotePeerId;\n }\n\n async onOpen(context: ExtensionContext) {\n log('onOpen', { localPeerId: context.localPeerId, remotePeerId: context.remotePeerId });\n this.extensionContext = context;\n this._rpc = createProtoRpcPeer<{ TestService: TestService }, { TestService: TestService }>({\n port: await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n requested: {\n TestService: schema.getService('example.testing.rpc.TestService'),\n },\n exposed: {\n TestService: schema.getService('example.testing.rpc.TestService'),\n },\n handlers: {\n TestService: {\n voidCall: async (request) => {\n // Ok.\n },\n testCall: async (request) => {\n return {\n data: request.data,\n };\n },\n },\n },\n timeout: 2000,\n });\n\n await this._rpc.open();\n await this.callbacks.onOpen?.();\n\n this.open.wake();\n }\n\n async onClose(err?: Error) {\n log('onClose', { err });\n await this.callbacks.onClose?.();\n this.closed.wake();\n await this._rpc?.close();\n }\n\n async test(message = 'test') {\n await this.open.wait({ timeout: 1500 });\n const res = await asyncTimeout(this._rpc.rpc.TestService.testCall({ data: message }), 1500);\n invariant(res.data === message);\n }\n\n /**\n * Force-close the connection.\n */\n async closeConnection(err?: Error) {\n this.extensionContext?.close(err);\n }\n}\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { randomBytes } from 'node:crypto';\nimport { Duplex } from 'node:stream';\n\nimport { Trigger } from '@dxos/async';\nimport { invariant } from '@dxos/invariant';\nimport { log } from '@dxos/log';\nimport { schema } from '@dxos/protocols';\nimport { TestServiceWithStreams } from '@dxos/protocols/proto/example/testing/rpc';\nimport { createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from '../teleport';\n\ninterface TestExtensionWithStreamsCallbacks {\n onOpen?: () => Promise<void>;\n onClose?: () => Promise<void>;\n}\n\nexport class TestExtensionWithStreams implements TeleportExtension {\n public readonly open = new Trigger();\n public readonly closed = new Trigger();\n private readonly _streams = new Map<string, TestStream>();\n\n public extensionContext: ExtensionContext | undefined;\n private _rpc!: ProtoRpcPeer<{ TestServiceWithStreams: TestServiceWithStreams }>;\n\n constructor(public readonly callbacks: TestExtensionWithStreamsCallbacks = {}) {}\n\n get remotePeerId() {\n return this.extensionContext?.remotePeerId;\n }\n\n private async _openStream(streamTag: string, interval = 5, chunkSize = 2048) {\n invariant(!this._streams.has(streamTag), `Stream already exists: ${streamTag}`);\n\n const networkStream = await this.extensionContext!.createStream(streamTag, {\n contentType: 'application/x-test-stream',\n });\n\n const streamEntry: TestStream = {\n networkStream,\n bytesSent: 0,\n bytesReceived: 0,\n sendErrors: 0,\n receiveErrors: 0,\n startTimestamp: Date.now(),\n };\n\n const pushChunk = () => {\n streamEntry.timer = setTimeout(() => {\n const chunk = randomBytes(chunkSize);\n\n if (\n !networkStream.write(chunk, 'binary', (err) => {\n if (!err) {\n streamEntry.bytesSent += chunk.length;\n } else {\n streamEntry.sendErrors += 1;\n }\n })\n ) {\n networkStream.once('drain', pushChunk);\n } else {\n process.nextTick(pushChunk);\n }\n }, interval);\n };\n\n pushChunk();\n\n this._streams.set(streamTag, streamEntry);\n\n networkStream.on('data', (data) => {\n streamEntry.bytesReceived += data.length;\n });\n\n networkStream.on('error', (err) => {\n streamEntry.receiveErrors += 1;\n });\n\n networkStream.on('close', () => {\n networkStream.removeAllListeners();\n });\n\n streamEntry.reportingTimer = setInterval(() => {\n const { bytesSent, bytesReceived, sendErrors, receiveErrors } = streamEntry;\n // log.info('stream stats', { streamTag, bytesSent, bytesReceived, sendErrors, receiveErrors });\n log.trace('dxos.test.stream-stats', {\n streamTag,\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n from: this.extensionContext?.localPeerId,\n to: this.extensionContext?.remotePeerId,\n });\n }, 100);\n }\n\n private _closeStream(streamTag: string): Stats {\n invariant(this._streams.has(streamTag), `Stream does not exist: ${streamTag}`);\n\n const stream = this._streams.get(streamTag)!;\n\n clearTimeout(stream.timer);\n clearTimeout(stream.reportingTimer);\n\n const { bytesSent, bytesReceived, sendErrors, receiveErrors, startTimestamp } = stream;\n\n stream.networkStream.destroy();\n this._streams.delete(streamTag);\n\n return {\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime: Date.now() - (startTimestamp ?? 0),\n };\n }\n\n async onOpen(context: ExtensionContext) {\n log('onOpen', { localPeerId: context.localPeerId, remotePeerId: context.remotePeerId });\n this.extensionContext = context;\n this._rpc = createProtoRpcPeer<\n { TestServiceWithStreams: TestServiceWithStreams },\n { TestServiceWithStreams: TestServiceWithStreams }\n >({\n port: await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n }),\n requested: {\n TestServiceWithStreams: schema.getService('example.testing.rpc.TestServiceWithStreams'),\n },\n exposed: {\n TestServiceWithStreams: schema.getService('example.testing.rpc.TestServiceWithStreams'),\n },\n handlers: {\n TestServiceWithStreams: {\n requestTestStream: async (request) => {\n const { data: streamTag, streamLoadInterval, streamLoadChunkSize } = request;\n\n await this._openStream(streamTag, streamLoadInterval, streamLoadChunkSize);\n\n return {\n data: streamTag,\n };\n },\n closeTestStream: async (request) => {\n const streamTag = request.data;\n const { bytesSent, bytesReceived, sendErrors, receiveErrors, runningTime } = this._closeStream(streamTag);\n\n return {\n data: streamTag,\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime,\n };\n },\n },\n },\n timeout: 2000,\n });\n\n await this._rpc.open();\n await this.callbacks.onOpen?.();\n\n this.open.wake();\n }\n\n async onClose(err?: Error) {\n log('onClose', { err });\n await this.callbacks.onClose?.();\n this.closed.wake();\n for (const [streamTag, stream] of Object.entries(this._streams)) {\n log('closing stream', { streamTag });\n clearTimeout(stream.interval);\n stream.networkStream.destroy();\n }\n await this._rpc?.close();\n }\n\n async addNewStream(streamLoadInterval: number, streamLoadChunkSize: number, streamTag?: string): Promise<string> {\n await this.open.wait({ timeout: 1500 });\n if (!streamTag) {\n streamTag = `stream-${randomBytes(4).toString('hex')}`;\n }\n const { data } = await this._rpc.rpc.TestServiceWithStreams.requestTestStream({\n data: streamTag,\n streamLoadInterval,\n streamLoadChunkSize,\n });\n invariant(data === streamTag);\n\n await this._openStream(streamTag, streamLoadInterval, streamLoadChunkSize);\n return streamTag;\n }\n\n async closeStream(streamTag: string): Promise<TestStreamStats> {\n await this.open.wait({ timeout: 1500 });\n const { data, bytesSent, bytesReceived, sendErrors, receiveErrors, runningTime } =\n await this._rpc.rpc.TestServiceWithStreams.closeTestStream({\n data: streamTag,\n });\n\n invariant(data === streamTag);\n\n const local = this._closeStream(streamTag);\n\n return {\n streamTag,\n stats: {\n local,\n remote: {\n bytesSent,\n bytesReceived,\n sendErrors,\n receiveErrors,\n runningTime,\n },\n },\n };\n }\n\n /**\n * Force-close the connection.\n */\n async closeConnection(err?: Error) {\n this.extensionContext?.close(err);\n }\n}\n\ntype Stats = {\n bytesSent: number;\n bytesReceived: number;\n sendErrors: number;\n receiveErrors: number;\n runningTime: number;\n};\n\nexport type TestStreamStats = {\n streamTag: string;\n stats: {\n local: Stats;\n remote: Stats;\n };\n};\n\ntype TestStream = {\n networkStream: Duplex;\n bytesSent: number;\n bytesReceived: number;\n sendErrors: number;\n receiveErrors: number;\n timer?: NodeJS.Timer;\n startTimestamp?: number;\n reportingTimer?: NodeJS.Timer;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["pipeline", "invariant", "PublicKey", "log", "asyncTimeout", "scheduleTaskInterval", "runInContextAsync", "synchronized", "scheduleTask", "Context", "failUndefined", "invariant", "PublicKey", "log", "schema", "RpcClosedError", "createProtoRpcPeer", "Callback", "Duplex", "invariant", "FRAME_LENGTH_SIZE", "Framer", "_sendCallbacks", "_bytesSent", "_bytesReceived", "_stream", "objectMode", "read", "_processResponseQueue", "write", "chunk", "encoding", "callback", "_subscribeCb", "length", "_buffer", "Buffer", "concat", "_messageCb", "_popFrames", "undefined", "port", "send", "message", "Promise", "resolve", "frame", "encodeFrame", "canContinue", "push", "subscribe", "stream", "bytesSent", "bytesReceived", "responseQueue", "forEach", "cb", "offset", "decodeFrame", "bytesConsumed", "payload", "subarray", "destroy", "buffer", "frameLength", "readUInt16BE", "allocUnsafe", "writeUInt16BE", "set", "Duplex", "scheduleTaskInterval", "Event", "Trigger", "Context", "failUndefined", "invariant", "log", "schema", "varint", "Event", "log", "MAX_CHUNK_SIZE", "Balancer", "constructor", "_sysChannelId", "_lastCallerIndex", "_channels", "_framer", "Framer", "_sendBuffers", "Map", "_receiveBuffers", "incomingData", "Event", "stream", "push", "port", "subscribe", "_processIncomingMessage", "bind", "bytesSent", "bytesReceived", "addChannel", "channel", "pushData", "data", "trigger", "channelId", "noCalls", "size", "includes", "Error", "has", "set", "sendBuffer", "get", "chunks", "idx", "length", "subarray", "forEach", "chunk", "index", "msg", "encodeChunk", "dataLength", "undefined", "_sendChunks", "catch", "err", "log", "destroy", "clear", "decodeChunk", "buffer", "Buffer", "from", "msgLength", "emit", "channelBuffer", "concat", "delete", "_getNextCallerId", "_getNextChunk", "shift", "send", "wake", "throw", "channelTagLength", "encodingLength", "dataLengthLength", "message", "allocUnsafe", "varint", "encode", "withLength", "decode", "offset", "bytes", "Command", "schema", "getCodecForType", "STATS_INTERVAL", "MAX_SAFE_FRAME_SIZE", "SYSTEM_CHANNEL_ID", "Muxer", "constructor", "_balancer", "Balancer", "_channelsByLocalId", "Map", "_channelsByTag", "_ctx", "Context", "_nextId", "_destroyed", "_destroying", "close", "Event", "statsUpdated", "stream", "_lastChannelStats", "incomingData", "on", "msg", "_handleCommand", "decode", "scheduleTaskInterval", "_emitStats", "createStream", "tag", "opts", "channel", "_getOrCreateStream", "contentType", "invariant", "push", "Duplex", "write", "data", "encoding", "callback", "_sendData", "then", "catch", "read", "stats", "bytesReceived", "length", "destroy", "err", "_sendCommand", "openChannel", "id", "_destroyChannel", "createPort", "inboundBuffer", "port", "send", "subscribe", "cb", "error", "message", "_dispose", "dispose", "values", "emit", "clear", "cmd", "log", "warn", "remoteId", "buffer", "channelId", "get", "failUndefined", "trigger", "Trigger", "pushData", "encode", "wait", "params", "bytesSent", "set", "addChannel", "size", "threshold", "delete", "_lastStats", "undefined", "now", "Date", "interval", "timestamp", "calculateThroughput", "current", "last", "bytesSentRate", "bytesReceivedRate", "channels", "Array", "from", "map", "Teleport", "constructor", "initiator", "localPeerId", "remotePeerId", "_ctx", "Context", "onError", "err", "destroy", "catch", "log", "error", "_muxer", "Muxer", "_control", "ControlExtension", "heartbeatInterval", "heartbeatTimeout", "onTimeout", "Error", "_extensions", "Map", "_remoteExtensions", "Set", "_open", "invariant", "PublicKey", "isPublicKey", "onExtensionRegistered", "set", "name", "has", "add", "_openExtension", "stream", "on", "statsUpdated", "stats", "trace", "bytesSent", "bytesSentRate", "bytesReceived", "bytesReceivedRate", "channels", "open", "_setExtension", "close", "disposed", "dispose", "extension", "values", "onClose", "addExtension", "scheduleTask", "registerExtension", "RpcClosedError", "extensionName", "includes", "get", "failUndefined", "context", "createPort", "channelName", "opts", "createStream", "runInContextAsync", "onOpen", "synchronized", "_extensionContext", "Callback", "_rpc", "rpc", "Control", "extensionContext", "createProtoRpcPeer", "requested", "schema", "getService", "exposed", "handlers", "request", "call", "heartbeat", "port", "contentType", "scheduleTaskInterval", "asyncTimeout", "TestBuilder", "_peers", "Set", "createPeer", "opts", "peer", "factory", "add", "createPeers", "destroy", "Promise", "all", "Array", "from", "map", "agent", "connect", "peer1", "peer2", "invariant", "has", "connection1", "createConnection", "initiator", "remotePeerId", "peerId", "connection2", "pipeStreams", "teleport", "stream", "openConnection", "disconnect", "connections", "find", "connection", "equals", "closeConnection", "TestPeer", "constructor", "PublicKey", "random", "onOpen", "onClose", "TestConnection", "open", "close", "delete", "stream1", "stream2", "pipeline", "err", "code", "log", "catch", "localPeerId", "Teleport", "asyncTimeout", "Trigger", "invariant", "log", "schema", "createProtoRpcPeer", "TestExtension", "constructor", "callbacks", "open", "closed", "remotePeerId", "extensionContext", "onOpen", "context", "localPeerId", "_rpc", "port", "createPort", "contentType", "requested", "TestService", "getService", "exposed", "handlers", "voidCall", "request", "testCall", "data", "timeout", "wake", "onClose", "err", "close", "test", "message", "wait", "res", "rpc", "closeConnection", "randomBytes", "Trigger", "invariant", "log", "schema", "createProtoRpcPeer", "TestExtensionWithStreams", "constructor", "callbacks", "open", "closed", "_streams", "Map", "remotePeerId", "extensionContext", "_openStream", "streamTag", "interval", "chunkSize", "has", "networkStream", "createStream", "contentType", "streamEntry", "bytesSent", "bytesReceived", "sendErrors", "receiveErrors", "startTimestamp", "Date", "now", "pushChunk", "timer", "setTimeout", "chunk", "write", "err", "length", "once", "process", "nextTick", "set", "on", "data", "removeAllListeners", "reportingTimer", "setInterval", "trace", "from", "localPeerId", "to", "_closeStream", "stream", "get", "clearTimeout", "destroy", "delete", "runningTime", "onOpen", "context", "_rpc", "port", "createPort", "requested", "TestServiceWithStreams", "getService", "exposed", "handlers", "requestTestStream", "request", "streamLoadInterval", "streamLoadChunkSize", "closeTestStream", "timeout", "wake", "onClose", "Object", "entries", "close", "addNewStream", "wait", "toString", "rpc", "closeStream", "local", "stats", "remote", "closeConnection"]
7
+ }
@@ -10,7 +10,7 @@ import {
10
10
  TestPeer,
11
11
  decodeFrame,
12
12
  encodeFrame
13
- } from "./chunk-3FNN6ZOF.mjs";
13
+ } from "./chunk-2MN5W64H.mjs";
14
14
 
15
15
  // packages/core/mesh/teleport/src/rpc-extension.ts
16
16
  import { invariant } from "@dxos/invariant";
@@ -59,9 +59,8 @@ var RpcExtension = class {
59
59
  await this._rpc.open();
60
60
  }
61
61
  async onClose(err) {
62
- var _a;
63
62
  this._isClosed = true;
64
- await ((_a = this._rpc) == null ? void 0 : _a.close());
63
+ await this._rpc?.close();
65
64
  }
66
65
  close() {
67
66
  this._extensionContext.close();
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/rpc-extension.ts"],
4
4
  "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { createProtoRpcPeer, ProtoRpcPeer, ProtoRpcPeerOptions } from '@dxos/rpc';\n\nimport { ExtensionContext, TeleportExtension } from './teleport';\n\nexport abstract class RpcExtension<Client, Server> implements TeleportExtension {\n // TODO(dmaretskyi): Type optionally.\n private _extensionContext!: ExtensionContext;\n private _rpc?: ProtoRpcPeer<Client>;\n\n private _isClosed = false;\n\n constructor(private readonly _rpcParams: Omit<ProtoRpcPeerOptions<Client, Server>, 'port' | 'handlers'>) {}\n\n get initiator() {\n return this._extensionContext.initiator;\n }\n\n get localPeerId() {\n return this._extensionContext.localPeerId;\n }\n\n get remotePeerId() {\n return this._extensionContext.remotePeerId;\n }\n\n get rpc(): Client {\n invariant(this._rpc);\n return this._rpc.rpc;\n }\n\n protected abstract getHandlers(): Promise<Server>;\n\n async onOpen(context: ExtensionContext): Promise<void> {\n this._extensionContext = context;\n\n const handlers = await this.getHandlers();\n\n if (this._isClosed) {\n return;\n }\n\n const port = await context.createPort('rpc', {\n contentType: 'application/x-protobuf; messageType=\"dxos.rpc.Message\"',\n });\n this._rpc = createProtoRpcPeer({\n ...this._rpcParams,\n handlers,\n port,\n });\n\n await this._rpc.open();\n }\n\n async onClose(err?: Error | undefined): Promise<void> {\n this._isClosed = true;\n await this._rpc?.close();\n }\n\n close() {\n this._extensionContext.close();\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;AAIA,SAASA,iBAAiB;AAC1B,SAASC,0BAA6D;;AAI/D,IAAeC,eAAf,MAAeA;EAOpBC,YAA6BC,YAA4E;sBAA5EA;SAFrBC,YAAY;EAEsF;EAE1G,IAAIC,YAAY;AACd,WAAO,KAAKC,kBAAkBD;EAChC;EAEA,IAAIE,cAAc;AAChB,WAAO,KAAKD,kBAAkBC;EAChC;EAEA,IAAIC,eAAe;AACjB,WAAO,KAAKF,kBAAkBE;EAChC;EAEA,IAAIC,MAAc;AAChBV,cAAU,KAAKW,MAAI,QAAA;;;;;;;;;AACnB,WAAO,KAAKA,KAAKD;EACnB;EAIA,MAAME,OAAOC,SAA0C;AACrD,SAAKN,oBAAoBM;AAEzB,UAAMC,WAAW,MAAM,KAAKC,YAAW;AAEvC,QAAI,KAAKV,WAAW;AAClB;IACF;AAEA,UAAMW,OAAO,MAAMH,QAAQI,WAAW,OAAO;MAC3CC,aAAa;IACf,CAAA;AACA,SAAKP,OAAOV,mBAAmB;MAC7B,GAAG,KAAKG;MACRU;MACAE;IACF,CAAA;AAEA,UAAM,KAAKL,KAAKQ,KAAI;EACtB;EAEA,MAAMC,QAAQC,KAAwC;AA1DxD;AA2DI,SAAKhB,YAAY;AACjB,YAAM,UAAKM,SAAL,mBAAWW;EACnB;EAEAA,QAAQ;AACN,SAAKf,kBAAkBe,MAAK;EAC9B;AACF;",
5
+ "mappings": ";;;;;;;;;;;;;;;AAIA,SAASA,iBAAiB;AAC1B,SAASC,0BAA6D;;AAI/D,IAAeC,eAAf,MAAeA;EAOpBC,YAA6BC,YAA4E;sBAA5EA;SAFrBC,YAAY;EAEsF;EAE1G,IAAIC,YAAY;AACd,WAAO,KAAKC,kBAAkBD;EAChC;EAEA,IAAIE,cAAc;AAChB,WAAO,KAAKD,kBAAkBC;EAChC;EAEA,IAAIC,eAAe;AACjB,WAAO,KAAKF,kBAAkBE;EAChC;EAEA,IAAIC,MAAc;AAChBV,cAAU,KAAKW,MAAI,QAAA;;;;;;;;;AACnB,WAAO,KAAKA,KAAKD;EACnB;EAIA,MAAME,OAAOC,SAA0C;AACrD,SAAKN,oBAAoBM;AAEzB,UAAMC,WAAW,MAAM,KAAKC,YAAW;AAEvC,QAAI,KAAKV,WAAW;AAClB;IACF;AAEA,UAAMW,OAAO,MAAMH,QAAQI,WAAW,OAAO;MAC3CC,aAAa;IACf,CAAA;AACA,SAAKP,OAAOV,mBAAmB;MAC7B,GAAG,KAAKG;MACRU;MACAE;IACF,CAAA;AAEA,UAAM,KAAKL,KAAKQ,KAAI;EACtB;EAEA,MAAMC,QAAQC,KAAwC;AACpD,SAAKhB,YAAY;AACjB,UAAM,KAAKM,MAAMW,MAAAA;EACnB;EAEAA,QAAQ;AACN,SAAKf,kBAAkBe,MAAK;EAC9B;AACF;",
6
6
  "names": ["invariant", "createProtoRpcPeer", "RpcExtension", "constructor", "_rpcParams", "_isClosed", "initiator", "_extensionContext", "localPeerId", "remotePeerId", "rpc", "_rpc", "onOpen", "context", "handlers", "getHandlers", "port", "createPort", "contentType", "open", "onClose", "err", "close"]
7
7
  }