@dxos/network-manager 0.3.9-main.b7e6a67 → 0.3.9-main.c7cd0ec

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 (87) hide show
  1. package/dist/lib/browser/{chunk-LA2ACGLR.mjs → chunk-XF474R3E.mjs} +434 -116
  2. package/dist/lib/browser/chunk-XF474R3E.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 +3 -3
  6. package/dist/lib/node/{chunk-QWUG7JSH.cjs → chunk-Y2B5BDRH.cjs} +426 -104
  7. package/dist/lib/node/chunk-Y2B5BDRH.cjs.map +7 -0
  8. package/dist/lib/node/index.cjs +27 -36
  9. package/dist/lib/node/index.cjs.map +2 -2
  10. package/dist/lib/node/meta.json +1 -1
  11. package/dist/lib/node/testing/index.cjs +18 -19
  12. package/dist/lib/node/testing/index.cjs.map +1 -1
  13. package/dist/types/src/connection-log.d.ts.map +1 -1
  14. package/dist/types/src/swarm/connection.d.ts +4 -1
  15. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  16. package/dist/types/src/topology/mmst-topology.d.ts +1 -0
  17. package/dist/types/src/topology/mmst-topology.d.ts.map +1 -1
  18. package/dist/types/src/transport/index.d.ts +0 -1
  19. package/dist/types/src/transport/index.d.ts.map +1 -1
  20. package/dist/types/src/transport/libdatachannel-transport.d.ts +4 -1
  21. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -1
  22. package/dist/types/src/transport/memory-transport.d.ts +3 -1
  23. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  24. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts +3 -1
  25. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -1
  26. package/dist/types/src/transport/simplepeer-transport-service.d.ts +3 -1
  27. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -1
  28. package/dist/types/src/transport/simplepeer-transport.d.ts +7 -1
  29. package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -1
  30. package/dist/types/src/transport/tcp-transport.browser.d.ts +3 -1
  31. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -1
  32. package/dist/types/src/transport/tcp-transport.d.ts +3 -1
  33. package/dist/types/src/transport/tcp-transport.d.ts.map +1 -1
  34. package/dist/types/src/transport/transport.d.ts +17 -0
  35. package/dist/types/src/transport/transport.d.ts.map +1 -1
  36. package/dist/types/src/wire-protocol.d.ts +1 -1
  37. package/dist/types/src/wire-protocol.d.ts.map +1 -1
  38. package/package.json +18 -18
  39. package/src/connection-log.ts +14 -1
  40. package/src/swarm/connection.ts +40 -6
  41. package/src/topology/mmst-topology.ts +34 -6
  42. package/src/transport/index.ts +0 -1
  43. package/src/transport/libdatachannel-transport.test.ts +0 -4
  44. package/src/transport/libdatachannel-transport.ts +90 -8
  45. package/src/transport/memory-transport.ts +14 -1
  46. package/src/transport/simplepeer-transport-proxy.ts +9 -1
  47. package/src/transport/simplepeer-transport-service.ts +14 -0
  48. package/src/transport/simplepeer-transport.ts +70 -4
  49. package/src/transport/tcp-transport.browser.ts +9 -1
  50. package/src/transport/tcp-transport.ts +19 -1
  51. package/src/transport/transport.ts +19 -0
  52. package/src/wire-protocol.ts +3 -3
  53. package/dist/lib/browser/chunk-LA2ACGLR.mjs.map +0 -7
  54. package/dist/lib/browser/chunk-YERMWDRB.mjs +0 -24
  55. package/dist/lib/browser/chunk-YERMWDRB.mjs.map +0 -7
  56. package/dist/lib/browser/index.browser-O53CPVK3.mjs +0 -14
  57. package/dist/lib/browser/index.browser-O53CPVK3.mjs.map +0 -7
  58. package/dist/lib/node/chunk-QWUG7JSH.cjs.map +0 -7
  59. package/dist/lib/node/chunk-XE5JOIGD.cjs +0 -462
  60. package/dist/lib/node/chunk-XE5JOIGD.cjs.map +0 -7
  61. package/dist/lib/node/datachannel-53JZPGFA.cjs +0 -35
  62. package/dist/lib/node/datachannel-53JZPGFA.cjs.map +0 -7
  63. package/dist/types/src/transport/datachannel/index.browser.d.ts +0 -15
  64. package/dist/types/src/transport/datachannel/index.browser.d.ts.map +0 -1
  65. package/dist/types/src/transport/datachannel/index.d.ts +0 -8
  66. package/dist/types/src/transport/datachannel/index.d.ts.map +0 -1
  67. package/dist/types/src/transport/datachannel/rtc-data-channel.d.ts +0 -29
  68. package/dist/types/src/transport/datachannel/rtc-data-channel.d.ts.map +0 -1
  69. package/dist/types/src/transport/datachannel/rtc-events.d.ts +0 -9
  70. package/dist/types/src/transport/datachannel/rtc-events.d.ts.map +0 -1
  71. package/dist/types/src/transport/datachannel/rtc-ice-candidate.d.ts +0 -22
  72. package/dist/types/src/transport/datachannel/rtc-ice-candidate.d.ts.map +0 -1
  73. package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts +0 -47
  74. package/dist/types/src/transport/datachannel/rtc-peer-connection.d.ts.map +0 -1
  75. package/dist/types/src/transport/datachannel/rtc-peer-connection.test.d.ts +0 -2
  76. package/dist/types/src/transport/datachannel/rtc-peer-connection.test.d.ts.map +0 -1
  77. package/dist/types/src/transport/datachannel/rtc-session-description.d.ts +0 -10
  78. package/dist/types/src/transport/datachannel/rtc-session-description.d.ts.map +0 -1
  79. package/src/transport/datachannel/README.md +0 -2
  80. package/src/transport/datachannel/index.browser.ts +0 -8
  81. package/src/transport/datachannel/index.ts +0 -17
  82. package/src/transport/datachannel/rtc-data-channel.ts +0 -148
  83. package/src/transport/datachannel/rtc-events.ts +0 -23
  84. package/src/transport/datachannel/rtc-ice-candidate.ts +0 -54
  85. package/src/transport/datachannel/rtc-peer-connection.test.ts +0 -112
  86. package/src/transport/datachannel/rtc-peer-connection.ts +0 -347
  87. package/src/transport/datachannel/rtc-session-description.ts +0 -23
@@ -1,16 +1,27 @@
1
1
  import "@dxos/node-std/globals";
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
+ });
9
+
10
+ // inject-globals:@inject-globals
2
11
  import {
3
- __require
4
- } from "./chunk-YERMWDRB.mjs";
12
+ global,
13
+ Buffer as Buffer2,
14
+ process
15
+ } from "@dxos/node-std/inject-globals";
5
16
 
6
17
  // packages/core/mesh/network-manager/src/swarm/connection.ts
7
- import { DeferredTask, Event, sleep, scheduleTask, synchronized } from "@dxos/async";
18
+ import { DeferredTask, Event, sleep, scheduleTask, scheduleTaskInterval, synchronized } from "@dxos/async";
8
19
  import { Context, cancelWithContext } from "@dxos/context";
9
20
  import { ErrorStream } from "@dxos/debug";
10
21
  import { invariant } from "@dxos/invariant";
11
22
  import { PublicKey } from "@dxos/keys";
12
- import { log } from "@dxos/log";
13
- import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, UnknownProtocolError, trace } from "@dxos/protocols";
23
+ import { log, logInfo } from "@dxos/log";
24
+ import { CancelledError, ProtocolError, ConnectionResetError, ConnectivityError, TimeoutError, UnknownProtocolError, trace } from "@dxos/protocols";
14
25
  function _ts_decorate(decorators, target, key, desc) {
15
26
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
27
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -24,6 +35,7 @@ function _ts_decorate(decorators, target, key, desc) {
24
35
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/swarm/connection.ts";
25
36
  var STARTING_SIGNALLING_DELAY = 10;
26
37
  var TRANSPORT_CONNECTION_TIMEOUT = 1e4;
38
+ var TRANSPORT_STATS_INTERVAL = 5e3;
27
39
  var MAX_SIGNALLING_DELAY = 300;
28
40
  var ConnectionState;
29
41
  (function(ConnectionState5) {
@@ -86,6 +98,7 @@ var Connection = class {
86
98
  this.stateChanged = new Event();
87
99
  this.errors = new ErrorStream();
88
100
  this._instanceId = PublicKey.random().toHex();
101
+ this.transportStats = new Event();
89
102
  this._signalSendTask = new DeferredTask(this._ctx, async () => {
90
103
  await this._flushSignalBuffer();
91
104
  });
@@ -98,11 +111,14 @@ var Connection = class {
98
111
  initiator: this.initiator
99
112
  }, {
100
113
  F: __dxlog_file,
101
- L: 129,
114
+ L: 134,
102
115
  S: this,
103
116
  C: (f, a) => f(...a)
104
117
  });
105
118
  }
119
+ get sessionIdString() {
120
+ return this.sessionId.truncate();
121
+ }
106
122
  get state() {
107
123
  return this._state;
108
124
  }
@@ -118,7 +134,7 @@ var Connection = class {
118
134
  async openConnection() {
119
135
  invariant(this._state === ConnectionState.INITIAL, "Invalid state.", {
120
136
  F: __dxlog_file,
121
- L: 154,
137
+ L: 164,
122
138
  S: this,
123
139
  A: [
124
140
  "this._state === ConnectionState.INITIAL",
@@ -129,7 +145,7 @@ var Connection = class {
129
145
  id: this._instanceId
130
146
  }), {
131
147
  F: __dxlog_file,
132
- L: 155,
148
+ L: 165,
133
149
  S: this,
134
150
  C: (f, a) => f(...a)
135
151
  });
@@ -141,35 +157,35 @@ var Connection = class {
141
157
  initiator: this.initiator
142
158
  }, {
143
159
  F: __dxlog_file,
144
- L: 156,
160
+ L: 166,
145
161
  S: this,
146
162
  C: (f, a) => f(...a)
147
163
  });
148
164
  this._changeState(ConnectionState.CONNECTING);
149
- this._protocol.open().catch((err) => {
165
+ this._protocol.open(this.sessionId).catch((err) => {
150
166
  this.errors.raise(err);
151
167
  });
152
168
  this._protocol.stream.on("close", () => {
153
169
  log("protocol stream closed", void 0, {
154
170
  F: __dxlog_file,
155
- L: 173,
171
+ L: 183,
156
172
  S: this,
157
173
  C: (f, a) => f(...a)
158
174
  });
159
175
  this.close(new ProtocolError("protocol stream closed")).catch((err) => this.errors.raise(err));
160
176
  });
161
177
  scheduleTask(this.connectedTimeoutContext, async () => {
162
- log.info("timeout waiting for transport to connect, aborting", void 0, {
178
+ log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
163
179
  F: __dxlog_file,
164
- L: 180,
180
+ L: 190,
165
181
  S: this,
166
182
  C: (f, a) => f(...a)
167
183
  });
168
- await this.abort().catch((err) => this.errors.raise(err));
184
+ await this.abort(new TimeoutError(`${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect`)).catch((err) => this.errors.raise(err));
169
185
  }, TRANSPORT_CONNECTION_TIMEOUT);
170
186
  invariant(!this._transport, void 0, {
171
187
  F: __dxlog_file,
172
- L: 186,
188
+ L: 198,
173
189
  S: this,
174
190
  A: [
175
191
  "!this._transport",
@@ -179,18 +195,20 @@ var Connection = class {
179
195
  this._transport = this._transportFactory.createTransport({
180
196
  initiator: this.initiator,
181
197
  stream: this._protocol.stream,
182
- sendSignal: async (signal) => this._sendSignal(signal)
198
+ sendSignal: async (signal) => this._sendSignal(signal),
199
+ sessionId: this.sessionId
183
200
  });
184
201
  this._transport.connected.once(async () => {
185
202
  this._changeState(ConnectionState.CONNECTED);
186
203
  await this.connectedTimeoutContext.dispose();
187
204
  this._callbacks?.onConnected?.();
205
+ scheduleTaskInterval(this._ctx, async () => this._emitTransportStats(), TRANSPORT_STATS_INTERVAL);
188
206
  });
189
207
  this._transport.closed.once(() => {
190
208
  this._transport = void 0;
191
209
  log("abort triggered by transport close", void 0, {
192
210
  F: __dxlog_file,
193
- L: 201,
211
+ L: 216,
194
212
  S: this,
195
213
  C: (f, a) => f(...a)
196
214
  });
@@ -201,7 +219,7 @@ var Connection = class {
201
219
  err
202
220
  }, {
203
221
  F: __dxlog_file,
204
- L: 206,
222
+ L: 221,
205
223
  S: this,
206
224
  C: (f, a) => f(...a)
207
225
  });
@@ -211,7 +229,7 @@ var Connection = class {
211
229
  if (err instanceof ConnectionResetError) {
212
230
  log.info("aborting due to transport ConnectionResetError", void 0, {
213
231
  F: __dxlog_file,
214
- L: 213,
232
+ L: 228,
215
233
  S: this,
216
234
  C: (f, a) => f(...a)
217
235
  });
@@ -219,7 +237,7 @@ var Connection = class {
219
237
  } else if (err instanceof ConnectivityError) {
220
238
  log.info("aborting due to transport ConnectivityError", void 0, {
221
239
  F: __dxlog_file,
222
- L: 216,
240
+ L: 231,
223
241
  S: this,
224
242
  C: (f, a) => f(...a)
225
243
  });
@@ -229,7 +247,7 @@ var Connection = class {
229
247
  err
230
248
  }, {
231
249
  F: __dxlog_file,
232
- L: 219,
250
+ L: 234,
233
251
  S: this,
234
252
  C: (f, a) => f(...a)
235
253
  });
@@ -247,7 +265,7 @@ var Connection = class {
247
265
  id: this._instanceId
248
266
  }), {
249
267
  F: __dxlog_file,
250
- L: 235,
268
+ L: 250,
251
269
  S: this,
252
270
  C: (f, a) => f(...a)
253
271
  });
@@ -257,14 +275,14 @@ var Connection = class {
257
275
  err
258
276
  }, {
259
277
  F: __dxlog_file,
260
- L: 242,
278
+ L: 257,
261
279
  S: this,
262
280
  C: (f, a) => f(...a)
263
281
  });
264
282
  if (this._state === ConnectionState.CLOSED || this._state === ConnectionState.ABORTED) {
265
283
  log(`abort ignored: already ${this._state}`, this.closeReason, {
266
284
  F: __dxlog_file,
267
- L: 244,
285
+ L: 259,
268
286
  S: this,
269
287
  C: (f, a) => f(...a)
270
288
  });
@@ -279,7 +297,7 @@ var Connection = class {
279
297
  try {
280
298
  log("aborting protocol... ", void 0, {
281
299
  F: __dxlog_file,
282
- L: 258,
300
+ L: 273,
283
301
  S: this,
284
302
  C: (f, a) => f(...a)
285
303
  });
@@ -287,7 +305,7 @@ var Connection = class {
287
305
  } catch (err2) {
288
306
  log.catch(err2, void 0, {
289
307
  F: __dxlog_file,
290
- L: 261,
308
+ L: 276,
291
309
  S: this,
292
310
  C: (f, a) => f(...a)
293
311
  });
@@ -297,7 +315,7 @@ var Connection = class {
297
315
  } catch (err2) {
298
316
  log.catch(err2, void 0, {
299
317
  F: __dxlog_file,
300
- L: 268,
318
+ L: 283,
301
319
  S: this,
302
320
  C: (f, a) => f(...a)
303
321
  });
@@ -307,7 +325,7 @@ var Connection = class {
307
325
  } catch (err2) {
308
326
  log.catch(err2, void 0, {
309
327
  F: __dxlog_file,
310
- L: 274,
328
+ L: 289,
311
329
  S: this,
312
330
  C: (f, a) => f(...a)
313
331
  });
@@ -331,7 +349,7 @@ var Connection = class {
331
349
  peerId: this.ownId
332
350
  }, {
333
351
  F: __dxlog_file,
334
- L: 299,
352
+ L: 314,
335
353
  S: this,
336
354
  C: (f, a) => f(...a)
337
355
  });
@@ -341,7 +359,7 @@ var Connection = class {
341
359
  } catch (err2) {
342
360
  log.catch(err2, void 0, {
343
361
  F: __dxlog_file,
344
- L: 306,
362
+ L: 321,
345
363
  S: this,
346
364
  C: (f, a) => f(...a)
347
365
  });
@@ -351,7 +369,34 @@ var Connection = class {
351
369
  } catch (err2) {
352
370
  log.catch(err2, void 0, {
353
371
  F: __dxlog_file,
354
- L: 313,
372
+ L: 328,
373
+ S: this,
374
+ C: (f, a) => f(...a)
375
+ });
376
+ }
377
+ } else {
378
+ log.info(`graceful close requested when we were in ${lastState} state? aborting`, void 0, {
379
+ F: __dxlog_file,
380
+ L: 331,
381
+ S: this,
382
+ C: (f, a) => f(...a)
383
+ });
384
+ try {
385
+ await this._protocol.abort();
386
+ } catch (err2) {
387
+ log.catch(err2, void 0, {
388
+ F: __dxlog_file,
389
+ L: 335,
390
+ S: this,
391
+ C: (f, a) => f(...a)
392
+ });
393
+ }
394
+ try {
395
+ await this._transport?.destroy();
396
+ } catch (err2) {
397
+ log.catch(err2, void 0, {
398
+ F: __dxlog_file,
399
+ L: 340,
355
400
  S: this,
356
401
  C: (f, a) => f(...a)
357
402
  });
@@ -361,7 +406,7 @@ var Connection = class {
361
406
  peerId: this.ownId
362
407
  }, {
363
408
  F: __dxlog_file,
364
- L: 317,
409
+ L: 344,
365
410
  S: this,
366
411
  C: (f, a) => f(...a)
367
412
  });
@@ -404,7 +449,7 @@ var Connection = class {
404
449
  err
405
450
  }, {
406
451
  F: __dxlog_file,
407
- L: 355,
452
+ L: 382,
408
453
  S: this,
409
454
  C: (f, a) => f(...a)
410
455
  });
@@ -417,7 +462,7 @@ var Connection = class {
417
462
  async signal(msg) {
418
463
  invariant(msg.sessionId, void 0, {
419
464
  F: __dxlog_file,
420
- L: 364,
465
+ L: 391,
421
466
  S: this,
422
467
  A: [
423
468
  "msg.sessionId",
@@ -427,7 +472,7 @@ var Connection = class {
427
472
  if (!msg.sessionId.equals(this.sessionId)) {
428
473
  log("dropping signal for incorrect session id", void 0, {
429
474
  F: __dxlog_file,
430
- L: 366,
475
+ L: 393,
431
476
  S: this,
432
477
  C: (f, a) => f(...a)
433
478
  });
@@ -435,7 +480,7 @@ var Connection = class {
435
480
  }
436
481
  invariant(msg.data.signal || msg.data.signalBatch, void 0, {
437
482
  F: __dxlog_file,
438
- L: 369,
483
+ L: 396,
439
484
  S: this,
440
485
  A: [
441
486
  "msg.data.signal || msg.data.signalBatch",
@@ -444,7 +489,7 @@ var Connection = class {
444
489
  });
445
490
  invariant(msg.author?.equals(this.remoteId), void 0, {
446
491
  F: __dxlog_file,
447
- L: 370,
492
+ L: 397,
448
493
  S: this,
449
494
  A: [
450
495
  "msg.author?.equals(this.remoteId)",
@@ -453,7 +498,7 @@ var Connection = class {
453
498
  });
454
499
  invariant(msg.recipient?.equals(this.ownId), void 0, {
455
500
  F: __dxlog_file,
456
- L: 371,
501
+ L: 398,
457
502
  S: this,
458
503
  A: [
459
504
  "msg.recipient?.equals(this.ownId)",
@@ -477,7 +522,7 @@ var Connection = class {
477
522
  msg: msg.data
478
523
  }, {
479
524
  F: __dxlog_file,
480
- L: 380,
525
+ L: 407,
481
526
  S: this,
482
527
  C: (f, a) => f(...a)
483
528
  });
@@ -485,7 +530,7 @@ var Connection = class {
485
530
  } else {
486
531
  invariant(this._transport, "Connection not ready to accept signals.", {
487
532
  F: __dxlog_file,
488
- L: 383,
533
+ L: 410,
489
534
  S: this,
490
535
  A: [
491
536
  "this._transport",
@@ -498,7 +543,7 @@ var Connection = class {
498
543
  msg: msg.data
499
544
  }, {
500
545
  F: __dxlog_file,
501
- L: 384,
546
+ L: 411,
502
547
  S: this,
503
548
  C: (f, a) => f(...a)
504
549
  });
@@ -516,13 +561,13 @@ var Connection = class {
516
561
  peerId: this.ownId
517
562
  }, {
518
563
  F: __dxlog_file,
519
- L: 395,
564
+ L: 422,
520
565
  S: this,
521
566
  C: (f, a) => f(...a)
522
567
  });
523
568
  invariant(state !== this._state, "Already in this state.", {
524
569
  F: __dxlog_file,
525
- L: 396,
570
+ L: 423,
526
571
  S: this,
527
572
  A: [
528
573
  "state !== this._state",
@@ -532,7 +577,16 @@ var Connection = class {
532
577
  this._state = state;
533
578
  this.stateChanged.emit(state);
534
579
  }
580
+ async _emitTransportStats() {
581
+ const stats = await this.transport?.getStats();
582
+ if (stats) {
583
+ this.transportStats.emit(stats);
584
+ }
585
+ }
535
586
  };
587
+ _ts_decorate([
588
+ logInfo
589
+ ], Connection.prototype, "sessionIdString", null);
536
590
  _ts_decorate([
537
591
  synchronized
538
592
  ], Connection.prototype, "abort", null);
@@ -545,7 +599,7 @@ import { Context as Context2 } from "@dxos/context";
545
599
  import { invariant as invariant2 } from "@dxos/invariant";
546
600
  import { PublicKey as PublicKey2 } from "@dxos/keys";
547
601
  import { log as log2 } from "@dxos/log";
548
- import { schema, TimeoutError } from "@dxos/protocols";
602
+ import { schema, TimeoutError as TimeoutError2 } from "@dxos/protocols";
549
603
  import { ComplexMap } from "@dxos/util";
550
604
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/signal/swarm-messenger.ts";
551
605
  var SwarmMessage = schema.getCodecForType("dxos.mesh.swarm.SwarmMessage");
@@ -730,7 +784,7 @@ var SwarmMessenger = class {
730
784
  }
731
785
  });
732
786
  } catch (err) {
733
- if (err instanceof TimeoutError) {
787
+ if (err instanceof TimeoutError2) {
734
788
  log2.info("timeout sending answer to offer", {
735
789
  err
736
790
  }, {
@@ -789,7 +843,7 @@ import { Context as Context4 } from "@dxos/context";
789
843
  import { ErrorStream as ErrorStream2 } from "@dxos/debug";
790
844
  import { invariant as invariant4 } from "@dxos/invariant";
791
845
  import { PublicKey as PublicKey4 } from "@dxos/keys";
792
- import { log as log4, logInfo } from "@dxos/log";
846
+ import { log as log4, logInfo as logInfo2 } from "@dxos/log";
793
847
  import { trace as trace2 } from "@dxos/protocols";
794
848
  import { ComplexMap as ComplexMap2, isNotNullOrUndefined } from "@dxos/util";
795
849
 
@@ -1753,13 +1807,13 @@ var Swarm = class {
1753
1807
  }
1754
1808
  };
1755
1809
  _ts_decorate3([
1756
- logInfo
1810
+ logInfo2
1757
1811
  ], Swarm.prototype, "_instanceId", void 0);
1758
1812
  _ts_decorate3([
1759
- logInfo
1813
+ logInfo2
1760
1814
  ], Swarm.prototype, "ownPeerId", null);
1761
1815
  _ts_decorate3([
1762
- logInfo
1816
+ logInfo2
1763
1817
  ], Swarm.prototype, "topic", null);
1764
1818
  _ts_decorate3([
1765
1819
  synchronized3
@@ -1976,7 +2030,7 @@ var ConnectionLog = class {
1976
2030
  };
1977
2031
  info.connections.push(connectionInfo);
1978
2032
  this.update.emit();
1979
- connection.stateChanged.on((state) => {
2033
+ connection.stateChanged.on(async (state) => {
1980
2034
  connectionInfo.state = state;
1981
2035
  connectionInfo.closeReason = connection.closeReason;
1982
2036
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
@@ -1984,6 +2038,10 @@ var ConnectionLog = class {
1984
2038
  type: EventType.CONNECTION_STATE_CHANGED,
1985
2039
  newState: state
1986
2040
  });
2041
+ if (state === ConnectionState.CONNECTED) {
2042
+ const details = await connection.transport?.getDetails();
2043
+ connectionInfo.transportDetails = details;
2044
+ }
1987
2045
  this.update.emit();
1988
2046
  });
1989
2047
  connection.protocol?.stats?.on((stats) => {
@@ -1993,6 +2051,12 @@ var ConnectionLog = class {
1993
2051
  connectionInfo.lastUpdate = /* @__PURE__ */ new Date();
1994
2052
  this.update.emit();
1995
2053
  });
2054
+ connection.transportStats?.on((stats) => {
2055
+ connectionInfo.transportBytesSent = stats.bytesSent;
2056
+ connectionInfo.transportBytesReceived = stats.bytesReceived;
2057
+ connectionInfo.transportPacketsSent = stats.packetsSent;
2058
+ connectionInfo.transportPacketsReceived = stats.packetsReceived;
2059
+ });
1996
2060
  gcSwarm(info);
1997
2061
  });
1998
2062
  }
@@ -2296,9 +2360,12 @@ import distance from "xor-distance";
2296
2360
  import { invariant as invariant8 } from "@dxos/invariant";
2297
2361
  import { log as log8 } from "@dxos/log";
2298
2362
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/mmst-topology.ts";
2363
+ var MIN_UPDATE_INTERVAL = 1e3 * 10;
2364
+ var MAX_CHANGES_PER_UPDATE = 1;
2299
2365
  var MMSTTopology = class {
2300
2366
  constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 } = {}) {
2301
2367
  this._sampleCollected = false;
2368
+ this._lastAction = /* @__PURE__ */ new Date(0);
2302
2369
  this._originateConnections = originateConnections;
2303
2370
  this._maxPeers = maxPeers;
2304
2371
  this._sampleSize = sampleSize;
@@ -2306,7 +2373,7 @@ var MMSTTopology = class {
2306
2373
  init(controller) {
2307
2374
  invariant8(!this._controller, "Already initialized", {
2308
2375
  F: __dxlog_file9,
2309
- L: 46,
2376
+ L: 51,
2310
2377
  S: this,
2311
2378
  A: [
2312
2379
  "!this._controller",
@@ -2318,7 +2385,7 @@ var MMSTTopology = class {
2318
2385
  update() {
2319
2386
  invariant8(this._controller, "Not initialized", {
2320
2387
  F: __dxlog_file9,
2321
- L: 51,
2388
+ L: 56,
2322
2389
  S: this,
2323
2390
  A: [
2324
2391
  "this._controller",
@@ -2329,7 +2396,7 @@ var MMSTTopology = class {
2329
2396
  if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {
2330
2397
  log8("Running the algorithm.", void 0, {
2331
2398
  F: __dxlog_file9,
2332
- L: 55,
2399
+ L: 60,
2333
2400
  S: this,
2334
2401
  C: (f, a) => f(...a)
2335
2402
  });
@@ -2340,7 +2407,7 @@ var MMSTTopology = class {
2340
2407
  async onOffer(peer) {
2341
2408
  invariant8(this._controller, "Not initialized", {
2342
2409
  F: __dxlog_file9,
2343
- L: 62,
2410
+ L: 67,
2344
2411
  S: this,
2345
2412
  A: [
2346
2413
  "this._controller",
@@ -2351,7 +2418,7 @@ var MMSTTopology = class {
2351
2418
  const accept = connected.length < this._maxPeers;
2352
2419
  log8(`Offer ${peer} accept=${accept}`, void 0, {
2353
2420
  F: __dxlog_file9,
2354
- L: 65,
2421
+ L: 70,
2355
2422
  S: this,
2356
2423
  C: (f, a) => f(...a)
2357
2424
  });
@@ -2362,7 +2429,7 @@ var MMSTTopology = class {
2362
2429
  _runAlgorithm() {
2363
2430
  invariant8(this._controller, "Not initialized", {
2364
2431
  F: __dxlog_file9,
2365
- L: 74,
2432
+ L: 79,
2366
2433
  S: this,
2367
2434
  A: [
2368
2435
  "this._controller",
@@ -2371,27 +2438,84 @@ var MMSTTopology = class {
2371
2438
  });
2372
2439
  const { connected, candidates, ownPeerId } = this._controller.getState();
2373
2440
  if (connected.length > this._maxPeers) {
2441
+ log8(`disconnect ${connected.length - this._maxPeers} peers.`, void 0, {
2442
+ F: __dxlog_file9,
2443
+ L: 85,
2444
+ S: this,
2445
+ C: (f, a) => f(...a)
2446
+ });
2374
2447
  const sorted = sortByXorDistance(connected, ownPeerId).reverse().slice(0, this._maxPeers - connected.length);
2375
- for (const peer of sorted) {
2376
- log8(`Disconnect ${peer}.`, void 0, {
2448
+ invariant8(sorted.length === 0, void 0, {
2449
+ F: __dxlog_file9,
2450
+ L: 89,
2451
+ S: this,
2452
+ A: [
2453
+ "sorted.length === 0",
2454
+ ""
2455
+ ]
2456
+ });
2457
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
2458
+ log8(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
2377
2459
  F: __dxlog_file9,
2378
- L: 83,
2460
+ L: 92,
2461
+ S: this,
2462
+ C: (f, a) => f(...a)
2463
+ });
2464
+ }
2465
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
2466
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
2467
+ log8(`Disconnect ${peer}.`, void 0, {
2468
+ F: __dxlog_file9,
2469
+ L: 97,
2470
+ S: this,
2471
+ C: (f, a) => f(...a)
2472
+ });
2473
+ this._controller.disconnect(peer);
2474
+ }
2475
+ this._lastAction = /* @__PURE__ */ new Date();
2476
+ } else {
2477
+ log8("rate limited discconnect", void 0, {
2478
+ F: __dxlog_file9,
2479
+ L: 102,
2379
2480
  S: this,
2380
2481
  C: (f, a) => f(...a)
2381
2482
  });
2382
- this._controller.disconnect(peer);
2383
2483
  }
2384
2484
  } else if (connected.length < this._originateConnections) {
2485
+ log8(`connect ${this._originateConnections - connected.length} peers.`, void 0, {
2486
+ F: __dxlog_file9,
2487
+ L: 106,
2488
+ S: this,
2489
+ C: (f, a) => f(...a)
2490
+ });
2385
2491
  const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
2386
2492
  const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
2387
- for (const peer of sorted) {
2388
- log8(`Connect ${peer}.`, void 0, {
2493
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
2494
+ log8(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
2389
2495
  F: __dxlog_file9,
2390
- L: 91,
2496
+ L: 111,
2497
+ S: this,
2498
+ C: (f, a) => f(...a)
2499
+ });
2500
+ }
2501
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
2502
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
2503
+ log8(`Connect ${peer}.`, void 0, {
2504
+ F: __dxlog_file9,
2505
+ L: 115,
2506
+ S: this,
2507
+ C: (f, a) => f(...a)
2508
+ });
2509
+ this._controller.connect(peer);
2510
+ }
2511
+ this._lastAction = /* @__PURE__ */ new Date();
2512
+ } else {
2513
+ log8("rate limited connect", void 0, {
2514
+ F: __dxlog_file9,
2515
+ L: 120,
2391
2516
  S: this,
2392
2517
  C: (f, a) => f(...a)
2393
2518
  });
2394
- this._controller.connect(peer);
2395
2519
  }
2396
2520
  }
2397
2521
  }
@@ -2503,7 +2627,7 @@ import { Event as Event7, Trigger } from "@dxos/async";
2503
2627
  import { ErrorStream as ErrorStream3 } from "@dxos/debug";
2504
2628
  import { invariant as invariant10 } from "@dxos/invariant";
2505
2629
  import { PublicKey as PublicKey9 } from "@dxos/keys";
2506
- import { log as log10, logInfo as logInfo2 } from "@dxos/log";
2630
+ import { log as log10, logInfo as logInfo3 } from "@dxos/log";
2507
2631
  import { ComplexMap as ComplexMap7 } from "@dxos/util";
2508
2632
  function _ts_decorate4(decorators, target, key, desc) {
2509
2633
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2678,12 +2802,23 @@ var MemoryTransport = class _MemoryTransport {
2678
2802
  this._remote.wake(remoteId);
2679
2803
  }
2680
2804
  }
2805
+ async getDetails() {
2806
+ return this._instanceId.toHex();
2807
+ }
2808
+ async getStats() {
2809
+ return {
2810
+ bytesSent: 0,
2811
+ bytesReceived: 0,
2812
+ packetsSent: 0,
2813
+ packetsReceived: 0
2814
+ };
2815
+ }
2681
2816
  };
2682
2817
  _ts_decorate4([
2683
- logInfo2
2818
+ logInfo3
2684
2819
  ], MemoryTransport.prototype, "_instanceId", void 0);
2685
2820
  _ts_decorate4([
2686
- logInfo2
2821
+ logInfo3
2687
2822
  ], MemoryTransport.prototype, "_remoteInstanceId", void 0);
2688
2823
 
2689
2824
  // packages/core/mesh/network-manager/src/transport/transport.ts
@@ -2715,6 +2850,9 @@ try {
2715
2850
  // packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts
2716
2851
  var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts";
2717
2852
  var SimplePeerTransport = class {
2853
+ /**
2854
+ * @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
2855
+ */
2718
2856
  constructor(params) {
2719
2857
  this.params = params;
2720
2858
  this._closed = false;
@@ -2727,13 +2865,13 @@ var SimplePeerTransport = class {
2727
2865
  id: this._instanceId
2728
2866
  }), {
2729
2867
  F: __dxlog_file12,
2730
- L: 41,
2868
+ L: 44,
2731
2869
  S: this,
2732
2870
  C: (f, a) => f(...a)
2733
2871
  });
2734
2872
  log11("created connection", params, {
2735
2873
  F: __dxlog_file12,
2736
- L: 42,
2874
+ L: 45,
2737
2875
  S: this,
2738
2876
  C: (f, a) => f(...a)
2739
2877
  });
@@ -2746,7 +2884,7 @@ var SimplePeerTransport = class {
2746
2884
  this._peer.on("signal", async (data) => {
2747
2885
  log11("signal", data, {
2748
2886
  F: __dxlog_file12,
2749
- L: 51,
2887
+ L: 54,
2750
2888
  S: this,
2751
2889
  C: (f, a) => f(...a)
2752
2890
  });
@@ -2759,7 +2897,7 @@ var SimplePeerTransport = class {
2759
2897
  this._peer.on("connect", () => {
2760
2898
  log11("connected", void 0, {
2761
2899
  F: __dxlog_file12,
2762
- L: 56,
2900
+ L: 59,
2763
2901
  S: this,
2764
2902
  C: (f, a) => f(...a)
2765
2903
  });
@@ -2770,7 +2908,7 @@ var SimplePeerTransport = class {
2770
2908
  this._peer.on("close", async () => {
2771
2909
  log11("closed", void 0, {
2772
2910
  F: __dxlog_file12,
2773
- L: 63,
2911
+ L: 66,
2774
2912
  S: this,
2775
2913
  C: (f, a) => f(...a)
2776
2914
  });
@@ -2781,12 +2919,20 @@ var SimplePeerTransport = class {
2781
2919
  if (err.errorDetail === "sctp-failure") {
2782
2920
  this.errors.raise(new ConnectionResetError2("sctp-failure from RTCError", err));
2783
2921
  } else {
2922
+ log11.info("unknown RTCError", {
2923
+ err
2924
+ }, {
2925
+ F: __dxlog_file12,
2926
+ L: 77,
2927
+ S: this,
2928
+ C: (f, a) => f(...a)
2929
+ });
2784
2930
  this.errors.raise(new UnknownProtocolError2("unknown RTCError", err));
2785
2931
  }
2786
2932
  } else if ("code" in err) {
2787
2933
  log11.info("simple-peer error", err, {
2788
2934
  F: __dxlog_file12,
2789
- L: 78,
2935
+ L: 82,
2790
2936
  S: this,
2791
2937
  C: (f, a) => f(...a)
2792
2938
  });
@@ -2794,10 +2940,12 @@ var SimplePeerTransport = class {
2794
2940
  case "ERR_WEBRTC_SUPPORT":
2795
2941
  this.errors.raise(new ProtocolError2("WebRTC not supported", err));
2796
2942
  break;
2943
+ case "ERR_SIGNALING":
2944
+ this.errors.raise(new ConnectivityError2("signaling failure", err));
2945
+ break;
2797
2946
  case "ERR_ICE_CONNECTION_FAILURE":
2798
2947
  case "ERR_DATA_CHANNEL":
2799
2948
  case "ERR_CONNECTION_FAILURE":
2800
- case "ERR_SIGNALING":
2801
2949
  this.errors.raise(new ConnectivityError2("unknown communication failure", err));
2802
2950
  break;
2803
2951
  case "ERR_CREATE_OFFER":
@@ -2814,7 +2962,7 @@ var SimplePeerTransport = class {
2814
2962
  } else {
2815
2963
  log11.info("unknown peer connection error", err, {
2816
2964
  F: __dxlog_file12,
2817
- L: 102,
2965
+ L: 108,
2818
2966
  S: this,
2819
2967
  C: (f, a) => f(...a)
2820
2968
  });
@@ -2825,10 +2973,10 @@ var SimplePeerTransport = class {
2825
2973
  this._peer._pc.getStats().then((stats) => {
2826
2974
  log11.info("report after webrtc error", {
2827
2975
  config: this.params.webrtcConfig,
2828
- stats
2976
+ stats: Object.fromEntries(stats.entries())
2829
2977
  }, {
2830
2978
  F: __dxlog_file12,
2831
- L: 110,
2979
+ L: 116,
2832
2980
  S: this,
2833
2981
  C: (f, a) => f(...a)
2834
2982
  });
@@ -2837,7 +2985,7 @@ var SimplePeerTransport = class {
2837
2985
  } catch (err2) {
2838
2986
  log11.catch(err2, void 0, {
2839
2987
  F: __dxlog_file12,
2840
- L: 117,
2988
+ L: 123,
2841
2989
  S: this,
2842
2990
  C: (f, a) => f(...a)
2843
2991
  });
@@ -2848,28 +2996,81 @@ var SimplePeerTransport = class {
2848
2996
  id: this._instanceId
2849
2997
  }), {
2850
2998
  F: __dxlog_file12,
2851
- L: 122,
2999
+ L: 129,
2852
3000
  S: this,
2853
3001
  C: (f, a) => f(...a)
2854
3002
  });
2855
3003
  }
3004
+ async getStats() {
3005
+ const stats = await this._getStats();
3006
+ if (!stats) {
3007
+ return {
3008
+ bytesSent: 0,
3009
+ bytesReceived: 0,
3010
+ packetsSent: 0,
3011
+ packetsReceived: 0,
3012
+ rawStats: {}
3013
+ };
3014
+ }
3015
+ return {
3016
+ bytesSent: stats.transport.bytesSent,
3017
+ bytesReceived: stats.transport.bytesReceived,
3018
+ packetsSent: stats.transport.packetsSent,
3019
+ packetsReceived: stats.transport.packetsReceived,
3020
+ rawStats: stats.raw
3021
+ };
3022
+ }
3023
+ async _getStats() {
3024
+ if (typeof this._peer?._pc?.getStats !== "function") {
3025
+ return null;
3026
+ }
3027
+ return await this._peer._pc.getStats().then((stats) => {
3028
+ const statsEntries = Array.from(stats.entries());
3029
+ const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
3030
+ const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
3031
+ let selectedCandidatePair;
3032
+ let remoteCandidate;
3033
+ if (candidatePair.length > 0) {
3034
+ selectedCandidatePair = candidatePair[0][1];
3035
+ remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
3036
+ }
3037
+ return {
3038
+ datachannel: statsEntries.filter((s) => s[1].type === "data-channel")[0][1],
3039
+ transport,
3040
+ selectedCandidatePair,
3041
+ remoteCandidate,
3042
+ raw: Object.fromEntries(stats.entries())
3043
+ };
3044
+ });
3045
+ }
3046
+ async getDetails() {
3047
+ const stats = await this._getStats();
3048
+ const rc = stats?.remoteCandidate;
3049
+ if (!rc) {
3050
+ return "unavailable";
3051
+ }
3052
+ if (rc.candidateType === "relay") {
3053
+ return `${rc.ip}:${rc.port}/${rc.protocol} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3054
+ }
3055
+ return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
3056
+ }
2856
3057
  async destroy() {
2857
3058
  log11("closing...", void 0, {
2858
3059
  F: __dxlog_file12,
2859
- L: 126,
3060
+ L: 192,
2860
3061
  S: this,
2861
3062
  C: (f, a) => f(...a)
2862
3063
  });
2863
3064
  if (this._closed) {
2864
3065
  return;
2865
3066
  }
2866
- this._closed = true;
2867
3067
  this._disconnectStreams();
2868
3068
  this._peer.destroy();
3069
+ this._closed = true;
2869
3070
  this.closed.emit();
2870
3071
  log11("closed", void 0, {
2871
3072
  F: __dxlog_file12,
2872
- L: 134,
3073
+ L: 200,
2873
3074
  S: this,
2874
3075
  C: (f, a) => f(...a)
2875
3076
  });
@@ -2984,7 +3185,7 @@ var SimplePeerTransportService = class {
2984
3185
  async sendSignal({ proxyId, signal }) {
2985
3186
  invariant12(this.transports.has(proxyId), void 0, {
2986
3187
  F: __dxlog_file13,
2987
- L: 112,
3188
+ L: 116,
2988
3189
  S: this,
2989
3190
  A: [
2990
3191
  "this.transports.has(proxyId)",
@@ -2993,18 +3194,46 @@ var SimplePeerTransportService = class {
2993
3194
  });
2994
3195
  await this.transports.get(proxyId).transport.signal(signal);
2995
3196
  }
3197
+ async getDetails({ proxyId }) {
3198
+ invariant12(this.transports.has(proxyId), void 0, {
3199
+ F: __dxlog_file13,
3200
+ L: 121,
3201
+ S: this,
3202
+ A: [
3203
+ "this.transports.has(proxyId)",
3204
+ ""
3205
+ ]
3206
+ });
3207
+ return {
3208
+ details: await this.transports.get(proxyId).transport.getDetails()
3209
+ };
3210
+ }
3211
+ async getStats({ proxyId }) {
3212
+ invariant12(this.transports.has(proxyId), void 0, {
3213
+ F: __dxlog_file13,
3214
+ L: 126,
3215
+ S: this,
3216
+ A: [
3217
+ "this.transports.has(proxyId)",
3218
+ ""
3219
+ ]
3220
+ });
3221
+ return {
3222
+ stats: await this.transports.get(proxyId).transport.getStats()
3223
+ };
3224
+ }
2996
3225
  async sendData({ proxyId, payload }) {
2997
3226
  if (this.transports.get(proxyId)?.state !== "OPEN") {
2998
3227
  log12.debug("transport is closed", void 0, {
2999
3228
  F: __dxlog_file13,
3000
- L: 118,
3229
+ L: 132,
3001
3230
  S: this,
3002
3231
  C: (f, a) => f(...a)
3003
3232
  });
3004
3233
  }
3005
3234
  invariant12(this.transports.has(proxyId), void 0, {
3006
3235
  F: __dxlog_file13,
3007
- L: 120,
3236
+ L: 134,
3008
3237
  S: this,
3009
3238
  A: [
3010
3239
  "this.transports.has(proxyId)",
@@ -3027,7 +3256,7 @@ var SimplePeerTransportService = class {
3027
3256
  }
3028
3257
  log12("Closed.", void 0, {
3029
3258
  F: __dxlog_file13,
3030
- L: 136,
3259
+ L: 150,
3031
3260
  S: this,
3032
3261
  C: (f, a) => f(...a)
3033
3262
  });
@@ -3042,7 +3271,7 @@ import { ErrorStream as ErrorStream5 } from "@dxos/debug";
3042
3271
  import { invariant as invariant13 } from "@dxos/invariant";
3043
3272
  import { PublicKey as PublicKey12 } from "@dxos/keys";
3044
3273
  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";
3274
+ import { ConnectionResetError as ConnectionResetError3, TimeoutError as TimeoutError3, ProtocolError as ProtocolError3, ConnectivityError as ConnectivityError3, UnknownProtocolError as UnknownProtocolError3 } from "@dxos/protocols";
3046
3275
  import { ConnectionState as ConnectionState4 } from "@dxos/protocols/proto/dxos/mesh/bridge";
3047
3276
  import { arrayToBuffer } from "@dxos/util";
3048
3277
  var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-proxy.ts";
@@ -3098,9 +3327,9 @@ var SimplePeerTransportProxy = class {
3098
3327
  }
3099
3328
  this._timeoutCount = 0;
3100
3329
  }, (err) => {
3101
- if (err instanceof TimeoutError2 || err.constructor.name === "TimeoutError") {
3330
+ if (err instanceof TimeoutError3 || err.constructor.name === "TimeoutError") {
3102
3331
  if (this._timeoutCount++ > TIMEOUT_THRESHOLD) {
3103
- throw new TimeoutError2(`too many timeoutes (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
3332
+ throw new TimeoutError3(`too many timeoutes (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
3104
3333
  } else {
3105
3334
  log13("timeout error, but still invoking callback", void 0, {
3106
3335
  F: __dxlog_file14,
@@ -3166,6 +3395,16 @@ var SimplePeerTransportProxy = class {
3166
3395
  signal
3167
3396
  }).catch((err) => this.errors.raise(decodeError(err)));
3168
3397
  }
3398
+ async getDetails() {
3399
+ return (await this._params.bridgeService.getDetails({
3400
+ proxyId: this._proxyId
3401
+ })).details;
3402
+ }
3403
+ async getStats() {
3404
+ return (await this._params.bridgeService.getStats({
3405
+ proxyId: this._proxyId
3406
+ })).stats;
3407
+ }
3169
3408
  // TODO(burdon): Move open from constructor.
3170
3409
  async destroy() {
3171
3410
  await this._ctx.dispose();
@@ -3180,7 +3419,7 @@ var SimplePeerTransportProxy = class {
3180
3419
  } catch (err) {
3181
3420
  log13.catch(err, void 0, {
3182
3421
  F: __dxlog_file14,
3183
- L: 160,
3422
+ L: 168,
3184
3423
  S: this,
3185
3424
  C: (f, a) => f(...a)
3186
3425
  });
@@ -3216,7 +3455,7 @@ var SimplePeerTransportProxyFactory = class {
3216
3455
  createTransport(options) {
3217
3456
  invariant13(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
3218
3457
  F: __dxlog_file14,
3219
- L: 197,
3458
+ L: 205,
3220
3459
  S: this,
3221
3460
  A: [
3222
3461
  "this._bridgeService",
@@ -3237,7 +3476,7 @@ var decodeError = (err) => {
3237
3476
  if (message.includes("CONNECTION_RESET")) {
3238
3477
  return new ConnectionResetError3(message);
3239
3478
  } else if (message.includes("TIMEOUT")) {
3240
- return new TimeoutError2(message);
3479
+ return new TimeoutError3(message);
3241
3480
  } else if (message.includes("PROTOCOL_ERROR")) {
3242
3481
  return new ProtocolError3(message);
3243
3482
  } else if (message.includes("CONNECTIVITY_ERROR")) {
@@ -3279,17 +3518,24 @@ var LibDataChannelTransport = class {
3279
3518
  this._readyForCandidates = new Trigger2();
3280
3519
  this._writeCallback = null;
3281
3520
  this._peer = (async () => {
3282
- const { RTCPeerConnection: PeerConnection } = await import("./index.browser-O53CPVK3.mjs");
3521
+ const { RTCPeerConnection } = (await importESM("node-datachannel/polyfill")).default;
3283
3522
  if (this._closed) {
3284
3523
  this.errors.raise(new Error("connection already closed"));
3285
3524
  }
3286
- const peer = new PeerConnection(params.webrtcConfig);
3525
+ if (params.webrtcConfig) {
3526
+ params.webrtcConfig.iceServers = params.webrtcConfig.iceServers ?? [];
3527
+ } else {
3528
+ params.webrtcConfig = {
3529
+ iceServers: []
3530
+ };
3531
+ }
3532
+ const peer = new RTCPeerConnection(params.webrtcConfig);
3287
3533
  peer.onicecandidateerror = (event) => {
3288
3534
  log14.error("peer.onicecandidateerror", {
3289
3535
  event
3290
3536
  }, {
3291
3537
  F: __dxlog_file15,
3292
- L: 53,
3538
+ L: 61,
3293
3539
  S: this,
3294
3540
  C: (f, a) => f(...a)
3295
3541
  });
@@ -3301,7 +3547,7 @@ var LibDataChannelTransport = class {
3301
3547
  transportConnectionState: this._connected
3302
3548
  }, {
3303
3549
  F: __dxlog_file15,
3304
- L: 57,
3550
+ L: 65,
3305
3551
  S: this,
3306
3552
  C: (f, a) => f(...a)
3307
3553
  });
@@ -3311,7 +3557,7 @@ var LibDataChannelTransport = class {
3311
3557
  event
3312
3558
  }, {
3313
3559
  F: __dxlog_file15,
3314
- L: 66,
3560
+ L: 74,
3315
3561
  S: this,
3316
3562
  C: (f, a) => f(...a)
3317
3563
  });
@@ -3335,7 +3581,7 @@ var LibDataChannelTransport = class {
3335
3581
  err
3336
3582
  }, {
3337
3583
  F: __dxlog_file15,
3338
- L: 83,
3584
+ L: 91,
3339
3585
  S: this,
3340
3586
  C: (f, a) => f(...a)
3341
3587
  });
@@ -3344,12 +3590,15 @@ var LibDataChannelTransport = class {
3344
3590
  };
3345
3591
  if (params.initiator) {
3346
3592
  peer.createOffer().then(async (offer) => {
3593
+ if (this._closed) {
3594
+ return;
3595
+ }
3347
3596
  if (peer.connectionState !== "connecting") {
3348
3597
  log14.error("i am initiator but peer not in state connecting", {
3349
3598
  peer
3350
3599
  }, {
3351
3600
  F: __dxlog_file15,
3352
- L: 92,
3601
+ L: 104,
3353
3602
  S: this,
3354
3603
  C: (f, a) => f(...a)
3355
3604
  });
@@ -3359,7 +3608,7 @@ var LibDataChannelTransport = class {
3359
3608
  offer
3360
3609
  }, {
3361
3610
  F: __dxlog_file15,
3362
- L: 95,
3611
+ L: 107,
3363
3612
  S: this,
3364
3613
  C: (f, a) => f(...a)
3365
3614
  });
@@ -3379,7 +3628,7 @@ var LibDataChannelTransport = class {
3379
3628
  this.handleChannel(peer.createDataChannel(DATACHANNEL_LABEL));
3380
3629
  log14.debug("created data channel", void 0, {
3381
3630
  F: __dxlog_file15,
3382
- L: 104,
3631
+ L: 116,
3383
3632
  S: this,
3384
3633
  C: (f, a) => f(...a)
3385
3634
  });
@@ -3392,7 +3641,7 @@ var LibDataChannelTransport = class {
3392
3641
  event
3393
3642
  }, {
3394
3643
  F: __dxlog_file15,
3395
- L: 110,
3644
+ L: 122,
3396
3645
  S: this,
3397
3646
  C: (f, a) => f(...a)
3398
3647
  });
@@ -3410,23 +3659,28 @@ var LibDataChannelTransport = class {
3410
3659
  this._channel.onopen = () => {
3411
3660
  log14.debug("dataChannel.onopen", void 0, {
3412
3661
  F: __dxlog_file15,
3413
- L: 126,
3662
+ L: 138,
3414
3663
  S: this,
3415
3664
  C: (f, a) => f(...a)
3416
3665
  });
3417
3666
  const duplex = new Duplex2({
3418
3667
  read: () => {
3419
3668
  },
3420
- write: (chunk, encoding, callback) => {
3669
+ write: async (chunk, encoding, callback) => {
3421
3670
  if (chunk.length > MAX_MESSAGE_SIZE) {
3422
3671
  this.errors.raise(new Error(`message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}`));
3423
3672
  }
3424
- dataChannel.send(chunk);
3673
+ try {
3674
+ dataChannel.send(chunk);
3675
+ } catch (err) {
3676
+ this.errors.raise(err);
3677
+ await this._close();
3678
+ }
3425
3679
  if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
3426
3680
  if (this._writeCallback !== null) {
3427
3681
  log14.error("consumer trying to write before we're ready for more data", void 0, {
3428
3682
  F: __dxlog_file15,
3429
- L: 139,
3683
+ L: 155,
3430
3684
  S: this,
3431
3685
  C: (f, a) => f(...a)
3432
3686
  });
@@ -3451,7 +3705,7 @@ var LibDataChannelTransport = class {
3451
3705
  err
3452
3706
  }, {
3453
3707
  F: __dxlog_file15,
3454
- L: 159,
3708
+ L: 175,
3455
3709
  S: this,
3456
3710
  C: (f, a) => f(...a)
3457
3711
  });
@@ -3460,7 +3714,7 @@ var LibDataChannelTransport = class {
3460
3714
  this._channel.onmessage = (event) => {
3461
3715
  let data = event.data;
3462
3716
  if (data instanceof ArrayBuffer) {
3463
- data = Buffer.from(data);
3717
+ data = Buffer2.from(data);
3464
3718
  }
3465
3719
  this._stream.push(data);
3466
3720
  };
@@ -3475,6 +3729,12 @@ var LibDataChannelTransport = class {
3475
3729
  return;
3476
3730
  }
3477
3731
  await this._disconnectStreams();
3732
+ const peer = await this._peer;
3733
+ try {
3734
+ peer.close();
3735
+ } catch (err) {
3736
+ this.errors.raise(err);
3737
+ }
3478
3738
  this._closed = true;
3479
3739
  this.closed.emit();
3480
3740
  }
@@ -3488,7 +3748,7 @@ var LibDataChannelTransport = class {
3488
3748
  peer
3489
3749
  }, {
3490
3750
  F: __dxlog_file15,
3491
- L: 194,
3751
+ L: 216,
3492
3752
  S: this,
3493
3753
  C: (f, a) => f(...a)
3494
3754
  });
@@ -3516,7 +3776,7 @@ var LibDataChannelTransport = class {
3516
3776
  err
3517
3777
  }, {
3518
3778
  F: __dxlog_file15,
3519
- L: 205,
3779
+ L: 227,
3520
3780
  S: this,
3521
3781
  C: (f, a) => f(...a)
3522
3782
  });
@@ -3536,7 +3796,7 @@ var LibDataChannelTransport = class {
3536
3796
  err
3537
3797
  }, {
3538
3798
  F: __dxlog_file15,
3539
- L: 216,
3799
+ L: 238,
3540
3800
  S: this,
3541
3801
  C: (f, a) => f(...a)
3542
3802
  });
@@ -3555,7 +3815,7 @@ var LibDataChannelTransport = class {
3555
3815
  signal
3556
3816
  }, {
3557
3817
  F: __dxlog_file15,
3558
- L: 227,
3818
+ L: 249,
3559
3819
  S: this,
3560
3820
  C: (f, a) => f(...a)
3561
3821
  });
@@ -3564,12 +3824,62 @@ var LibDataChannelTransport = class {
3564
3824
  }).catch((err) => {
3565
3825
  log14.catch(err, void 0, {
3566
3826
  F: __dxlog_file15,
3567
- L: 232,
3827
+ L: 254,
3568
3828
  S: this,
3569
3829
  C: (f, a) => f(...a)
3570
3830
  });
3571
3831
  });
3572
3832
  }
3833
+ async getDetails() {
3834
+ const stats = await this._getStats();
3835
+ const rc = stats?.remoteCandidate;
3836
+ if (!rc) {
3837
+ return "unavailable";
3838
+ }
3839
+ if (rc.candidateType === "relay") {
3840
+ return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3841
+ }
3842
+ return `${rc.ip}:${rc.port} ${rc.candidateType}`;
3843
+ }
3844
+ async _getStats() {
3845
+ return this._peer.then(async (peer) => {
3846
+ const stats = await peer.getStats();
3847
+ const statsEntries = Array.from(stats.entries());
3848
+ const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
3849
+ const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
3850
+ let selectedCandidatePair;
3851
+ let remoteCandidate;
3852
+ if (candidatePair.length > 0) {
3853
+ selectedCandidatePair = candidatePair[0][1];
3854
+ remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
3855
+ }
3856
+ return {
3857
+ transport,
3858
+ selectedCandidatePair,
3859
+ remoteCandidate,
3860
+ raw: Object.fromEntries(stats)
3861
+ };
3862
+ });
3863
+ }
3864
+ async getStats() {
3865
+ const stats = await this._getStats();
3866
+ if (!stats) {
3867
+ return {
3868
+ bytesSent: 0,
3869
+ bytesReceived: 0,
3870
+ packetsSent: 0,
3871
+ packetsReceived: 0,
3872
+ rawStats: {}
3873
+ };
3874
+ }
3875
+ return {
3876
+ bytesSent: stats.transport.bytesSent,
3877
+ bytesReceived: stats.transport.bytesReceived,
3878
+ packetsSent: 0,
3879
+ packetsReceived: 0,
3880
+ rawStats: stats.raw
3881
+ };
3882
+ }
3573
3883
  // TODO(nf): add classmethod to call node-datachannel.cleanup() when all instances have been destroyed?
3574
3884
  async destroy() {
3575
3885
  await this._close();
@@ -3587,6 +3897,7 @@ var createLibDataChannelTransportFactory = (webrtcConfig) => ({
3587
3897
  webrtcConfig
3588
3898
  })
3589
3899
  });
3900
+ var importESM = Function("path", "return import(path)");
3590
3901
 
3591
3902
  // packages/core/mesh/network-manager/src/transport/tcp-transport.browser.ts
3592
3903
  import { Event as Event11 } from "@dxos/async";
@@ -3606,6 +3917,12 @@ var TcpTransport = class {
3606
3917
  signal() {
3607
3918
  throw new Error("Method not implemented.");
3608
3919
  }
3920
+ async getStats() {
3921
+ throw new Error("Method not implemented.");
3922
+ }
3923
+ async getDetails() {
3924
+ throw new Error("Method not implemented.");
3925
+ }
3609
3926
  };
3610
3927
 
3611
3928
  // packages/core/mesh/network-manager/src/wire-protocol.ts
@@ -3615,8 +3932,8 @@ var createTeleportProtocolFactory = (onConnection) => {
3615
3932
  const teleport = new Teleport(params);
3616
3933
  return {
3617
3934
  stream: teleport.stream,
3618
- open: async () => {
3619
- await teleport.open();
3935
+ open: async (sessionId) => {
3936
+ await teleport.open(sessionId);
3620
3937
  await onConnection(teleport);
3621
3938
  },
3622
3939
  close: async () => {
@@ -3630,6 +3947,7 @@ var createTeleportProtocolFactory = (onConnection) => {
3630
3947
  };
3631
3948
 
3632
3949
  export {
3950
+ process,
3633
3951
  ConnectionState,
3634
3952
  Connection,
3635
3953
  SwarmMessenger,
@@ -3657,4 +3975,4 @@ export {
3657
3975
  TcpTransport,
3658
3976
  createTeleportProtocolFactory
3659
3977
  };
3660
- //# sourceMappingURL=chunk-LA2ACGLR.mjs.map
3978
+ //# sourceMappingURL=chunk-XF474R3E.mjs.map