@dxos/network-manager 0.3.9-main.cab5453 → 0.3.9-main.cdfefb1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/lib/browser/{chunk-4HITD6WI.mjs → chunk-7JESB3AJ.mjs} +376 -108
  2. package/dist/lib/browser/chunk-7JESB3AJ.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +1 -11
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +1 -2
  6. package/dist/lib/browser/testing/index.mjs.map +1 -1
  7. package/dist/lib/node/{chunk-6AD7QA4X.cjs → chunk-Y2B5BDRH.cjs} +383 -103
  8. package/dist/lib/node/chunk-Y2B5BDRH.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +27 -36
  10. package/dist/lib/node/index.cjs.map +2 -2
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +18 -19
  13. package/dist/lib/node/testing/index.cjs.map +1 -1
  14. package/dist/types/src/connection-log.d.ts.map +1 -1
  15. package/dist/types/src/swarm/connection.d.ts +4 -1
  16. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  17. package/dist/types/src/topology/mmst-topology.d.ts +1 -0
  18. package/dist/types/src/topology/mmst-topology.d.ts.map +1 -1
  19. package/dist/types/src/transport/index.d.ts +0 -1
  20. package/dist/types/src/transport/index.d.ts.map +1 -1
  21. package/dist/types/src/transport/libdatachannel-transport.d.ts +4 -1
  22. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -1
  23. package/dist/types/src/transport/memory-transport.d.ts +3 -1
  24. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  25. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts +3 -1
  26. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -1
  27. package/dist/types/src/transport/simplepeer-transport-service.d.ts +3 -1
  28. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -1
  29. package/dist/types/src/transport/simplepeer-transport.d.ts +7 -1
  30. package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -1
  31. package/dist/types/src/transport/tcp-transport.browser.d.ts +3 -1
  32. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -1
  33. package/dist/types/src/transport/tcp-transport.d.ts +3 -1
  34. package/dist/types/src/transport/tcp-transport.d.ts.map +1 -1
  35. package/dist/types/src/transport/transport.d.ts +17 -0
  36. package/dist/types/src/transport/transport.d.ts.map +1 -1
  37. package/dist/types/src/wire-protocol.d.ts +1 -1
  38. package/dist/types/src/wire-protocol.d.ts.map +1 -1
  39. package/package.json +18 -18
  40. package/src/connection-log.ts +14 -1
  41. package/src/swarm/connection.ts +23 -4
  42. package/src/topology/mmst-topology.ts +34 -6
  43. package/src/transport/index.ts +0 -1
  44. package/src/transport/libdatachannel-transport.test.ts +0 -4
  45. package/src/transport/libdatachannel-transport.ts +83 -5
  46. package/src/transport/memory-transport.ts +14 -1
  47. package/src/transport/simplepeer-transport-proxy.ts +9 -1
  48. package/src/transport/simplepeer-transport-service.ts +14 -0
  49. package/src/transport/simplepeer-transport.ts +66 -3
  50. package/src/transport/tcp-transport.browser.ts +9 -1
  51. package/src/transport/tcp-transport.ts +19 -1
  52. package/src/transport/transport.ts +19 -0
  53. package/src/wire-protocol.ts +3 -3
  54. package/dist/lib/browser/chunk-4HITD6WI.mjs.map +0 -7
  55. package/dist/lib/browser/chunk-YERMWDRB.mjs +0 -24
  56. package/dist/lib/browser/chunk-YERMWDRB.mjs.map +0 -7
  57. package/dist/lib/browser/index.browser-O53CPVK3.mjs +0 -14
  58. package/dist/lib/browser/index.browser-O53CPVK3.mjs.map +0 -7
  59. package/dist/lib/node/chunk-6AD7QA4X.cjs.map +0 -7
  60. package/dist/lib/node/chunk-XE5JOIGD.cjs +0 -462
  61. package/dist/lib/node/chunk-XE5JOIGD.cjs.map +0 -7
  62. package/dist/lib/node/datachannel-53JZPGFA.cjs +0 -35
  63. package/dist/lib/node/datachannel-53JZPGFA.cjs.map +0 -7
  64. package/dist/types/src/transport/datachannel/index.browser.d.ts +0 -15
  65. package/dist/types/src/transport/datachannel/index.browser.d.ts.map +0 -1
  66. package/dist/types/src/transport/datachannel/index.d.ts +0 -8
  67. package/dist/types/src/transport/datachannel/index.d.ts.map +0 -1
  68. package/dist/types/src/transport/datachannel/rtc-data-channel.d.ts +0 -29
  69. package/dist/types/src/transport/datachannel/rtc-data-channel.d.ts.map +0 -1
  70. package/dist/types/src/transport/datachannel/rtc-events.d.ts +0 -9
  71. package/dist/types/src/transport/datachannel/rtc-events.d.ts.map +0 -1
  72. package/dist/types/src/transport/datachannel/rtc-ice-candidate.d.ts +0 -22
  73. package/dist/types/src/transport/datachannel/rtc-ice-candidate.d.ts.map +0 -1
  74. package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts +0 -47
  75. package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts.map +0 -1
  76. package/dist/types/src/transport/datachannel/rtc-peer-connection.test.d.ts +0 -2
  77. package/dist/types/src/transport/datachannel/rtc-peer-connection.test.d.ts.map +0 -1
  78. package/dist/types/src/transport/datachannel/rtc-session-description.d.ts +0 -10
  79. package/dist/types/src/transport/datachannel/rtc-session-description.d.ts.map +0 -1
  80. package/src/transport/datachannel/README.md +0 -2
  81. package/src/transport/datachannel/index.browser.ts +0 -8
  82. package/src/transport/datachannel/index.ts +0 -17
  83. package/src/transport/datachannel/rtc-data-channel.ts +0 -148
  84. package/src/transport/datachannel/rtc-events.ts +0 -23
  85. package/src/transport/datachannel/rtc-ice-candidate.ts +0 -54
  86. package/src/transport/datachannel/rtc-peer-connection.test.ts +0 -112
  87. package/src/transport/datachannel/rtc-peer-connection.ts +0 -347
  88. package/src/transport/datachannel/rtc-session-description.ts +0 -23
@@ -1,15 +1,19 @@
1
1
  import "@dxos/node-std/globals";
2
- import {
3
- __require
4
- } from "./chunk-YERMWDRB.mjs";
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
3
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
4
+ }) : x)(function(x) {
5
+ if (typeof require !== "undefined")
6
+ return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
8
+ });
5
9
 
6
10
  // packages/core/mesh/network-manager/src/swarm/connection.ts
7
- import { DeferredTask, Event, sleep, scheduleTask, synchronized } from "@dxos/async";
11
+ import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized } from "@dxos/async";
8
12
  import { Context, cancelWithContext } from "@dxos/context";
9
13
  import { ErrorStream } from "@dxos/debug";
10
14
  import { invariant } from "@dxos/invariant";
11
15
  import { PublicKey } from "@dxos/keys";
12
- import { log } from "@dxos/log";
16
+ import { log, logInfo } from "@dxos/log";
13
17
  import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, UnknownProtocolError, trace } from "@dxos/protocols";
14
18
  function _ts_decorate(decorators, target, key, desc) {
15
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -24,6 +28,7 @@ function _ts_decorate(decorators, target, key, desc) {
24
28
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/connection.ts";
25
29
  var STARTING_SIGNALLING_DELAY = 10;
26
30
  var TRANSPORT_CONNECTION_TIMEOUT = 1e4;
31
+ var TRANSPORT_STATS_INTERVAL = 5e3;
27
32
  var MAX_SIGNALLING_DELAY = 300;
28
33
  var ConnectionState;
29
34
  (function(ConnectionState5) {
@@ -86,6 +91,7 @@ var Connection = class {
86
91
  this.stateChanged = new Event();
87
92
  this.errors = new ErrorStream();
88
93
  this._instanceId = PublicKey.random().toHex();
94
+ this.transportStats = new Event();
89
95
  this._signalSendTask = new DeferredTask(this._ctx, async () => {
90
96
  await this._flushSignalBuffer();
91
97
  });
@@ -98,11 +104,14 @@ var Connection = class {
98
104
  initiator: this.initiator
99
105
  }, {
100
106
  F: __dxlog_file,
101
- L: 130,
107
+ L: 134,
102
108
  S: this,
103
109
  C: (f, a) => f(...a)
104
110
  });
105
111
  }
112
+ get sessionIdString() {
113
+ return this.sessionId.truncate();
114
+ }
106
115
  get state() {
107
116
  return this._state;
108
117
  }
@@ -118,7 +127,7 @@ var Connection = class {
118
127
  async openConnection() {
119
128
  invariant(this._state === ConnectionState.INITIAL, "Invalid state.", {
120
129
  F: __dxlog_file,
121
- L: 155,
130
+ L: 164,
122
131
  S: this,
123
132
  A: [
124
133
  "this._state === ConnectionState.INITIAL",
@@ -129,7 +138,7 @@ var Connection = class {
129
138
  id: this._instanceId
130
139
  }), {
131
140
  F: __dxlog_file,
132
- L: 156,
141
+ L: 165,
133
142
  S: this,
134
143
  C: (f, a) => f(...a)
135
144
  });
@@ -141,18 +150,18 @@ var Connection = class {
141
150
  initiator: this.initiator
142
151
  }, {
143
152
  F: __dxlog_file,
144
- L: 157,
153
+ L: 166,
145
154
  S: this,
146
155
  C: (f, a) => f(...a)
147
156
  });
148
157
  this._changeState(ConnectionState.CONNECTING);
149
- this._protocol.open().catch((err) => {
158
+ this._protocol.open(this.sessionId).catch((err) => {
150
159
  this.errors.raise(err);
151
160
  });
152
161
  this._protocol.stream.on("close", () => {
153
162
  log("protocol stream closed", void 0, {
154
163
  F: __dxlog_file,
155
- L: 174,
164
+ L: 183,
156
165
  S: this,
157
166
  C: (f, a) => f(...a)
158
167
  });
@@ -161,7 +170,7 @@ var Connection = class {
161
170
  scheduleTask(this.connectedTimeoutContext, async () => {
162
171
  log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
163
172
  F: __dxlog_file,
164
- L: 181,
173
+ L: 190,
165
174
  S: this,
166
175
  C: (f, a) => f(...a)
167
176
  });
@@ -169,7 +178,7 @@ var Connection = class {
169
178
  }, TRANSPORT_CONNECTION_TIMEOUT);
170
179
  invariant(!this._transport, void 0, {
171
180
  F: __dxlog_file,
172
- L: 189,
181
+ L: 198,
173
182
  S: this,
174
183
  A: [
175
184
  "!this._transport",
@@ -179,18 +188,20 @@ var Connection = class {
179
188
  this._transport = this._transportFactory.createTransport({
180
189
  initiator: this.initiator,
181
190
  stream: this._protocol.stream,
182
- sendSignal: async (signal) => this._sendSignal(signal)
191
+ sendSignal: async (signal) => this._sendSignal(signal),
192
+ sessionId: this.sessionId
183
193
  });
184
194
  this._transport.connected.once(async () => {
185
195
  this._changeState(ConnectionState.CONNECTED);
186
196
  await this.connectedTimeoutContext.dispose();
187
197
  this._callbacks?.onConnected?.();
198
+ scheduleTaskInterval(this._ctx, async () => this._emitTransportStats(), TRANSPORT_STATS_INTERVAL);
188
199
  });
189
200
  this._transport.closed.once(() => {
190
201
  this._transport = void 0;
191
202
  log("abort triggered by transport close", void 0, {
192
203
  F: __dxlog_file,
193
- L: 204,
204
+ L: 216,
194
205
  S: this,
195
206
  C: (f, a) => f(...a)
196
207
  });
@@ -201,7 +212,7 @@ var Connection = class {
201
212
  err
202
213
  }, {
203
214
  F: __dxlog_file,
204
- L: 209,
215
+ L: 221,
205
216
  S: this,
206
217
  C: (f, a) => f(...a)
207
218
  });
@@ -211,7 +222,7 @@ var Connection = class {
211
222
  if (err instanceof ConnectionResetError) {
212
223
  log.info("aborting due to transport ConnectionResetError", void 0, {
213
224
  F: __dxlog_file,
214
- L: 216,
225
+ L: 228,
215
226
  S: this,
216
227
  C: (f, a) => f(...a)
217
228
  });
@@ -219,7 +230,7 @@ var Connection = class {
219
230
  } else if (err instanceof ConnectivityError) {
220
231
  log.info("aborting due to transport ConnectivityError", void 0, {
221
232
  F: __dxlog_file,
222
- L: 219,
233
+ L: 231,
223
234
  S: this,
224
235
  C: (f, a) => f(...a)
225
236
  });
@@ -229,7 +240,7 @@ var Connection = class {
229
240
  err
230
241
  }, {
231
242
  F: __dxlog_file,
232
- L: 222,
243
+ L: 234,
233
244
  S: this,
234
245
  C: (f, a) => f(...a)
235
246
  });
@@ -247,7 +258,7 @@ var Connection = class {
247
258
  id: this._instanceId
248
259
  }), {
249
260
  F: __dxlog_file,
250
- L: 238,
261
+ L: 250,
251
262
  S: this,
252
263
  C: (f, a) => f(...a)
253
264
  });
@@ -257,14 +268,14 @@ var Connection = class {
257
268
  err
258
269
  }, {
259
270
  F: __dxlog_file,
260
- L: 245,
271
+ L: 257,
261
272
  S: this,
262
273
  C: (f, a) => f(...a)
263
274
  });
264
275
  if (this._state === ConnectionState.CLOSED || this._state === ConnectionState.ABORTED) {
265
276
  log(`abort ignored: already ${this._state}`, this.closeReason, {
266
277
  F: __dxlog_file,
267
- L: 247,
278
+ L: 259,
268
279
  S: this,
269
280
  C: (f, a) => f(...a)
270
281
  });
@@ -279,7 +290,7 @@ var Connection = class {
279
290
  try {
280
291
  log("aborting protocol... ", void 0, {
281
292
  F: __dxlog_file,
282
- L: 261,
293
+ L: 273,
283
294
  S: this,
284
295
  C: (f, a) => f(...a)
285
296
  });
@@ -287,7 +298,7 @@ var Connection = class {
287
298
  } catch (err2) {
288
299
  log.catch(err2, void 0, {
289
300
  F: __dxlog_file,
290
- L: 264,
301
+ L: 276,
291
302
  S: this,
292
303
  C: (f, a) => f(...a)
293
304
  });
@@ -297,7 +308,7 @@ var Connection = class {
297
308
  } catch (err2) {
298
309
  log.catch(err2, void 0, {
299
310
  F: __dxlog_file,
300
- L: 271,
311
+ L: 283,
301
312
  S: this,
302
313
  C: (f, a) => f(...a)
303
314
  });
@@ -307,7 +318,7 @@ var Connection = class {
307
318
  } catch (err2) {
308
319
  log.catch(err2, void 0, {
309
320
  F: __dxlog_file,
310
- L: 277,
321
+ L: 289,
311
322
  S: this,
312
323
  C: (f, a) => f(...a)
313
324
  });
@@ -331,7 +342,7 @@ var Connection = class {
331
342
  peerId: this.ownId
332
343
  }, {
333
344
  F: __dxlog_file,
334
- L: 302,
345
+ L: 314,
335
346
  S: this,
336
347
  C: (f, a) => f(...a)
337
348
  });
@@ -341,7 +352,7 @@ var Connection = class {
341
352
  } catch (err2) {
342
353
  log.catch(err2, void 0, {
343
354
  F: __dxlog_file,
344
- L: 309,
355
+ L: 321,
345
356
  S: this,
346
357
  C: (f, a) => f(...a)
347
358
  });
@@ -351,7 +362,7 @@ var Connection = class {
351
362
  } catch (err2) {
352
363
  log.catch(err2, void 0, {
353
364
  F: __dxlog_file,
354
- L: 316,
365
+ L: 328,
355
366
  S: this,
356
367
  C: (f, a) => f(...a)
357
368
  });
@@ -359,7 +370,7 @@ var Connection = class {
359
370
  } else {
360
371
  log.info(`graceful close requested when we were in ${lastState} state? aborting`, void 0, {
361
372
  F: __dxlog_file,
362
- L: 319,
373
+ L: 331,
363
374
  S: this,
364
375
  C: (f, a) => f(...a)
365
376
  });
@@ -368,7 +379,7 @@ var Connection = class {
368
379
  } catch (err2) {
369
380
  log.catch(err2, void 0, {
370
381
  F: __dxlog_file,
371
- L: 323,
382
+ L: 335,
372
383
  S: this,
373
384
  C: (f, a) => f(...a)
374
385
  });
@@ -378,7 +389,7 @@ var Connection = class {
378
389
  } catch (err2) {
379
390
  log.catch(err2, void 0, {
380
391
  F: __dxlog_file,
381
- L: 328,
392
+ L: 340,
382
393
  S: this,
383
394
  C: (f, a) => f(...a)
384
395
  });
@@ -388,7 +399,7 @@ var Connection = class {
388
399
  peerId: this.ownId
389
400
  }, {
390
401
  F: __dxlog_file,
391
- L: 332,
402
+ L: 344,
392
403
  S: this,
393
404
  C: (f, a) => f(...a)
394
405
  });
@@ -431,7 +442,7 @@ var Connection = class {
431
442
  err
432
443
  }, {
433
444
  F: __dxlog_file,
434
- L: 370,
445
+ L: 382,
435
446
  S: this,
436
447
  C: (f, a) => f(...a)
437
448
  });
@@ -444,7 +455,7 @@ var Connection = class {
444
455
  async signal(msg) {
445
456
  invariant(msg.sessionId, void 0, {
446
457
  F: __dxlog_file,
447
- L: 379,
458
+ L: 391,
448
459
  S: this,
449
460
  A: [
450
461
  "msg.sessionId",
@@ -454,7 +465,7 @@ var Connection = class {
454
465
  if (!msg.sessionId.equals(this.sessionId)) {
455
466
  log("dropping signal for incorrect session id", void 0, {
456
467
  F: __dxlog_file,
457
- L: 381,
468
+ L: 393,
458
469
  S: this,
459
470
  C: (f, a) => f(...a)
460
471
  });
@@ -462,7 +473,7 @@ var Connection = class {
462
473
  }
463
474
  invariant(msg.data.signal || msg.data.signalBatch, void 0, {
464
475
  F: __dxlog_file,
465
- L: 384,
476
+ L: 396,
466
477
  S: this,
467
478
  A: [
468
479
  "msg.data.signal || msg.data.signalBatch",
@@ -471,7 +482,7 @@ var Connection = class {
471
482
  });
472
483
  invariant(msg.author?.equals(this.remoteId), void 0, {
473
484
  F: __dxlog_file,
474
- L: 385,
485
+ L: 397,
475
486
  S: this,
476
487
  A: [
477
488
  "msg.author?.equals(this.remoteId)",
@@ -480,7 +491,7 @@ var Connection = class {
480
491
  });
481
492
  invariant(msg.recipient?.equals(this.ownId), void 0, {
482
493
  F: __dxlog_file,
483
- L: 386,
494
+ L: 398,
484
495
  S: this,
485
496
  A: [
486
497
  "msg.recipient?.equals(this.ownId)",
@@ -504,7 +515,7 @@ var Connection = class {
504
515
  msg: msg.data
505
516
  }, {
506
517
  F: __dxlog_file,
507
- L: 395,
518
+ L: 407,
508
519
  S: this,
509
520
  C: (f, a) => f(...a)
510
521
  });
@@ -512,7 +523,7 @@ var Connection = class {
512
523
  } else {
513
524
  invariant(this._transport, "Connection not ready to accept signals.", {
514
525
  F: __dxlog_file,
515
- L: 398,
526
+ L: 410,
516
527
  S: this,
517
528
  A: [
518
529
  "this._transport",
@@ -525,7 +536,7 @@ var Connection = class {
525
536
  msg: msg.data
526
537
  }, {
527
538
  F: __dxlog_file,
528
- L: 399,
539
+ L: 411,
529
540
  S: this,
530
541
  C: (f, a) => f(...a)
531
542
  });
@@ -543,13 +554,13 @@ var Connection = class {
543
554
  peerId: this.ownId
544
555
  }, {
545
556
  F: __dxlog_file,
546
- L: 410,
557
+ L: 422,
547
558
  S: this,
548
559
  C: (f, a) => f(...a)
549
560
  });
550
561
  invariant(state !== this._state, "Already in this state.", {
551
562
  F: __dxlog_file,
552
- L: 411,
563
+ L: 423,
553
564
  S: this,
554
565
  A: [
555
566
  "state !== this._state",
@@ -559,7 +570,16 @@ var Connection = class {
559
570
  this._state = state;
560
571
  this.stateChanged.emit(state);
561
572
  }
573
+ async _emitTransportStats() {
574
+ const stats = await this.transport?.getStats();
575
+ if (stats) {
576
+ this.transportStats.emit(stats);
577
+ }
578
+ }
562
579
  };
580
+ _ts_decorate([
581
+ logInfo
582
+ ], Connection.prototype, "sessionIdString", null);
563
583
  _ts_decorate([
564
584
  synchronized
565
585
  ], Connection.prototype, "abort", null);
@@ -816,7 +836,7 @@ import { Context as Context4 } from "@dxos/context";
816
836
  import { ErrorStream as ErrorStream2 } from "@dxos/debug";
817
837
  import { invariant as invariant4 } from "@dxos/invariant";
818
838
  import { PublicKey as PublicKey4 } from "@dxos/keys";
819
- import { log as log4, logInfo } from "@dxos/log";
839
+ import { log as log4, logInfo as logInfo2 } from "@dxos/log";
820
840
  import { trace as trace2 } from "@dxos/protocols";
821
841
  import { ComplexMap as ComplexMap2, isNotNullOrUndefined } from "@dxos/util";
822
842
 
@@ -1780,13 +1800,13 @@ var Swarm = class {
1780
1800
  }
1781
1801
  };
1782
1802
  _ts_decorate3([
1783
- logInfo
1803
+ logInfo2
1784
1804
  ], Swarm.prototype, "_instanceId", void 0);
1785
1805
  _ts_decorate3([
1786
- logInfo
1806
+ logInfo2
1787
1807
  ], Swarm.prototype, "ownPeerId", null);
1788
1808
  _ts_decorate3([
1789
- logInfo
1809
+ logInfo2
1790
1810
  ], Swarm.prototype, "topic", null);
1791
1811
  _ts_decorate3([
1792
1812
  synchronized3
@@ -2003,7 +2023,7 @@ var ConnectionLog = class {
2003
2023
  };
2004
2024
  info.connections.push(connectionInfo);
2005
2025
  this.update.emit();
2006
- connection.stateChanged.on((state) => {
2026
+ connection.stateChanged.on(async (state) => {
2007
2027
  connectionInfo.state = state;
2008
2028
  connectionInfo.closeReason = connection.closeReason;
2009
2029
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
@@ -2011,6 +2031,10 @@ var ConnectionLog = class {
2011
2031
  type: EventType.CONNECTION_STATE_CHANGED,
2012
2032
  newState: state
2013
2033
  });
2034
+ if (state === ConnectionState.CONNECTED) {
2035
+ const details = await connection.transport?.getDetails();
2036
+ connectionInfo.transportDetails = details;
2037
+ }
2014
2038
  this.update.emit();
2015
2039
  });
2016
2040
  connection.protocol?.stats?.on((stats) => {
@@ -2020,6 +2044,12 @@ var ConnectionLog = class {
2020
2044
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
2021
2045
  this.update.emit();
2022
2046
  });
2047
+ connection.transportStats?.on((stats) => {
2048
+ connectionInfo.transportBytesSent = stats.bytesSent;
2049
+ connectionInfo.transportBytesReceived = stats.bytesReceived;
2050
+ connectionInfo.transportPacketsSent = stats.packetsSent;
2051
+ connectionInfo.transportPacketsReceived = stats.packetsReceived;
2052
+ });
2023
2053
  gcSwarm(info);
2024
2054
  });
2025
2055
  }
@@ -2323,9 +2353,12 @@ import distance from "xor-distance";
2323
2353
  import { invariant as invariant8 } from "@dxos/invariant";
2324
2354
  import { log as log8 } from "@dxos/log";
2325
2355
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/mmst-topology.ts";
2356
+ var MIN_UPDATE_INTERVAL = 1e3 * 10;
2357
+ var MAX_CHANGES_PER_UPDATE = 1;
2326
2358
  var MMSTTopology = class {
2327
2359
  constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 } = {}) {
2328
2360
  this._sampleCollected = false;
2361
+ this._lastAction = /* @__PURE__ */ new Date(0);
2329
2362
  this._originateConnections = originateConnections;
2330
2363
  this._maxPeers = maxPeers;
2331
2364
  this._sampleSize = sampleSize;
@@ -2333,7 +2366,7 @@ var MMSTTopology = class {
2333
2366
  init(controller) {
2334
2367
  invariant8(!this._controller, "Already initialized", {
2335
2368
  F: __dxlog_file9,
2336
- L: 46,
2369
+ L: 51,
2337
2370
  S: this,
2338
2371
  A: [
2339
2372
  "!this._controller",
@@ -2345,7 +2378,7 @@ var MMSTTopology = class {
2345
2378
  update() {
2346
2379
  invariant8(this._controller, "Not initialized", {
2347
2380
  F: __dxlog_file9,
2348
- L: 51,
2381
+ L: 56,
2349
2382
  S: this,
2350
2383
  A: [
2351
2384
  "this._controller",
@@ -2356,7 +2389,7 @@ var MMSTTopology = class {
2356
2389
  if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {
2357
2390
  log8("Running the algorithm.", void 0, {
2358
2391
  F: __dxlog_file9,
2359
- L: 55,
2392
+ L: 60,
2360
2393
  S: this,
2361
2394
  C: (f, a) => f(...a)
2362
2395
  });
@@ -2367,7 +2400,7 @@ var MMSTTopology = class {
2367
2400
  async onOffer(peer) {
2368
2401
  invariant8(this._controller, "Not initialized", {
2369
2402
  F: __dxlog_file9,
2370
- L: 62,
2403
+ L: 67,
2371
2404
  S: this,
2372
2405
  A: [
2373
2406
  "this._controller",
@@ -2378,7 +2411,7 @@ var MMSTTopology = class {
2378
2411
  const accept = connected.length < this._maxPeers;
2379
2412
  log8(`Offer ${peer} accept=${accept}`, void 0, {
2380
2413
  F: __dxlog_file9,
2381
- L: 65,
2414
+ L: 70,
2382
2415
  S: this,
2383
2416
  C: (f, a) => f(...a)
2384
2417
  });
@@ -2389,7 +2422,7 @@ var MMSTTopology = class {
2389
2422
  _runAlgorithm() {
2390
2423
  invariant8(this._controller, "Not initialized", {
2391
2424
  F: __dxlog_file9,
2392
- L: 74,
2425
+ L: 79,
2393
2426
  S: this,
2394
2427
  A: [
2395
2428
  "this._controller",
@@ -2398,27 +2431,84 @@ var MMSTTopology = class {
2398
2431
  });
2399
2432
  const { connected, candidates, ownPeerId } = this._controller.getState();
2400
2433
  if (connected.length > this._maxPeers) {
2434
+ log8(`disconnect ${connected.length - this._maxPeers} peers.`, void 0, {
2435
+ F: __dxlog_file9,
2436
+ L: 85,
2437
+ S: this,
2438
+ C: (f, a) => f(...a)
2439
+ });
2401
2440
  const sorted = sortByXorDistance(connected, ownPeerId).reverse().slice(0, this._maxPeers - connected.length);
2402
- for (const peer of sorted) {
2403
- log8(`Disconnect ${peer}.`, void 0, {
2441
+ invariant8(sorted.length === 0, void 0, {
2442
+ F: __dxlog_file9,
2443
+ L: 89,
2444
+ S: this,
2445
+ A: [
2446
+ "sorted.length === 0",
2447
+ ""
2448
+ ]
2449
+ });
2450
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
2451
+ log8(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
2452
+ F: __dxlog_file9,
2453
+ L: 92,
2454
+ S: this,
2455
+ C: (f, a) => f(...a)
2456
+ });
2457
+ }
2458
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
2459
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
2460
+ log8(`Disconnect ${peer}.`, void 0, {
2461
+ F: __dxlog_file9,
2462
+ L: 97,
2463
+ S: this,
2464
+ C: (f, a) => f(...a)
2465
+ });
2466
+ this._controller.disconnect(peer);
2467
+ }
2468
+ this._lastAction = /* @__PURE__ */ new Date();
2469
+ } else {
2470
+ log8("rate limited discconnect", void 0, {
2404
2471
  F: __dxlog_file9,
2405
- L: 83,
2472
+ L: 102,
2406
2473
  S: this,
2407
2474
  C: (f, a) => f(...a)
2408
2475
  });
2409
- this._controller.disconnect(peer);
2410
2476
  }
2411
2477
  } else if (connected.length < this._originateConnections) {
2478
+ log8(`connect ${this._originateConnections - connected.length} peers.`, void 0, {
2479
+ F: __dxlog_file9,
2480
+ L: 106,
2481
+ S: this,
2482
+ C: (f, a) => f(...a)
2483
+ });
2412
2484
  const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
2413
2485
  const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
2414
- for (const peer of sorted) {
2415
- log8(`Connect ${peer}.`, void 0, {
2486
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
2487
+ log8(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
2416
2488
  F: __dxlog_file9,
2417
- L: 91,
2489
+ L: 111,
2490
+ S: this,
2491
+ C: (f, a) => f(...a)
2492
+ });
2493
+ }
2494
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
2495
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
2496
+ log8(`Connect ${peer}.`, void 0, {
2497
+ F: __dxlog_file9,
2498
+ L: 115,
2499
+ S: this,
2500
+ C: (f, a) => f(...a)
2501
+ });
2502
+ this._controller.connect(peer);
2503
+ }
2504
+ this._lastAction = /* @__PURE__ */ new Date();
2505
+ } else {
2506
+ log8("rate limited connect", void 0, {
2507
+ F: __dxlog_file9,
2508
+ L: 120,
2418
2509
  S: this,
2419
2510
  C: (f, a) => f(...a)
2420
2511
  });
2421
- this._controller.connect(peer);
2422
2512
  }
2423
2513
  }
2424
2514
  }
@@ -2530,7 +2620,7 @@ import { Event as Event7, Trigger } from "@dxos/async";
2530
2620
  import { ErrorStream as ErrorStream3 } from "@dxos/debug";
2531
2621
  import { invariant as invariant10 } from "@dxos/invariant";
2532
2622
  import { PublicKey as PublicKey9 } from "@dxos/keys";
2533
- import { log as log10, logInfo as logInfo2 } from "@dxos/log";
2623
+ import { log as log10, logInfo as logInfo3 } from "@dxos/log";
2534
2624
  import { ComplexMap as ComplexMap7 } from "@dxos/util";
2535
2625
  function _ts_decorate4(decorators, target, key, desc) {
2536
2626
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2705,12 +2795,23 @@ var MemoryTransport = class _MemoryTransport {
2705
2795
  this._remote.wake(remoteId);
2706
2796
  }
2707
2797
  }
2798
+ async getDetails() {
2799
+ return this._instanceId.toHex();
2800
+ }
2801
+ async getStats() {
2802
+ return {
2803
+ bytesSent: 0,
2804
+ bytesReceived: 0,
2805
+ packetsSent: 0,
2806
+ packetsReceived: 0
2807
+ };
2808
+ }
2708
2809
  };
2709
2810
  _ts_decorate4([
2710
- logInfo2
2811
+ logInfo3
2711
2812
  ], MemoryTransport.prototype, "_instanceId", void 0);
2712
2813
  _ts_decorate4([
2713
- logInfo2
2814
+ logInfo3
2714
2815
  ], MemoryTransport.prototype, "_remoteInstanceId", void 0);
2715
2816
 
2716
2817
  // packages/core/mesh/network-manager/src/transport/transport.ts
@@ -2742,6 +2843,9 @@ try {
2742
2843
  // packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts
2743
2844
  var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts";
2744
2845
  var SimplePeerTransport = class {
2846
+ /**
2847
+ * @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
2848
+ */
2745
2849
  constructor(params) {
2746
2850
  this.params = params;
2747
2851
  this._closed = false;
@@ -2754,13 +2858,13 @@ var SimplePeerTransport = class {
2754
2858
  id: this._instanceId
2755
2859
  }), {
2756
2860
  F: __dxlog_file12,
2757
- L: 41,
2861
+ L: 44,
2758
2862
  S: this,
2759
2863
  C: (f, a) => f(...a)
2760
2864
  });
2761
2865
  log11("created connection", params, {
2762
2866
  F: __dxlog_file12,
2763
- L: 42,
2867
+ L: 45,
2764
2868
  S: this,
2765
2869
  C: (f, a) => f(...a)
2766
2870
  });
@@ -2773,7 +2877,7 @@ var SimplePeerTransport = class {
2773
2877
  this._peer.on("signal", async (data) => {
2774
2878
  log11("signal", data, {
2775
2879
  F: __dxlog_file12,
2776
- L: 51,
2880
+ L: 54,
2777
2881
  S: this,
2778
2882
  C: (f, a) => f(...a)
2779
2883
  });
@@ -2786,7 +2890,7 @@ var SimplePeerTransport = class {
2786
2890
  this._peer.on("connect", () => {
2787
2891
  log11("connected", void 0, {
2788
2892
  F: __dxlog_file12,
2789
- L: 56,
2893
+ L: 59,
2790
2894
  S: this,
2791
2895
  C: (f, a) => f(...a)
2792
2896
  });
@@ -2797,7 +2901,7 @@ var SimplePeerTransport = class {
2797
2901
  this._peer.on("close", async () => {
2798
2902
  log11("closed", void 0, {
2799
2903
  F: __dxlog_file12,
2800
- L: 63,
2904
+ L: 66,
2801
2905
  S: this,
2802
2906
  C: (f, a) => f(...a)
2803
2907
  });
@@ -2812,7 +2916,7 @@ var SimplePeerTransport = class {
2812
2916
  err
2813
2917
  }, {
2814
2918
  F: __dxlog_file12,
2815
- L: 74,
2919
+ L: 77,
2816
2920
  S: this,
2817
2921
  C: (f, a) => f(...a)
2818
2922
  });
@@ -2821,7 +2925,7 @@ var SimplePeerTransport = class {
2821
2925
  } else if ("code" in err) {
2822
2926
  log11.info("simple-peer error", err, {
2823
2927
  F: __dxlog_file12,
2824
- L: 79,
2928
+ L: 82,
2825
2929
  S: this,
2826
2930
  C: (f, a) => f(...a)
2827
2931
  });
@@ -2851,7 +2955,7 @@ var SimplePeerTransport = class {
2851
2955
  } else {
2852
2956
  log11.info("unknown peer connection error", err, {
2853
2957
  F: __dxlog_file12,
2854
- L: 105,
2958
+ L: 108,
2855
2959
  S: this,
2856
2960
  C: (f, a) => f(...a)
2857
2961
  });
@@ -2862,10 +2966,10 @@ var SimplePeerTransport = class {
2862
2966
  this._peer._pc.getStats().then((stats) => {
2863
2967
  log11.info("report after webrtc error", {
2864
2968
  config: this.params.webrtcConfig,
2865
- stats
2969
+ stats: Object.fromEntries(stats.entries())
2866
2970
  }, {
2867
2971
  F: __dxlog_file12,
2868
- L: 113,
2972
+ L: 116,
2869
2973
  S: this,
2870
2974
  C: (f, a) => f(...a)
2871
2975
  });
@@ -2874,7 +2978,7 @@ var SimplePeerTransport = class {
2874
2978
  } catch (err2) {
2875
2979
  log11.catch(err2, void 0, {
2876
2980
  F: __dxlog_file12,
2877
- L: 120,
2981
+ L: 123,
2878
2982
  S: this,
2879
2983
  C: (f, a) => f(...a)
2880
2984
  });
@@ -2885,28 +2989,81 @@ var SimplePeerTransport = class {
2885
2989
  id: this._instanceId
2886
2990
  }), {
2887
2991
  F: __dxlog_file12,
2888
- L: 125,
2992
+ L: 129,
2889
2993
  S: this,
2890
2994
  C: (f, a) => f(...a)
2891
2995
  });
2892
2996
  }
2997
+ async getStats() {
2998
+ const stats = await this._getStats();
2999
+ if (!stats) {
3000
+ return {
3001
+ bytesSent: 0,
3002
+ bytesReceived: 0,
3003
+ packetsSent: 0,
3004
+ packetsReceived: 0,
3005
+ rawStats: {}
3006
+ };
3007
+ }
3008
+ return {
3009
+ bytesSent: stats.transport.bytesSent,
3010
+ bytesReceived: stats.transport.bytesReceived,
3011
+ packetsSent: stats.transport.packetsSent,
3012
+ packetsReceived: stats.transport.packetsReceived,
3013
+ rawStats: stats.raw
3014
+ };
3015
+ }
3016
+ async _getStats() {
3017
+ if (typeof this._peer?._pc?.getStats !== "function") {
3018
+ return null;
3019
+ }
3020
+ return await this._peer._pc.getStats().then((stats) => {
3021
+ const statsEntries = Array.from(stats.entries());
3022
+ const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
3023
+ const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
3024
+ let selectedCandidatePair;
3025
+ let remoteCandidate;
3026
+ if (candidatePair.length > 0) {
3027
+ selectedCandidatePair = candidatePair[0][1];
3028
+ remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
3029
+ }
3030
+ return {
3031
+ datachannel: statsEntries.filter((s) => s[1].type === "data-channel")[0][1],
3032
+ transport,
3033
+ selectedCandidatePair,
3034
+ remoteCandidate,
3035
+ raw: Object.fromEntries(stats.entries())
3036
+ };
3037
+ });
3038
+ }
3039
+ async getDetails() {
3040
+ const stats = await this._getStats();
3041
+ const rc = stats?.remoteCandidate;
3042
+ if (!rc) {
3043
+ return "unavailable";
3044
+ }
3045
+ if (rc.candidateType === "relay") {
3046
+ return `${rc.ip}:${rc.port}/${rc.protocol} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3047
+ }
3048
+ return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
3049
+ }
2893
3050
  async destroy() {
2894
3051
  log11("closing...", void 0, {
2895
3052
  F: __dxlog_file12,
2896
- L: 129,
3053
+ L: 192,
2897
3054
  S: this,
2898
3055
  C: (f, a) => f(...a)
2899
3056
  });
2900
3057
  if (this._closed) {
2901
3058
  return;
2902
3059
  }
2903
- this._closed = true;
2904
3060
  this._disconnectStreams();
2905
3061
  this._peer.destroy();
3062
+ this._closed = true;
2906
3063
  this.closed.emit();
2907
3064
  log11("closed", void 0, {
2908
3065
  F: __dxlog_file12,
2909
- L: 137,
3066
+ L: 200,
2910
3067
  S: this,
2911
3068
  C: (f, a) => f(...a)
2912
3069
  });
@@ -3021,7 +3178,7 @@ var SimplePeerTransportService = class {
3021
3178
  async sendSignal({ proxyId, signal }) {
3022
3179
  invariant12(this.transports.has(proxyId), void 0, {
3023
3180
  F: __dxlog_file13,
3024
- L: 112,
3181
+ L: 116,
3025
3182
  S: this,
3026
3183
  A: [
3027
3184
  "this.transports.has(proxyId)",
@@ -3030,18 +3187,46 @@ var SimplePeerTransportService = class {
3030
3187
  });
3031
3188
  await this.transports.get(proxyId).transport.signal(signal);
3032
3189
  }
3190
+ async getDetails({ proxyId }) {
3191
+ invariant12(this.transports.has(proxyId), void 0, {
3192
+ F: __dxlog_file13,
3193
+ L: 121,
3194
+ S: this,
3195
+ A: [
3196
+ "this.transports.has(proxyId)",
3197
+ ""
3198
+ ]
3199
+ });
3200
+ return {
3201
+ details: await this.transports.get(proxyId).transport.getDetails()
3202
+ };
3203
+ }
3204
+ async getStats({ proxyId }) {
3205
+ invariant12(this.transports.has(proxyId), void 0, {
3206
+ F: __dxlog_file13,
3207
+ L: 126,
3208
+ S: this,
3209
+ A: [
3210
+ "this.transports.has(proxyId)",
3211
+ ""
3212
+ ]
3213
+ });
3214
+ return {
3215
+ stats: await this.transports.get(proxyId).transport.getStats()
3216
+ };
3217
+ }
3033
3218
  async sendData({ proxyId, payload }) {
3034
3219
  if (this.transports.get(proxyId)?.state !== "OPEN") {
3035
3220
  log12.debug("transport is closed", void 0, {
3036
3221
  F: __dxlog_file13,
3037
- L: 118,
3222
+ L: 132,
3038
3223
  S: this,
3039
3224
  C: (f, a) => f(...a)
3040
3225
  });
3041
3226
  }
3042
3227
  invariant12(this.transports.has(proxyId), void 0, {
3043
3228
  F: __dxlog_file13,
3044
- L: 120,
3229
+ L: 134,
3045
3230
  S: this,
3046
3231
  A: [
3047
3232
  "this.transports.has(proxyId)",
@@ -3064,7 +3249,7 @@ var SimplePeerTransportService = class {
3064
3249
  }
3065
3250
  log12("Closed.", void 0, {
3066
3251
  F: __dxlog_file13,
3067
- L: 136,
3252
+ L: 150,
3068
3253
  S: this,
3069
3254
  C: (f, a) => f(...a)
3070
3255
  });
@@ -3203,6 +3388,16 @@ var SimplePeerTransportProxy = class {
3203
3388
  signal
3204
3389
  }).catch((err) => this.errors.raise(decodeError(err)));
3205
3390
  }
3391
+ async getDetails() {
3392
+ return (await this._params.bridgeService.getDetails({
3393
+ proxyId: this._proxyId
3394
+ })).details;
3395
+ }
3396
+ async getStats() {
3397
+ return (await this._params.bridgeService.getStats({
3398
+ proxyId: this._proxyId
3399
+ })).stats;
3400
+ }
3206
3401
  // TODO(burdon): Move open from constructor.
3207
3402
  async destroy() {
3208
3403
  await this._ctx.dispose();
@@ -3217,7 +3412,7 @@ var SimplePeerTransportProxy = class {
3217
3412
  } catch (err) {
3218
3413
  log13.catch(err, void 0, {
3219
3414
  F: __dxlog_file14,
3220
- L: 160,
3415
+ L: 168,
3221
3416
  S: this,
3222
3417
  C: (f, a) => f(...a)
3223
3418
  });
@@ -3253,7 +3448,7 @@ var SimplePeerTransportProxyFactory = class {
3253
3448
  createTransport(options) {
3254
3449
  invariant13(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
3255
3450
  F: __dxlog_file14,
3256
- L: 197,
3451
+ L: 205,
3257
3452
  S: this,
3258
3453
  A: [
3259
3454
  "this._bridgeService",
@@ -3316,17 +3511,24 @@ var LibDataChannelTransport = class {
3316
3511
  this._readyForCandidates = new Trigger2();
3317
3512
  this._writeCallback = null;
3318
3513
  this._peer = (async () => {
3319
- const { RTCPeerConnection: PeerConnection } = await import("./index.browser-O53CPVK3.mjs");
3514
+ const { RTCPeerConnection } = (await importESM("node-datachannel/polyfill")).default;
3320
3515
  if (this._closed) {
3321
3516
  this.errors.raise(new Error("connection already closed"));
3322
3517
  }
3323
- const peer = new PeerConnection(params.webrtcConfig);
3518
+ if (params.webrtcConfig) {
3519
+ params.webrtcConfig.iceServers = params.webrtcConfig.iceServers ?? [];
3520
+ } else {
3521
+ params.webrtcConfig = {
3522
+ iceServers: []
3523
+ };
3524
+ }
3525
+ const peer = new RTCPeerConnection(params.webrtcConfig);
3324
3526
  peer.onicecandidateerror = (event) => {
3325
3527
  log14.error("peer.onicecandidateerror", {
3326
3528
  event
3327
3529
  }, {
3328
3530
  F: __dxlog_file15,
3329
- L: 53,
3531
+ L: 61,
3330
3532
  S: this,
3331
3533
  C: (f, a) => f(...a)
3332
3534
  });
@@ -3338,7 +3540,7 @@ var LibDataChannelTransport = class {
3338
3540
  transportConnectionState: this._connected
3339
3541
  }, {
3340
3542
  F: __dxlog_file15,
3341
- L: 57,
3543
+ L: 65,
3342
3544
  S: this,
3343
3545
  C: (f, a) => f(...a)
3344
3546
  });
@@ -3348,7 +3550,7 @@ var LibDataChannelTransport = class {
3348
3550
  event
3349
3551
  }, {
3350
3552
  F: __dxlog_file15,
3351
- L: 66,
3553
+ L: 74,
3352
3554
  S: this,
3353
3555
  C: (f, a) => f(...a)
3354
3556
  });
@@ -3372,7 +3574,7 @@ var LibDataChannelTransport = class {
3372
3574
  err
3373
3575
  }, {
3374
3576
  F: __dxlog_file15,
3375
- L: 83,
3577
+ L: 91,
3376
3578
  S: this,
3377
3579
  C: (f, a) => f(...a)
3378
3580
  });
@@ -3381,12 +3583,15 @@ var LibDataChannelTransport = class {
3381
3583
  };
3382
3584
  if (params.initiator) {
3383
3585
  peer.createOffer().then(async (offer) => {
3586
+ if (this._closed) {
3587
+ return;
3588
+ }
3384
3589
  if (peer.connectionState !== "connecting") {
3385
3590
  log14.error("i am initiator but peer not in state connecting", {
3386
3591
  peer
3387
3592
  }, {
3388
3593
  F: __dxlog_file15,
3389
- L: 92,
3594
+ L: 104,
3390
3595
  S: this,
3391
3596
  C: (f, a) => f(...a)
3392
3597
  });
@@ -3396,7 +3601,7 @@ var LibDataChannelTransport = class {
3396
3601
  offer
3397
3602
  }, {
3398
3603
  F: __dxlog_file15,
3399
- L: 95,
3604
+ L: 107,
3400
3605
  S: this,
3401
3606
  C: (f, a) => f(...a)
3402
3607
  });
@@ -3416,7 +3621,7 @@ var LibDataChannelTransport = class {
3416
3621
  this.handleChannel(peer.createDataChannel(DATACHANNEL_LABEL));
3417
3622
  log14.debug("created data channel", void 0, {
3418
3623
  F: __dxlog_file15,
3419
- L: 104,
3624
+ L: 116,
3420
3625
  S: this,
3421
3626
  C: (f, a) => f(...a)
3422
3627
  });
@@ -3429,7 +3634,7 @@ var LibDataChannelTransport = class {
3429
3634
  event
3430
3635
  }, {
3431
3636
  F: __dxlog_file15,
3432
- L: 110,
3637
+ L: 122,
3433
3638
  S: this,
3434
3639
  C: (f, a) => f(...a)
3435
3640
  });
@@ -3447,7 +3652,7 @@ var LibDataChannelTransport = class {
3447
3652
  this._channel.onopen = () => {
3448
3653
  log14.debug("dataChannel.onopen", void 0, {
3449
3654
  F: __dxlog_file15,
3450
- L: 126,
3655
+ L: 138,
3451
3656
  S: this,
3452
3657
  C: (f, a) => f(...a)
3453
3658
  });
@@ -3468,7 +3673,7 @@ var LibDataChannelTransport = class {
3468
3673
  if (this._writeCallback !== null) {
3469
3674
  log14.error("consumer trying to write before we're ready for more data", void 0, {
3470
3675
  F: __dxlog_file15,
3471
- L: 143,
3676
+ L: 155,
3472
3677
  S: this,
3473
3678
  C: (f, a) => f(...a)
3474
3679
  });
@@ -3493,7 +3698,7 @@ var LibDataChannelTransport = class {
3493
3698
  err
3494
3699
  }, {
3495
3700
  F: __dxlog_file15,
3496
- L: 163,
3701
+ L: 175,
3497
3702
  S: this,
3498
3703
  C: (f, a) => f(...a)
3499
3704
  });
@@ -3517,6 +3722,12 @@ var LibDataChannelTransport = class {
3517
3722
  return;
3518
3723
  }
3519
3724
  await this._disconnectStreams();
3725
+ const peer = await this._peer;
3726
+ try {
3727
+ peer.close();
3728
+ } catch (err) {
3729
+ this.errors.raise(err);
3730
+ }
3520
3731
  this._closed = true;
3521
3732
  this.closed.emit();
3522
3733
  }
@@ -3530,7 +3741,7 @@ var LibDataChannelTransport = class {
3530
3741
  peer
3531
3742
  }, {
3532
3743
  F: __dxlog_file15,
3533
- L: 198,
3744
+ L: 216,
3534
3745
  S: this,
3535
3746
  C: (f, a) => f(...a)
3536
3747
  });
@@ -3558,7 +3769,7 @@ var LibDataChannelTransport = class {
3558
3769
  err
3559
3770
  }, {
3560
3771
  F: __dxlog_file15,
3561
- L: 209,
3772
+ L: 227,
3562
3773
  S: this,
3563
3774
  C: (f, a) => f(...a)
3564
3775
  });
@@ -3578,7 +3789,7 @@ var LibDataChannelTransport = class {
3578
3789
  err
3579
3790
  }, {
3580
3791
  F: __dxlog_file15,
3581
- L: 220,
3792
+ L: 238,
3582
3793
  S: this,
3583
3794
  C: (f, a) => f(...a)
3584
3795
  });
@@ -3597,7 +3808,7 @@ var LibDataChannelTransport = class {
3597
3808
  signal
3598
3809
  }, {
3599
3810
  F: __dxlog_file15,
3600
- L: 231,
3811
+ L: 249,
3601
3812
  S: this,
3602
3813
  C: (f, a) => f(...a)
3603
3814
  });
@@ -3606,12 +3817,62 @@ var LibDataChannelTransport = class {
3606
3817
  }).catch((err) => {
3607
3818
  log14.catch(err, void 0, {
3608
3819
  F: __dxlog_file15,
3609
- L: 236,
3820
+ L: 254,
3610
3821
  S: this,
3611
3822
  C: (f, a) => f(...a)
3612
3823
  });
3613
3824
  });
3614
3825
  }
3826
+ async getDetails() {
3827
+ const stats = await this._getStats();
3828
+ const rc = stats?.remoteCandidate;
3829
+ if (!rc) {
3830
+ return "unavailable";
3831
+ }
3832
+ if (rc.candidateType === "relay") {
3833
+ return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3834
+ }
3835
+ return `${rc.ip}:${rc.port} ${rc.candidateType}`;
3836
+ }
3837
+ async _getStats() {
3838
+ return this._peer.then(async (peer) => {
3839
+ const stats = await peer.getStats();
3840
+ const statsEntries = Array.from(stats.entries());
3841
+ const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
3842
+ const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
3843
+ let selectedCandidatePair;
3844
+ let remoteCandidate;
3845
+ if (candidatePair.length > 0) {
3846
+ selectedCandidatePair = candidatePair[0][1];
3847
+ remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
3848
+ }
3849
+ return {
3850
+ transport,
3851
+ selectedCandidatePair,
3852
+ remoteCandidate,
3853
+ raw: Object.fromEntries(stats)
3854
+ };
3855
+ });
3856
+ }
3857
+ async getStats() {
3858
+ const stats = await this._getStats();
3859
+ if (!stats) {
3860
+ return {
3861
+ bytesSent: 0,
3862
+ bytesReceived: 0,
3863
+ packetsSent: 0,
3864
+ packetsReceived: 0,
3865
+ rawStats: {}
3866
+ };
3867
+ }
3868
+ return {
3869
+ bytesSent: stats.transport.bytesSent,
3870
+ bytesReceived: stats.transport.bytesReceived,
3871
+ packetsSent: 0,
3872
+ packetsReceived: 0,
3873
+ rawStats: stats.raw
3874
+ };
3875
+ }
3615
3876
  // TODO(nf): add classmethod to call node-datachannel.cleanup() when all instances have been destroyed?
3616
3877
  async destroy() {
3617
3878
  await this._close();
@@ -3629,6 +3890,7 @@ var createLibDataChannelTransportFactory = (webrtcConfig) => ({
3629
3890
  webrtcConfig
3630
3891
  })
3631
3892
  });
3893
+ var importESM = Function("path", "return import(path)");
3632
3894
 
3633
3895
  // packages/core/mesh/network-manager/src/transport/tcp-transport.browser.ts
3634
3896
  import { Event as Event11 } from "@dxos/async";
@@ -3648,6 +3910,12 @@ var TcpTransport = class {
3648
3910
  signal() {
3649
3911
  throw new Error("Method not implemented.");
3650
3912
  }
3913
+ async getStats() {
3914
+ throw new Error("Method not implemented.");
3915
+ }
3916
+ async getDetails() {
3917
+ throw new Error("Method not implemented.");
3918
+ }
3651
3919
  };
3652
3920
 
3653
3921
  // packages/core/mesh/network-manager/src/wire-protocol.ts
@@ -3657,8 +3925,8 @@ var createTeleportProtocolFactory = (onConnection) => {
3657
3925
  const teleport = new Teleport(params);
3658
3926
  return {
3659
3927
  stream: teleport.stream,
3660
- open: async () => {
3661
- await teleport.open();
3928
+ open: async (sessionId) => {
3929
+ await teleport.open(sessionId);
3662
3930
  await onConnection(teleport);
3663
3931
  },
3664
3932
  close: async () => {
@@ -3699,4 +3967,4 @@ export {
3699
3967
  TcpTransport,
3700
3968
  createTeleportProtocolFactory
3701
3969
  };
3702
- //# sourceMappingURL=chunk-4HITD6WI.mjs.map
3970
+ //# sourceMappingURL=chunk-7JESB3AJ.mjs.map