@dxos/network-manager 0.3.9-main.ee9a520 → 0.3.9-main.ef334cd

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-LA2ACGLR.mjs → chunk-7JESB3AJ.mjs} +426 -116
  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-QWUG7JSH.cjs → chunk-Y2B5BDRH.cjs} +426 -104
  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 +40 -6
  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 +90 -8
  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 +70 -4
  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-LA2ACGLR.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-QWUG7JSH.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,16 +1,20 @@
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";
13
- import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, UnknownProtocolError, trace } from "@dxos/protocols";
16
+ import { log, logInfo } from "@dxos/log";
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;
16
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -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: 129,
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: 154,
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: 155,
141
+ L: 165,
133
142
  S: this,
134
143
  C: (f, a) => f(...a)
135
144
  });
@@ -141,35 +150,35 @@ var Connection = class {
141
150
  initiator: this.initiator
142
151
  }, {
143
152
  F: __dxlog_file,
144
- L: 156,
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: 173,
164
+ L: 183,
156
165
  S: this,
157
166
  C: (f, a) => f(...a)
158
167
  });
159
168
  this.close(new ProtocolError("protocol stream closed")).catch((err) => this.errors.raise(err));
160
169
  });
161
170
  scheduleTask(this.connectedTimeoutContext, async () => {
162
- log.info("timeout waiting for transport to connect, aborting", void 0, {
171
+ log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
163
172
  F: __dxlog_file,
164
- L: 180,
173
+ L: 190,
165
174
  S: this,
166
175
  C: (f, a) => f(...a)
167
176
  });
168
- await this.abort().catch((err) => this.errors.raise(err));
177
+ await this.abort(new TimeoutError(`${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect`)).catch((err) => this.errors.raise(err));
169
178
  }, TRANSPORT_CONNECTION_TIMEOUT);
170
179
  invariant(!this._transport, void 0, {
171
180
  F: __dxlog_file,
172
- L: 186,
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: 201,
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: 206,
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: 213,
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: 216,
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: 219,
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: 235,
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: 242,
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: 244,
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: 258,
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: 261,
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: 268,
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: 274,
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: 299,
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: 306,
355
+ L: 321,
345
356
  S: this,
346
357
  C: (f, a) => f(...a)
347
358
  });
@@ -351,7 +362,34 @@ var Connection = class {
351
362
  } catch (err2) {
352
363
  log.catch(err2, void 0, {
353
364
  F: __dxlog_file,
354
- L: 313,
365
+ L: 328,
366
+ S: this,
367
+ C: (f, a) => f(...a)
368
+ });
369
+ }
370
+ } else {
371
+ log.info(`graceful close requested when we were in ${lastState} state? aborting`, void 0, {
372
+ F: __dxlog_file,
373
+ L: 331,
374
+ S: this,
375
+ C: (f, a) => f(...a)
376
+ });
377
+ try {
378
+ await this._protocol.abort();
379
+ } catch (err2) {
380
+ log.catch(err2, void 0, {
381
+ F: __dxlog_file,
382
+ L: 335,
383
+ S: this,
384
+ C: (f, a) => f(...a)
385
+ });
386
+ }
387
+ try {
388
+ await this._transport?.destroy();
389
+ } catch (err2) {
390
+ log.catch(err2, void 0, {
391
+ F: __dxlog_file,
392
+ L: 340,
355
393
  S: this,
356
394
  C: (f, a) => f(...a)
357
395
  });
@@ -361,7 +399,7 @@ var Connection = class {
361
399
  peerId: this.ownId
362
400
  }, {
363
401
  F: __dxlog_file,
364
- L: 317,
402
+ L: 344,
365
403
  S: this,
366
404
  C: (f, a) => f(...a)
367
405
  });
@@ -404,7 +442,7 @@ var Connection = class {
404
442
  err
405
443
  }, {
406
444
  F: __dxlog_file,
407
- L: 355,
445
+ L: 382,
408
446
  S: this,
409
447
  C: (f, a) => f(...a)
410
448
  });
@@ -417,7 +455,7 @@ var Connection = class {
417
455
  async signal(msg) {
418
456
  invariant(msg.sessionId, void 0, {
419
457
  F: __dxlog_file,
420
- L: 364,
458
+ L: 391,
421
459
  S: this,
422
460
  A: [
423
461
  "msg.sessionId",
@@ -427,7 +465,7 @@ var Connection = class {
427
465
  if (!msg.sessionId.equals(this.sessionId)) {
428
466
  log("dropping signal for incorrect session id", void 0, {
429
467
  F: __dxlog_file,
430
- L: 366,
468
+ L: 393,
431
469
  S: this,
432
470
  C: (f, a) => f(...a)
433
471
  });
@@ -435,7 +473,7 @@ var Connection = class {
435
473
  }
436
474
  invariant(msg.data.signal || msg.data.signalBatch, void 0, {
437
475
  F: __dxlog_file,
438
- L: 369,
476
+ L: 396,
439
477
  S: this,
440
478
  A: [
441
479
  "msg.data.signal || msg.data.signalBatch",
@@ -444,7 +482,7 @@ var Connection = class {
444
482
  });
445
483
  invariant(msg.author?.equals(this.remoteId), void 0, {
446
484
  F: __dxlog_file,
447
- L: 370,
485
+ L: 397,
448
486
  S: this,
449
487
  A: [
450
488
  "msg.author?.equals(this.remoteId)",
@@ -453,7 +491,7 @@ var Connection = class {
453
491
  });
454
492
  invariant(msg.recipient?.equals(this.ownId), void 0, {
455
493
  F: __dxlog_file,
456
- L: 371,
494
+ L: 398,
457
495
  S: this,
458
496
  A: [
459
497
  "msg.recipient?.equals(this.ownId)",
@@ -477,7 +515,7 @@ var Connection = class {
477
515
  msg: msg.data
478
516
  }, {
479
517
  F: __dxlog_file,
480
- L: 380,
518
+ L: 407,
481
519
  S: this,
482
520
  C: (f, a) => f(...a)
483
521
  });
@@ -485,7 +523,7 @@ var Connection = class {
485
523
  } else {
486
524
  invariant(this._transport, "Connection not ready to accept signals.", {
487
525
  F: __dxlog_file,
488
- L: 383,
526
+ L: 410,
489
527
  S: this,
490
528
  A: [
491
529
  "this._transport",
@@ -498,7 +536,7 @@ var Connection = class {
498
536
  msg: msg.data
499
537
  }, {
500
538
  F: __dxlog_file,
501
- L: 384,
539
+ L: 411,
502
540
  S: this,
503
541
  C: (f, a) => f(...a)
504
542
  });
@@ -516,13 +554,13 @@ var Connection = class {
516
554
  peerId: this.ownId
517
555
  }, {
518
556
  F: __dxlog_file,
519
- L: 395,
557
+ L: 422,
520
558
  S: this,
521
559
  C: (f, a) => f(...a)
522
560
  });
523
561
  invariant(state !== this._state, "Already in this state.", {
524
562
  F: __dxlog_file,
525
- L: 396,
563
+ L: 423,
526
564
  S: this,
527
565
  A: [
528
566
  "state !== this._state",
@@ -532,7 +570,16 @@ var Connection = class {
532
570
  this._state = state;
533
571
  this.stateChanged.emit(state);
534
572
  }
573
+ async _emitTransportStats() {
574
+ const stats = await this.transport?.getStats();
575
+ if (stats) {
576
+ this.transportStats.emit(stats);
577
+ }
578
+ }
535
579
  };
580
+ _ts_decorate([
581
+ logInfo
582
+ ], Connection.prototype, "sessionIdString", null);
536
583
  _ts_decorate([
537
584
  synchronized
538
585
  ], Connection.prototype, "abort", null);
@@ -545,7 +592,7 @@ import { Context as Context2 } from "@dxos/context";
545
592
  import { invariant as invariant2 } from "@dxos/invariant";
546
593
  import { PublicKey as PublicKey2 } from "@dxos/keys";
547
594
  import { log as log2 } from "@dxos/log";
548
- import { schema, TimeoutError } from "@dxos/protocols";
595
+ import { schema, TimeoutError as TimeoutError2 } from "@dxos/protocols";
549
596
  import { ComplexMap } from "@dxos/util";
550
597
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/signal/swarm-messenger.ts";
551
598
  var SwarmMessage = schema.getCodecForType("dxos.mesh.swarm.SwarmMessage");
@@ -730,7 +777,7 @@ var SwarmMessenger = class {
730
777
  }
731
778
  });
732
779
  } catch (err) {
733
- if (err instanceof TimeoutError) {
780
+ if (err instanceof TimeoutError2) {
734
781
  log2.info("timeout sending answer to offer", {
735
782
  err
736
783
  }, {
@@ -789,7 +836,7 @@ import { Context as Context4 } from "@dxos/context";
789
836
  import { ErrorStream as ErrorStream2 } from "@dxos/debug";
790
837
  import { invariant as invariant4 } from "@dxos/invariant";
791
838
  import { PublicKey as PublicKey4 } from "@dxos/keys";
792
- import { log as log4, logInfo } from "@dxos/log";
839
+ import { log as log4, logInfo as logInfo2 } from "@dxos/log";
793
840
  import { trace as trace2 } from "@dxos/protocols";
794
841
  import { ComplexMap as ComplexMap2, isNotNullOrUndefined } from "@dxos/util";
795
842
 
@@ -1753,13 +1800,13 @@ var Swarm = class {
1753
1800
  }
1754
1801
  };
1755
1802
  _ts_decorate3([
1756
- logInfo
1803
+ logInfo2
1757
1804
  ], Swarm.prototype, "_instanceId", void 0);
1758
1805
  _ts_decorate3([
1759
- logInfo
1806
+ logInfo2
1760
1807
  ], Swarm.prototype, "ownPeerId", null);
1761
1808
  _ts_decorate3([
1762
- logInfo
1809
+ logInfo2
1763
1810
  ], Swarm.prototype, "topic", null);
1764
1811
  _ts_decorate3([
1765
1812
  synchronized3
@@ -1976,7 +2023,7 @@ var ConnectionLog = class {
1976
2023
  };
1977
2024
  info.connections.push(connectionInfo);
1978
2025
  this.update.emit();
1979
- connection.stateChanged.on((state) => {
2026
+ connection.stateChanged.on(async (state) => {
1980
2027
  connectionInfo.state = state;
1981
2028
  connectionInfo.closeReason = connection.closeReason;
1982
2029
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
@@ -1984,6 +2031,10 @@ var ConnectionLog = class {
1984
2031
  type: EventType.CONNECTION_STATE_CHANGED,
1985
2032
  newState: state
1986
2033
  });
2034
+ if (state === ConnectionState.CONNECTED) {
2035
+ const details = await connection.transport?.getDetails();
2036
+ connectionInfo.transportDetails = details;
2037
+ }
1987
2038
  this.update.emit();
1988
2039
  });
1989
2040
  connection.protocol?.stats?.on((stats) => {
@@ -1993,6 +2044,12 @@ var ConnectionLog = class {
1993
2044
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
1994
2045
  this.update.emit();
1995
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
+ });
1996
2053
  gcSwarm(info);
1997
2054
  });
1998
2055
  }
@@ -2296,9 +2353,12 @@ import distance from "xor-distance";
2296
2353
  import { invariant as invariant8 } from "@dxos/invariant";
2297
2354
  import { log as log8 } from "@dxos/log";
2298
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;
2299
2358
  var MMSTTopology = class {
2300
2359
  constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 } = {}) {
2301
2360
  this._sampleCollected = false;
2361
+ this._lastAction = /* @__PURE__ */ new Date(0);
2302
2362
  this._originateConnections = originateConnections;
2303
2363
  this._maxPeers = maxPeers;
2304
2364
  this._sampleSize = sampleSize;
@@ -2306,7 +2366,7 @@ var MMSTTopology = class {
2306
2366
  init(controller) {
2307
2367
  invariant8(!this._controller, "Already initialized", {
2308
2368
  F: __dxlog_file9,
2309
- L: 46,
2369
+ L: 51,
2310
2370
  S: this,
2311
2371
  A: [
2312
2372
  "!this._controller",
@@ -2318,7 +2378,7 @@ var MMSTTopology = class {
2318
2378
  update() {
2319
2379
  invariant8(this._controller, "Not initialized", {
2320
2380
  F: __dxlog_file9,
2321
- L: 51,
2381
+ L: 56,
2322
2382
  S: this,
2323
2383
  A: [
2324
2384
  "this._controller",
@@ -2329,7 +2389,7 @@ var MMSTTopology = class {
2329
2389
  if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {
2330
2390
  log8("Running the algorithm.", void 0, {
2331
2391
  F: __dxlog_file9,
2332
- L: 55,
2392
+ L: 60,
2333
2393
  S: this,
2334
2394
  C: (f, a) => f(...a)
2335
2395
  });
@@ -2340,7 +2400,7 @@ var MMSTTopology = class {
2340
2400
  async onOffer(peer) {
2341
2401
  invariant8(this._controller, "Not initialized", {
2342
2402
  F: __dxlog_file9,
2343
- L: 62,
2403
+ L: 67,
2344
2404
  S: this,
2345
2405
  A: [
2346
2406
  "this._controller",
@@ -2351,7 +2411,7 @@ var MMSTTopology = class {
2351
2411
  const accept = connected.length < this._maxPeers;
2352
2412
  log8(`Offer ${peer} accept=${accept}`, void 0, {
2353
2413
  F: __dxlog_file9,
2354
- L: 65,
2414
+ L: 70,
2355
2415
  S: this,
2356
2416
  C: (f, a) => f(...a)
2357
2417
  });
@@ -2362,7 +2422,7 @@ var MMSTTopology = class {
2362
2422
  _runAlgorithm() {
2363
2423
  invariant8(this._controller, "Not initialized", {
2364
2424
  F: __dxlog_file9,
2365
- L: 74,
2425
+ L: 79,
2366
2426
  S: this,
2367
2427
  A: [
2368
2428
  "this._controller",
@@ -2371,27 +2431,84 @@ var MMSTTopology = class {
2371
2431
  });
2372
2432
  const { connected, candidates, ownPeerId } = this._controller.getState();
2373
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
+ });
2374
2440
  const sorted = sortByXorDistance(connected, ownPeerId).reverse().slice(0, this._maxPeers - connected.length);
2375
- for (const peer of sorted) {
2376
- 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, {
2377
2452
  F: __dxlog_file9,
2378
- L: 83,
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, {
2471
+ F: __dxlog_file9,
2472
+ L: 102,
2379
2473
  S: this,
2380
2474
  C: (f, a) => f(...a)
2381
2475
  });
2382
- this._controller.disconnect(peer);
2383
2476
  }
2384
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
+ });
2385
2484
  const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
2386
2485
  const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
2387
- for (const peer of sorted) {
2388
- 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, {
2389
2488
  F: __dxlog_file9,
2390
- 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,
2391
2509
  S: this,
2392
2510
  C: (f, a) => f(...a)
2393
2511
  });
2394
- this._controller.connect(peer);
2395
2512
  }
2396
2513
  }
2397
2514
  }
@@ -2503,7 +2620,7 @@ import { Event as Event7, Trigger } from "@dxos/async";
2503
2620
  import { ErrorStream as ErrorStream3 } from "@dxos/debug";
2504
2621
  import { invariant as invariant10 } from "@dxos/invariant";
2505
2622
  import { PublicKey as PublicKey9 } from "@dxos/keys";
2506
- import { log as log10, logInfo as logInfo2 } from "@dxos/log";
2623
+ import { log as log10, logInfo as logInfo3 } from "@dxos/log";
2507
2624
  import { ComplexMap as ComplexMap7 } from "@dxos/util";
2508
2625
  function _ts_decorate4(decorators, target, key, desc) {
2509
2626
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2678,12 +2795,23 @@ var MemoryTransport = class _MemoryTransport {
2678
2795
  this._remote.wake(remoteId);
2679
2796
  }
2680
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
+ }
2681
2809
  };
2682
2810
  _ts_decorate4([
2683
- logInfo2
2811
+ logInfo3
2684
2812
  ], MemoryTransport.prototype, "_instanceId", void 0);
2685
2813
  _ts_decorate4([
2686
- logInfo2
2814
+ logInfo3
2687
2815
  ], MemoryTransport.prototype, "_remoteInstanceId", void 0);
2688
2816
 
2689
2817
  // packages/core/mesh/network-manager/src/transport/transport.ts
@@ -2715,6 +2843,9 @@ try {
2715
2843
  // packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts
2716
2844
  var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts";
2717
2845
  var SimplePeerTransport = class {
2846
+ /**
2847
+ * @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
2848
+ */
2718
2849
  constructor(params) {
2719
2850
  this.params = params;
2720
2851
  this._closed = false;
@@ -2727,13 +2858,13 @@ var SimplePeerTransport = class {
2727
2858
  id: this._instanceId
2728
2859
  }), {
2729
2860
  F: __dxlog_file12,
2730
- L: 41,
2861
+ L: 44,
2731
2862
  S: this,
2732
2863
  C: (f, a) => f(...a)
2733
2864
  });
2734
2865
  log11("created connection", params, {
2735
2866
  F: __dxlog_file12,
2736
- L: 42,
2867
+ L: 45,
2737
2868
  S: this,
2738
2869
  C: (f, a) => f(...a)
2739
2870
  });
@@ -2746,7 +2877,7 @@ var SimplePeerTransport = class {
2746
2877
  this._peer.on("signal", async (data) => {
2747
2878
  log11("signal", data, {
2748
2879
  F: __dxlog_file12,
2749
- L: 51,
2880
+ L: 54,
2750
2881
  S: this,
2751
2882
  C: (f, a) => f(...a)
2752
2883
  });
@@ -2759,7 +2890,7 @@ var SimplePeerTransport = class {
2759
2890
  this._peer.on("connect", () => {
2760
2891
  log11("connected", void 0, {
2761
2892
  F: __dxlog_file12,
2762
- L: 56,
2893
+ L: 59,
2763
2894
  S: this,
2764
2895
  C: (f, a) => f(...a)
2765
2896
  });
@@ -2770,7 +2901,7 @@ var SimplePeerTransport = class {
2770
2901
  this._peer.on("close", async () => {
2771
2902
  log11("closed", void 0, {
2772
2903
  F: __dxlog_file12,
2773
- L: 63,
2904
+ L: 66,
2774
2905
  S: this,
2775
2906
  C: (f, a) => f(...a)
2776
2907
  });
@@ -2781,12 +2912,20 @@ var SimplePeerTransport = class {
2781
2912
  if (err.errorDetail === "sctp-failure") {
2782
2913
  this.errors.raise(new ConnectionResetError2("sctp-failure from RTCError", err));
2783
2914
  } else {
2915
+ log11.info("unknown RTCError", {
2916
+ err
2917
+ }, {
2918
+ F: __dxlog_file12,
2919
+ L: 77,
2920
+ S: this,
2921
+ C: (f, a) => f(...a)
2922
+ });
2784
2923
  this.errors.raise(new UnknownProtocolError2("unknown RTCError", err));
2785
2924
  }
2786
2925
  } else if ("code" in err) {
2787
2926
  log11.info("simple-peer error", err, {
2788
2927
  F: __dxlog_file12,
2789
- L: 78,
2928
+ L: 82,
2790
2929
  S: this,
2791
2930
  C: (f, a) => f(...a)
2792
2931
  });
@@ -2794,10 +2933,12 @@ var SimplePeerTransport = class {
2794
2933
  case "ERR_WEBRTC_SUPPORT":
2795
2934
  this.errors.raise(new ProtocolError2("WebRTC not supported", err));
2796
2935
  break;
2936
+ case "ERR_SIGNALING":
2937
+ this.errors.raise(new ConnectivityError2("signaling failure", err));
2938
+ break;
2797
2939
  case "ERR_ICE_CONNECTION_FAILURE":
2798
2940
  case "ERR_DATA_CHANNEL":
2799
2941
  case "ERR_CONNECTION_FAILURE":
2800
- case "ERR_SIGNALING":
2801
2942
  this.errors.raise(new ConnectivityError2("unknown communication failure", err));
2802
2943
  break;
2803
2944
  case "ERR_CREATE_OFFER":
@@ -2814,7 +2955,7 @@ var SimplePeerTransport = class {
2814
2955
  } else {
2815
2956
  log11.info("unknown peer connection error", err, {
2816
2957
  F: __dxlog_file12,
2817
- L: 102,
2958
+ L: 108,
2818
2959
  S: this,
2819
2960
  C: (f, a) => f(...a)
2820
2961
  });
@@ -2825,10 +2966,10 @@ var SimplePeerTransport = class {
2825
2966
  this._peer._pc.getStats().then((stats) => {
2826
2967
  log11.info("report after webrtc error", {
2827
2968
  config: this.params.webrtcConfig,
2828
- stats
2969
+ stats: Object.fromEntries(stats.entries())
2829
2970
  }, {
2830
2971
  F: __dxlog_file12,
2831
- L: 110,
2972
+ L: 116,
2832
2973
  S: this,
2833
2974
  C: (f, a) => f(...a)
2834
2975
  });
@@ -2837,7 +2978,7 @@ var SimplePeerTransport = class {
2837
2978
  } catch (err2) {
2838
2979
  log11.catch(err2, void 0, {
2839
2980
  F: __dxlog_file12,
2840
- L: 117,
2981
+ L: 123,
2841
2982
  S: this,
2842
2983
  C: (f, a) => f(...a)
2843
2984
  });
@@ -2848,28 +2989,81 @@ var SimplePeerTransport = class {
2848
2989
  id: this._instanceId
2849
2990
  }), {
2850
2991
  F: __dxlog_file12,
2851
- L: 122,
2992
+ L: 129,
2852
2993
  S: this,
2853
2994
  C: (f, a) => f(...a)
2854
2995
  });
2855
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
+ }
2856
3050
  async destroy() {
2857
3051
  log11("closing...", void 0, {
2858
3052
  F: __dxlog_file12,
2859
- L: 126,
3053
+ L: 192,
2860
3054
  S: this,
2861
3055
  C: (f, a) => f(...a)
2862
3056
  });
2863
3057
  if (this._closed) {
2864
3058
  return;
2865
3059
  }
2866
- this._closed = true;
2867
3060
  this._disconnectStreams();
2868
3061
  this._peer.destroy();
3062
+ this._closed = true;
2869
3063
  this.closed.emit();
2870
3064
  log11("closed", void 0, {
2871
3065
  F: __dxlog_file12,
2872
- L: 134,
3066
+ L: 200,
2873
3067
  S: this,
2874
3068
  C: (f, a) => f(...a)
2875
3069
  });
@@ -2984,7 +3178,7 @@ var SimplePeerTransportService = class {
2984
3178
  async sendSignal({ proxyId, signal }) {
2985
3179
  invariant12(this.transports.has(proxyId), void 0, {
2986
3180
  F: __dxlog_file13,
2987
- L: 112,
3181
+ L: 116,
2988
3182
  S: this,
2989
3183
  A: [
2990
3184
  "this.transports.has(proxyId)",
@@ -2993,18 +3187,46 @@ var SimplePeerTransportService = class {
2993
3187
  });
2994
3188
  await this.transports.get(proxyId).transport.signal(signal);
2995
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
+ }
2996
3218
  async sendData({ proxyId, payload }) {
2997
3219
  if (this.transports.get(proxyId)?.state !== "OPEN") {
2998
3220
  log12.debug("transport is closed", void 0, {
2999
3221
  F: __dxlog_file13,
3000
- L: 118,
3222
+ L: 132,
3001
3223
  S: this,
3002
3224
  C: (f, a) => f(...a)
3003
3225
  });
3004
3226
  }
3005
3227
  invariant12(this.transports.has(proxyId), void 0, {
3006
3228
  F: __dxlog_file13,
3007
- L: 120,
3229
+ L: 134,
3008
3230
  S: this,
3009
3231
  A: [
3010
3232
  "this.transports.has(proxyId)",
@@ -3027,7 +3249,7 @@ var SimplePeerTransportService = class {
3027
3249
  }
3028
3250
  log12("Closed.", void 0, {
3029
3251
  F: __dxlog_file13,
3030
- L: 136,
3252
+ L: 150,
3031
3253
  S: this,
3032
3254
  C: (f, a) => f(...a)
3033
3255
  });
@@ -3042,7 +3264,7 @@ import { ErrorStream as ErrorStream5 } from "@dxos/debug";
3042
3264
  import { invariant as invariant13 } from "@dxos/invariant";
3043
3265
  import { PublicKey as PublicKey12 } from "@dxos/keys";
3044
3266
  import { log as log13 } from "@dxos/log";
3045
- import { ConnectionResetError as ConnectionResetError3, TimeoutError as TimeoutError2, ProtocolError as ProtocolError3, ConnectivityError as ConnectivityError3, UnknownProtocolError as UnknownProtocolError3 } from "@dxos/protocols";
3267
+ import { ConnectionResetError as ConnectionResetError3, TimeoutError as TimeoutError3, ProtocolError as ProtocolError3, ConnectivityError as ConnectivityError3, UnknownProtocolError as UnknownProtocolError3 } from "@dxos/protocols";
3046
3268
  import { ConnectionState as ConnectionState4 } from "@dxos/protocols/proto/dxos/mesh/bridge";
3047
3269
  import { arrayToBuffer } from "@dxos/util";
3048
3270
  var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-proxy.ts";
@@ -3098,9 +3320,9 @@ var SimplePeerTransportProxy = class {
3098
3320
  }
3099
3321
  this._timeoutCount = 0;
3100
3322
  }, (err) => {
3101
- if (err instanceof TimeoutError2 || err.constructor.name === "TimeoutError") {
3323
+ if (err instanceof TimeoutError3 || err.constructor.name === "TimeoutError") {
3102
3324
  if (this._timeoutCount++ > TIMEOUT_THRESHOLD) {
3103
- throw new TimeoutError2(`too many timeoutes (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
3325
+ throw new TimeoutError3(`too many timeoutes (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
3104
3326
  } else {
3105
3327
  log13("timeout error, but still invoking callback", void 0, {
3106
3328
  F: __dxlog_file14,
@@ -3166,6 +3388,16 @@ var SimplePeerTransportProxy = class {
3166
3388
  signal
3167
3389
  }).catch((err) => this.errors.raise(decodeError(err)));
3168
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
+ }
3169
3401
  // TODO(burdon): Move open from constructor.
3170
3402
  async destroy() {
3171
3403
  await this._ctx.dispose();
@@ -3180,7 +3412,7 @@ var SimplePeerTransportProxy = class {
3180
3412
  } catch (err) {
3181
3413
  log13.catch(err, void 0, {
3182
3414
  F: __dxlog_file14,
3183
- L: 160,
3415
+ L: 168,
3184
3416
  S: this,
3185
3417
  C: (f, a) => f(...a)
3186
3418
  });
@@ -3216,7 +3448,7 @@ var SimplePeerTransportProxyFactory = class {
3216
3448
  createTransport(options) {
3217
3449
  invariant13(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
3218
3450
  F: __dxlog_file14,
3219
- L: 197,
3451
+ L: 205,
3220
3452
  S: this,
3221
3453
  A: [
3222
3454
  "this._bridgeService",
@@ -3237,7 +3469,7 @@ var decodeError = (err) => {
3237
3469
  if (message.includes("CONNECTION_RESET")) {
3238
3470
  return new ConnectionResetError3(message);
3239
3471
  } else if (message.includes("TIMEOUT")) {
3240
- return new TimeoutError2(message);
3472
+ return new TimeoutError3(message);
3241
3473
  } else if (message.includes("PROTOCOL_ERROR")) {
3242
3474
  return new ProtocolError3(message);
3243
3475
  } else if (message.includes("CONNECTIVITY_ERROR")) {
@@ -3279,17 +3511,24 @@ var LibDataChannelTransport = class {
3279
3511
  this._readyForCandidates = new Trigger2();
3280
3512
  this._writeCallback = null;
3281
3513
  this._peer = (async () => {
3282
- const { RTCPeerConnection: PeerConnection } = await import("./index.browser-O53CPVK3.mjs");
3514
+ const { RTCPeerConnection } = (await importESM("node-datachannel/polyfill")).default;
3283
3515
  if (this._closed) {
3284
3516
  this.errors.raise(new Error("connection already closed"));
3285
3517
  }
3286
- 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);
3287
3526
  peer.onicecandidateerror = (event) => {
3288
3527
  log14.error("peer.onicecandidateerror", {
3289
3528
  event
3290
3529
  }, {
3291
3530
  F: __dxlog_file15,
3292
- L: 53,
3531
+ L: 61,
3293
3532
  S: this,
3294
3533
  C: (f, a) => f(...a)
3295
3534
  });
@@ -3301,7 +3540,7 @@ var LibDataChannelTransport = class {
3301
3540
  transportConnectionState: this._connected
3302
3541
  }, {
3303
3542
  F: __dxlog_file15,
3304
- L: 57,
3543
+ L: 65,
3305
3544
  S: this,
3306
3545
  C: (f, a) => f(...a)
3307
3546
  });
@@ -3311,7 +3550,7 @@ var LibDataChannelTransport = class {
3311
3550
  event
3312
3551
  }, {
3313
3552
  F: __dxlog_file15,
3314
- L: 66,
3553
+ L: 74,
3315
3554
  S: this,
3316
3555
  C: (f, a) => f(...a)
3317
3556
  });
@@ -3335,7 +3574,7 @@ var LibDataChannelTransport = class {
3335
3574
  err
3336
3575
  }, {
3337
3576
  F: __dxlog_file15,
3338
- L: 83,
3577
+ L: 91,
3339
3578
  S: this,
3340
3579
  C: (f, a) => f(...a)
3341
3580
  });
@@ -3344,12 +3583,15 @@ var LibDataChannelTransport = class {
3344
3583
  };
3345
3584
  if (params.initiator) {
3346
3585
  peer.createOffer().then(async (offer) => {
3586
+ if (this._closed) {
3587
+ return;
3588
+ }
3347
3589
  if (peer.connectionState !== "connecting") {
3348
3590
  log14.error("i am initiator but peer not in state connecting", {
3349
3591
  peer
3350
3592
  }, {
3351
3593
  F: __dxlog_file15,
3352
- L: 92,
3594
+ L: 104,
3353
3595
  S: this,
3354
3596
  C: (f, a) => f(...a)
3355
3597
  });
@@ -3359,7 +3601,7 @@ var LibDataChannelTransport = class {
3359
3601
  offer
3360
3602
  }, {
3361
3603
  F: __dxlog_file15,
3362
- L: 95,
3604
+ L: 107,
3363
3605
  S: this,
3364
3606
  C: (f, a) => f(...a)
3365
3607
  });
@@ -3379,7 +3621,7 @@ var LibDataChannelTransport = class {
3379
3621
  this.handleChannel(peer.createDataChannel(DATACHANNEL_LABEL));
3380
3622
  log14.debug("created data channel", void 0, {
3381
3623
  F: __dxlog_file15,
3382
- L: 104,
3624
+ L: 116,
3383
3625
  S: this,
3384
3626
  C: (f, a) => f(...a)
3385
3627
  });
@@ -3392,7 +3634,7 @@ var LibDataChannelTransport = class {
3392
3634
  event
3393
3635
  }, {
3394
3636
  F: __dxlog_file15,
3395
- L: 110,
3637
+ L: 122,
3396
3638
  S: this,
3397
3639
  C: (f, a) => f(...a)
3398
3640
  });
@@ -3410,23 +3652,28 @@ var LibDataChannelTransport = class {
3410
3652
  this._channel.onopen = () => {
3411
3653
  log14.debug("dataChannel.onopen", void 0, {
3412
3654
  F: __dxlog_file15,
3413
- L: 126,
3655
+ L: 138,
3414
3656
  S: this,
3415
3657
  C: (f, a) => f(...a)
3416
3658
  });
3417
3659
  const duplex = new Duplex2({
3418
3660
  read: () => {
3419
3661
  },
3420
- write: (chunk, encoding, callback) => {
3662
+ write: async (chunk, encoding, callback) => {
3421
3663
  if (chunk.length > MAX_MESSAGE_SIZE) {
3422
3664
  this.errors.raise(new Error(`message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}`));
3423
3665
  }
3424
- dataChannel.send(chunk);
3666
+ try {
3667
+ dataChannel.send(chunk);
3668
+ } catch (err) {
3669
+ this.errors.raise(err);
3670
+ await this._close();
3671
+ }
3425
3672
  if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
3426
3673
  if (this._writeCallback !== null) {
3427
3674
  log14.error("consumer trying to write before we're ready for more data", void 0, {
3428
3675
  F: __dxlog_file15,
3429
- L: 139,
3676
+ L: 155,
3430
3677
  S: this,
3431
3678
  C: (f, a) => f(...a)
3432
3679
  });
@@ -3451,7 +3698,7 @@ var LibDataChannelTransport = class {
3451
3698
  err
3452
3699
  }, {
3453
3700
  F: __dxlog_file15,
3454
- L: 159,
3701
+ L: 175,
3455
3702
  S: this,
3456
3703
  C: (f, a) => f(...a)
3457
3704
  });
@@ -3475,6 +3722,12 @@ var LibDataChannelTransport = class {
3475
3722
  return;
3476
3723
  }
3477
3724
  await this._disconnectStreams();
3725
+ const peer = await this._peer;
3726
+ try {
3727
+ peer.close();
3728
+ } catch (err) {
3729
+ this.errors.raise(err);
3730
+ }
3478
3731
  this._closed = true;
3479
3732
  this.closed.emit();
3480
3733
  }
@@ -3488,7 +3741,7 @@ var LibDataChannelTransport = class {
3488
3741
  peer
3489
3742
  }, {
3490
3743
  F: __dxlog_file15,
3491
- L: 194,
3744
+ L: 216,
3492
3745
  S: this,
3493
3746
  C: (f, a) => f(...a)
3494
3747
  });
@@ -3516,7 +3769,7 @@ var LibDataChannelTransport = class {
3516
3769
  err
3517
3770
  }, {
3518
3771
  F: __dxlog_file15,
3519
- L: 205,
3772
+ L: 227,
3520
3773
  S: this,
3521
3774
  C: (f, a) => f(...a)
3522
3775
  });
@@ -3536,7 +3789,7 @@ var LibDataChannelTransport = class {
3536
3789
  err
3537
3790
  }, {
3538
3791
  F: __dxlog_file15,
3539
- L: 216,
3792
+ L: 238,
3540
3793
  S: this,
3541
3794
  C: (f, a) => f(...a)
3542
3795
  });
@@ -3555,7 +3808,7 @@ var LibDataChannelTransport = class {
3555
3808
  signal
3556
3809
  }, {
3557
3810
  F: __dxlog_file15,
3558
- L: 227,
3811
+ L: 249,
3559
3812
  S: this,
3560
3813
  C: (f, a) => f(...a)
3561
3814
  });
@@ -3564,12 +3817,62 @@ var LibDataChannelTransport = class {
3564
3817
  }).catch((err) => {
3565
3818
  log14.catch(err, void 0, {
3566
3819
  F: __dxlog_file15,
3567
- L: 232,
3820
+ L: 254,
3568
3821
  S: this,
3569
3822
  C: (f, a) => f(...a)
3570
3823
  });
3571
3824
  });
3572
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
+ }
3573
3876
  // TODO(nf): add classmethod to call node-datachannel.cleanup() when all instances have been destroyed?
3574
3877
  async destroy() {
3575
3878
  await this._close();
@@ -3587,6 +3890,7 @@ var createLibDataChannelTransportFactory = (webrtcConfig) => ({
3587
3890
  webrtcConfig
3588
3891
  })
3589
3892
  });
3893
+ var importESM = Function("path", "return import(path)");
3590
3894
 
3591
3895
  // packages/core/mesh/network-manager/src/transport/tcp-transport.browser.ts
3592
3896
  import { Event as Event11 } from "@dxos/async";
@@ -3606,6 +3910,12 @@ var TcpTransport = class {
3606
3910
  signal() {
3607
3911
  throw new Error("Method not implemented.");
3608
3912
  }
3913
+ async getStats() {
3914
+ throw new Error("Method not implemented.");
3915
+ }
3916
+ async getDetails() {
3917
+ throw new Error("Method not implemented.");
3918
+ }
3609
3919
  };
3610
3920
 
3611
3921
  // packages/core/mesh/network-manager/src/wire-protocol.ts
@@ -3615,8 +3925,8 @@ var createTeleportProtocolFactory = (onConnection) => {
3615
3925
  const teleport = new Teleport(params);
3616
3926
  return {
3617
3927
  stream: teleport.stream,
3618
- open: async () => {
3619
- await teleport.open();
3928
+ open: async (sessionId) => {
3929
+ await teleport.open(sessionId);
3620
3930
  await onConnection(teleport);
3621
3931
  },
3622
3932
  close: async () => {
@@ -3657,4 +3967,4 @@ export {
3657
3967
  TcpTransport,
3658
3968
  createTeleportProtocolFactory
3659
3969
  };
3660
- //# sourceMappingURL=chunk-LA2ACGLR.mjs.map
3970
+ //# sourceMappingURL=chunk-7JESB3AJ.mjs.map