@dxos/network-manager 0.6.12 → 0.6.13-main.548ca8d

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 (157) hide show
  1. package/dist/lib/browser/chunk-GW3YM55A.mjs +14 -0
  2. package/dist/lib/browser/chunk-GW3YM55A.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-XYSYUN63.mjs → chunk-IDPSMH73.mjs} +1230 -1031
  4. package/dist/lib/browser/chunk-IDPSMH73.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +10 -19
  6. package/dist/lib/browser/meta.json +1 -1
  7. package/dist/lib/browser/testing/index.mjs +18 -27
  8. package/dist/lib/browser/testing/index.mjs.map +3 -3
  9. package/dist/lib/browser/transport/tcp/index.mjs +39 -0
  10. package/dist/lib/browser/transport/tcp/index.mjs.map +7 -0
  11. package/dist/lib/node/{chunk-4YAYC7WN.cjs → chunk-MCPADZS5.cjs} +1246 -1174
  12. package/dist/lib/node/chunk-MCPADZS5.cjs.map +7 -0
  13. package/dist/lib/node/index.cjs +27 -37
  14. package/dist/lib/node/index.cjs.map +2 -2
  15. package/dist/lib/node/meta.json +1 -1
  16. package/dist/lib/node/testing/index.cjs +20 -29
  17. package/dist/lib/node/testing/index.cjs.map +3 -3
  18. package/dist/lib/node/transport/tcp/index.cjs +191 -0
  19. package/dist/lib/node/transport/tcp/index.cjs.map +7 -0
  20. package/dist/lib/node-esm/chunk-NL5MMIE4.mjs +4388 -0
  21. package/dist/lib/node-esm/chunk-NL5MMIE4.mjs.map +7 -0
  22. package/dist/lib/node-esm/index.mjs +50 -0
  23. package/dist/lib/node-esm/index.mjs.map +7 -0
  24. package/dist/lib/node-esm/meta.json +1 -0
  25. package/dist/lib/node-esm/testing/index.mjs +280 -0
  26. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  27. package/dist/lib/node-esm/transport/tcp/index.mjs +159 -0
  28. package/dist/lib/node-esm/transport/tcp/index.mjs.map +7 -0
  29. package/dist/types/src/signal/ice.d.ts.map +1 -1
  30. package/dist/types/src/signal/integration.node.test.d.ts +2 -0
  31. package/dist/types/src/signal/integration.node.test.d.ts.map +1 -0
  32. package/dist/types/src/signal/swarm-messenger.node.test.d.ts +2 -0
  33. package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +1 -0
  34. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  35. package/dist/types/src/swarm/swarm.d.ts +1 -1
  36. package/dist/types/src/testing/test-builder.d.ts +2 -2
  37. package/dist/types/src/testing/test-builder.d.ts.map +1 -1
  38. package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
  39. package/dist/types/src/tests/property-test-suite.d.ts.map +1 -1
  40. package/dist/types/src/tests/tcp-transport.node.test.d.ts +2 -0
  41. package/dist/types/src/tests/tcp-transport.node.test.d.ts.map +1 -0
  42. package/dist/types/src/tests/utils.d.ts.map +1 -1
  43. package/dist/types/src/transport/index.d.ts +1 -5
  44. package/dist/types/src/transport/index.d.ts.map +1 -1
  45. package/dist/types/src/transport/memory-transport.d.ts +2 -2
  46. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  47. package/dist/types/src/transport/tcp/index.d.ts +2 -0
  48. package/dist/types/src/transport/tcp/index.d.ts.map +1 -0
  49. package/dist/types/src/transport/{tcp-transport.browser.d.ts → tcp/tcp-transport.browser.d.ts} +3 -3
  50. package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +1 -0
  51. package/dist/types/src/transport/{tcp-transport.d.ts → tcp/tcp-transport.d.ts} +3 -3
  52. package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +1 -0
  53. package/dist/types/src/transport/transport.d.ts +7 -6
  54. package/dist/types/src/transport/transport.d.ts.map +1 -1
  55. package/dist/types/src/transport/webrtc/index.d.ts +4 -0
  56. package/dist/types/src/transport/webrtc/index.d.ts.map +1 -0
  57. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +14 -0
  58. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +1 -0
  59. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +68 -0
  60. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +1 -0
  61. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +33 -0
  62. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +1 -0
  63. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +2 -0
  64. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +1 -0
  65. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +4 -0
  66. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +1 -0
  67. package/dist/types/src/transport/{simplepeer-transport-proxy.d.ts → webrtc/rtc-transport-proxy.d.ts} +10 -12
  68. package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +1 -0
  69. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +2 -0
  70. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +1 -0
  71. package/dist/types/src/transport/{simplepeer-transport-service.d.ts → webrtc/rtc-transport-service.d.ts} +9 -7
  72. package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +1 -0
  73. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +4 -0
  74. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +1 -0
  75. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +2 -0
  76. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +1 -0
  77. package/dist/types/src/transport/webrtc/test-utils.d.ts +5 -0
  78. package/dist/types/src/transport/webrtc/test-utils.d.ts.map +1 -0
  79. package/dist/types/src/transport/webrtc/utils.d.ts +3 -0
  80. package/dist/types/src/transport/webrtc/utils.d.ts.map +1 -0
  81. package/package.json +53 -30
  82. package/src/signal/ice.test.ts +1 -3
  83. package/src/signal/ice.ts +6 -1
  84. package/src/signal/{integration.test.ts → integration.node.test.ts} +9 -15
  85. package/src/signal/{swarm-messenger.test.ts → swarm-messenger.node.test.ts} +13 -23
  86. package/src/swarm/connection-limiter.test.ts +3 -6
  87. package/src/swarm/connection.test.ts +63 -38
  88. package/src/swarm/connection.ts +5 -5
  89. package/src/swarm/swarm.test.ts +9 -11
  90. package/src/swarm/swarm.ts +1 -1
  91. package/src/testing/test-builder.ts +12 -28
  92. package/src/tests/basic-test-suite.ts +34 -33
  93. package/src/tests/memory-transport.test.ts +40 -42
  94. package/src/tests/property-test-suite.ts +21 -22
  95. package/src/tests/tcp-transport.node.test.ts +65 -0
  96. package/src/tests/utils.ts +3 -2
  97. package/src/tests/webrtc-transport.test.ts +9 -9
  98. package/src/transport/index.ts +1 -5
  99. package/src/transport/memory-transport.ts +2 -0
  100. package/src/transport/tcp/index.ts +5 -0
  101. package/src/transport/{tcp-transport.browser.ts → tcp/tcp-transport.browser.ts} +7 -3
  102. package/src/transport/{tcp-transport.ts → tcp/tcp-transport.ts} +3 -1
  103. package/src/transport/transport.ts +8 -7
  104. package/src/transport/webrtc/index.ts +7 -0
  105. package/src/transport/webrtc/rtc-connection-factory.ts +82 -0
  106. package/src/transport/webrtc/rtc-peer-connection.ts +472 -0
  107. package/src/transport/webrtc/rtc-transport-channel.test.ts +176 -0
  108. package/src/transport/webrtc/rtc-transport-channel.ts +195 -0
  109. package/src/transport/webrtc/rtc-transport-factory.ts +28 -0
  110. package/src/transport/webrtc/rtc-transport-proxy.test.ts +413 -0
  111. package/src/transport/webrtc/rtc-transport-proxy.ts +264 -0
  112. package/src/transport/webrtc/rtc-transport-service.ts +192 -0
  113. package/src/transport/webrtc/rtc-transport-stats.ts +67 -0
  114. package/src/transport/webrtc/rtc-transport.test.ts +198 -0
  115. package/src/transport/webrtc/test-utils.ts +22 -0
  116. package/src/transport/webrtc/utils.ts +36 -0
  117. package/src/typings.d.ts +8 -2
  118. package/dist/lib/browser/chunk-XYSYUN63.mjs.map +0 -7
  119. package/dist/lib/node/chunk-4YAYC7WN.cjs.map +0 -7
  120. package/dist/types/src/signal/integration.test.d.ts +0 -2
  121. package/dist/types/src/signal/integration.test.d.ts.map +0 -1
  122. package/dist/types/src/signal/swarm-messenger.test.d.ts +0 -2
  123. package/dist/types/src/signal/swarm-messenger.test.d.ts.map +0 -1
  124. package/dist/types/src/tests/tcp-transport.test.d.ts +0 -2
  125. package/dist/types/src/tests/tcp-transport.test.d.ts.map +0 -1
  126. package/dist/types/src/transport/libdatachannel-transport.d.ts +0 -42
  127. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +0 -1
  128. package/dist/types/src/transport/libdatachannel-transport.test.d.ts +0 -2
  129. package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +0 -1
  130. package/dist/types/src/transport/memory-transport.test.d.ts +0 -2
  131. package/dist/types/src/transport/memory-transport.test.d.ts.map +0 -1
  132. package/dist/types/src/transport/simplepeer-simple-peer.d.ts +0 -2
  133. package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +0 -1
  134. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +0 -2
  135. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +0 -1
  136. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +0 -1
  137. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +0 -1
  138. package/dist/types/src/transport/simplepeer-transport.d.ts +0 -36
  139. package/dist/types/src/transport/simplepeer-transport.d.ts.map +0 -1
  140. package/dist/types/src/transport/simplepeer-transport.test.d.ts +0 -2
  141. package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +0 -1
  142. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +0 -1
  143. package/dist/types/src/transport/tcp-transport.d.ts.map +0 -1
  144. package/dist/types/src/transport/webrtc.d.ts +0 -6
  145. package/dist/types/src/transport/webrtc.d.ts.map +0 -1
  146. package/src/globals.d.ts +0 -7
  147. package/src/tests/tcp-transport.test.ts +0 -67
  148. package/src/transport/libdatachannel-transport.test.ts +0 -100
  149. package/src/transport/libdatachannel-transport.ts +0 -376
  150. package/src/transport/memory-transport.test.ts +0 -74
  151. package/src/transport/simplepeer-simple-peer.ts +0 -26
  152. package/src/transport/simplepeer-transport-proxy-test.ts +0 -181
  153. package/src/transport/simplepeer-transport-proxy.ts +0 -246
  154. package/src/transport/simplepeer-transport-service.ts +0 -160
  155. package/src/transport/simplepeer-transport.test.ts +0 -61
  156. package/src/transport/simplepeer-transport.ts +0 -250
  157. package/src/transport/webrtc.ts +0 -15
@@ -26,37 +26,32 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var chunk_4YAYC7WN_exports = {};
30
- __export(chunk_4YAYC7WN_exports, {
29
+ var chunk_MCPADZS5_exports = {};
30
+ __export(chunk_MCPADZS5_exports, {
31
31
  Connection: () => Connection,
32
32
  ConnectionLimiter: () => ConnectionLimiter,
33
33
  ConnectionLog: () => ConnectionLog,
34
34
  ConnectionState: () => ConnectionState,
35
35
  EventType: () => EventType,
36
36
  FullyConnectedTopology: () => FullyConnectedTopology,
37
- LibDataChannelTransport: () => LibDataChannelTransport,
38
37
  MAX_CONCURRENT_INITIATING_CONNECTIONS: () => MAX_CONCURRENT_INITIATING_CONNECTIONS,
39
38
  MMSTTopology: () => MMSTTopology,
40
39
  MemoryTransport: () => MemoryTransport,
41
40
  MemoryTransportFactory: () => MemoryTransportFactory,
42
- SimplePeerTransport: () => SimplePeerTransport,
43
- SimplePeerTransportProxy: () => SimplePeerTransportProxy,
44
- SimplePeerTransportProxyFactory: () => SimplePeerTransportProxyFactory,
45
- SimplePeerTransportService: () => SimplePeerTransportService,
41
+ RtcTransportProxy: () => RtcTransportProxy,
42
+ RtcTransportProxyFactory: () => RtcTransportProxyFactory,
43
+ RtcTransportService: () => RtcTransportService,
46
44
  StarTopology: () => StarTopology,
47
45
  Swarm: () => Swarm,
48
46
  SwarmMapper: () => SwarmMapper,
49
47
  SwarmMessenger: () => SwarmMessenger,
50
48
  SwarmNetworkManager: () => SwarmNetworkManager,
51
- TcpTransport: () => TcpTransport,
52
- TcpTransportFactory: () => TcpTransportFactory,
53
49
  TransportKind: () => TransportKind,
54
50
  createIceProvider: () => createIceProvider,
55
- createLibDataChannelTransportFactory: () => createLibDataChannelTransportFactory,
56
- createSimplePeerTransportFactory: () => createSimplePeerTransportFactory,
51
+ createRtcTransportFactory: () => createRtcTransportFactory,
57
52
  createTeleportProtocolFactory: () => createTeleportProtocolFactory
58
53
  });
59
- module.exports = __toCommonJS(chunk_4YAYC7WN_exports);
54
+ module.exports = __toCommonJS(chunk_MCPADZS5_exports);
60
55
  var import_async = require("@dxos/async");
61
56
  var import_context = require("@dxos/context");
62
57
  var import_debug = require("@dxos/debug");
@@ -125,46 +120,37 @@ var import_invariant10 = require("@dxos/invariant");
125
120
  var import_keys9 = require("@dxos/keys");
126
121
  var import_log11 = require("@dxos/log");
127
122
  var import_util8 = require("@dxos/util");
128
- var import_simple_peer = __toESM(require("simple-peer"));
129
- var import_tiny_invariant = __toESM(require("tiny-invariant"));
130
123
  var import_async10 = require("@dxos/async");
131
- var import_debug5 = require("@dxos/debug");
132
- var import_keys10 = require("@dxos/keys");
124
+ var import_async11 = require("@dxos/async");
125
+ var import_invariant11 = require("@dxos/invariant");
133
126
  var import_log12 = require("@dxos/log");
134
127
  var import_protocols7 = require("@dxos/protocols");
128
+ var import_tracing = require("@dxos/tracing");
135
129
  var import_node_stream2 = require("node:stream");
136
- var import_codec_protobuf = require("@dxos/codec-protobuf");
137
- var import_invariant11 = require("@dxos/invariant");
138
- var import_keys11 = require("@dxos/keys");
130
+ var import_async12 = require("@dxos/async");
131
+ var import_context6 = require("@dxos/context");
132
+ var import_debug5 = require("@dxos/debug");
133
+ var import_invariant12 = require("@dxos/invariant");
139
134
  var import_log13 = require("@dxos/log");
140
- var import_bridge = require("@dxos/protocols/proto/dxos/mesh/bridge");
141
- var import_util9 = require("@dxos/util");
135
+ var import_protocols8 = require("@dxos/protocols");
142
136
  var import_node_stream3 = require("node:stream");
143
- var import_async11 = require("@dxos/async");
144
- var import_context6 = require("@dxos/context");
137
+ var import_async13 = require("@dxos/async");
138
+ var import_context7 = require("@dxos/context");
145
139
  var import_debug6 = require("@dxos/debug");
146
- var import_invariant12 = require("@dxos/invariant");
147
- var import_keys12 = require("@dxos/keys");
140
+ var import_invariant13 = require("@dxos/invariant");
141
+ var import_keys10 = require("@dxos/keys");
148
142
  var import_log14 = require("@dxos/log");
149
- var import_protocols8 = require("@dxos/protocols");
143
+ var import_protocols9 = require("@dxos/protocols");
144
+ var import_bridge = require("@dxos/protocols/proto/dxos/mesh/bridge");
145
+ var import_util9 = require("@dxos/util");
146
+ var import_node_stream4 = require("node:stream");
147
+ var import_codec_protobuf = require("@dxos/codec-protobuf");
148
+ var import_invariant14 = require("@dxos/invariant");
149
+ var import_keys11 = require("@dxos/keys");
150
+ var import_log15 = require("@dxos/log");
150
151
  var import_bridge2 = require("@dxos/protocols/proto/dxos/mesh/bridge");
151
152
  var import_util10 = require("@dxos/util");
152
- var import_stream = require("stream");
153
- var import_async12 = require("@dxos/async");
154
- var import_debug7 = require("@dxos/debug");
155
- var import_invariant13 = require("@dxos/invariant");
156
- var import_log15 = require("@dxos/log");
157
- var import_node_net = require("node:net");
158
- var import_async13 = require("@dxos/async");
159
- var import_debug8 = require("@dxos/debug");
160
- var import_log16 = require("@dxos/log");
161
153
  var import_teleport = require("@dxos/teleport");
162
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
163
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
164
- }) : x)(function(x) {
165
- if (typeof require !== "undefined") return require.apply(this, arguments);
166
- throw Error('Dynamic require of "' + x + '" is not supported');
167
- });
168
154
  function _ts_decorate(decorators, target, key, desc) {
169
155
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
170
156
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -200,11 +186,11 @@ var Connection = class {
200
186
  this._callbacks = _callbacks;
201
187
  this._ctx = new import_context.Context(void 0, {
202
188
  F: __dxlog_file,
203
- L: 101
189
+ L: 100
204
190
  });
205
191
  this.connectedTimeoutContext = new import_context.Context(void 0, {
206
192
  F: __dxlog_file,
207
- L: 102
193
+ L: 101
208
194
  });
209
195
  this._protocolClosed = new import_async.Trigger();
210
196
  this._transportClosed = new import_async.Trigger();
@@ -227,7 +213,7 @@ var Connection = class {
227
213
  initiator: this.initiator
228
214
  }, {
229
215
  F: __dxlog_file,
230
- L: 138,
216
+ L: 137,
231
217
  S: this,
232
218
  C: (f, a) => f(...a)
233
219
  });
@@ -250,7 +236,7 @@ var Connection = class {
250
236
  async openConnection() {
251
237
  (0, import_invariant.invariant)(this._state === "INITIAL", "Invalid state.", {
252
238
  F: __dxlog_file,
253
- L: 168,
239
+ L: 167,
254
240
  S: this,
255
241
  A: [
256
242
  "this._state === ConnectionState.INITIAL",
@@ -261,7 +247,7 @@ var Connection = class {
261
247
  id: this._instanceId
262
248
  }), {
263
249
  F: __dxlog_file,
264
- L: 169,
250
+ L: 168,
265
251
  S: this,
266
252
  C: (f, a) => f(...a)
267
253
  });
@@ -273,7 +259,7 @@ var Connection = class {
273
259
  initiator: this.initiator
274
260
  }, {
275
261
  F: __dxlog_file,
276
- L: 170,
262
+ L: 169,
277
263
  S: this,
278
264
  C: (f, a) => f(...a)
279
265
  });
@@ -284,7 +270,7 @@ var Connection = class {
284
270
  this._protocol.stream.on("close", () => {
285
271
  (0, import_log.log)("protocol stream closed", void 0, {
286
272
  F: __dxlog_file,
287
- L: 187,
273
+ L: 186,
288
274
  S: this,
289
275
  C: (f, a) => f(...a)
290
276
  });
@@ -294,7 +280,7 @@ var Connection = class {
294
280
  (0, import_async.scheduleTask)(this.connectedTimeoutContext, async () => {
295
281
  import_log.log.info(`timeout waiting ${TRANSPORT_CONNECTION_TIMEOUT / 1e3}s for transport to connect, aborting`, void 0, {
296
282
  F: __dxlog_file,
297
- L: 195,
283
+ L: 194,
298
284
  S: this,
299
285
  C: (f, a) => f(...a)
300
286
  });
@@ -302,7 +288,7 @@ var Connection = class {
302
288
  }, TRANSPORT_CONNECTION_TIMEOUT);
303
289
  (0, import_invariant.invariant)(!this._transport, void 0, {
304
290
  F: __dxlog_file,
305
- L: 203,
291
+ L: 202,
306
292
  S: this,
307
293
  A: [
308
294
  "!this._transport",
@@ -310,12 +296,14 @@ var Connection = class {
310
296
  ]
311
297
  });
312
298
  this._transport = this._transportFactory.createTransport({
299
+ ownPeerKey: this.localInfo.peerKey,
300
+ remotePeerKey: this.remoteInfo.peerKey,
301
+ topic: this.topic.toHex(),
313
302
  initiator: this.initiator,
314
303
  stream: this._protocol.stream,
315
304
  sendSignal: async (signal) => this._sendSignal(signal),
316
305
  sessionId: this.sessionId
317
306
  });
318
- await this._transport.open();
319
307
  this._transport.connected.once(async () => {
320
308
  this._changeState("CONNECTED");
321
309
  await this.connectedTimeoutContext.dispose();
@@ -361,21 +349,13 @@ var Connection = class {
361
349
  C: (f, a) => f(...a)
362
350
  });
363
351
  this.abort().catch((err2) => this.errors.raise(err2));
364
- } else if (err instanceof import_protocols.UnknownProtocolError) {
365
- import_log.log.warn("unsure what to do with UnknownProtocolError, will keep on truckin", {
366
- err
367
- }, {
368
- F: __dxlog_file,
369
- L: 242,
370
- S: this,
371
- C: (f, a) => f(...a)
372
- });
373
352
  }
374
353
  if (this._state !== "CLOSED" && this._state !== "CLOSING") {
375
354
  await this.connectedTimeoutContext.dispose();
376
355
  this.errors.raise(err);
377
356
  }
378
357
  });
358
+ await this._transport.open();
379
359
  for (const signal of this._incomingSignalBuffer) {
380
360
  void this._transport.onSignal(signal);
381
361
  }
@@ -737,15 +717,20 @@ var createIceProvider = (iceProviders) => {
737
717
  }
738
718
  cachedIceServers = (await Promise.all(iceProviders.map(({ urls }) => (0, import_async2.asyncTimeout)(fetch(urls, {
739
719
  method: "GET"
740
- }), 1e4).then((response) => response.json()).catch((err) => import_log2.log.error("Failed to fetch ICE servers from provider", {
741
- urls,
742
- err
743
- }, {
744
- F: __dxlog_file2,
745
- L: 27,
746
- S: void 0,
747
- C: (f, a) => f(...a)
748
- }))))).filter(import_util.isNotNullOrUndefined).map(({ iceServers }) => iceServers).flat();
720
+ }), 1e4).then((response) => response.json()).catch((err) => {
721
+ const isDev = typeof window !== "undefined" && window.location.href.includes("localhost");
722
+ if (!isDev) {
723
+ import_log2.log.error("Failed to fetch ICE servers from provider", {
724
+ urls,
725
+ err
726
+ }, {
727
+ F: __dxlog_file2,
728
+ L: 30,
729
+ S: void 0,
730
+ C: (f, a) => f(...a)
731
+ });
732
+ }
733
+ })))).filter(import_util.isNotNullOrUndefined).map(({ iceServers }) => iceServers).flat();
749
734
  return cachedIceServers;
750
735
  }
751
736
  };
@@ -2912,11 +2897,12 @@ var MemoryTransport = class _MemoryTransport {
2912
2897
  this.errors.raise(err);
2913
2898
  });
2914
2899
  }
2900
+ return this;
2915
2901
  }
2916
2902
  async close() {
2917
2903
  (0, import_log11.log)("closing...", void 0, {
2918
2904
  F: __dxlog_file12,
2919
- L: 129,
2905
+ L: 130,
2920
2906
  S: this,
2921
2907
  C: (f, a) => f(...a)
2922
2908
  });
@@ -2937,17 +2923,18 @@ var MemoryTransport = class _MemoryTransport {
2937
2923
  this.closed.emit();
2938
2924
  (0, import_log11.log)("closed", void 0, {
2939
2925
  F: __dxlog_file12,
2940
- L: 157,
2926
+ L: 158,
2941
2927
  S: this,
2942
2928
  C: (f, a) => f(...a)
2943
2929
  });
2930
+ return this;
2944
2931
  }
2945
2932
  async onSignal({ payload }) {
2946
2933
  (0, import_log11.log)("received signal", {
2947
2934
  payload
2948
2935
  }, {
2949
2936
  F: __dxlog_file12,
2950
- L: 161,
2937
+ L: 163,
2951
2938
  S: this,
2952
2939
  C: (f, a) => f(...a)
2953
2940
  });
@@ -2981,1278 +2968,1368 @@ _ts_decorate5([
2981
2968
  var toError = (err) => err instanceof Error ? err : new Error(String(err));
2982
2969
  var TransportKind;
2983
2970
  (function(TransportKind2) {
2984
- TransportKind2["SIMPLE_PEER"] = "SIMPLE_PEER";
2985
- TransportKind2["SIMPLE_PEER_PROXY"] = "SIMPLE_PEER_PROXY";
2986
- TransportKind2["LIBDATACHANNEL"] = "LIBDATACHANNEL";
2971
+ TransportKind2["WEB_RTC"] = "WEB-RTC";
2972
+ TransportKind2["WEB_RTC_PROXY"] = "WEB-RTC_PROXY";
2987
2973
  TransportKind2["MEMORY"] = "MEMORY";
2988
2974
  TransportKind2["TCP"] = "TCP";
2989
2975
  })(TransportKind || (TransportKind = {}));
2990
- var wrtc = null;
2991
- try {
2992
- wrtc = __require("@koush/wrtc");
2993
- } catch {
2994
- }
2995
- function _ts_decorate6(decorators, target, key, desc) {
2996
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2997
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2998
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2999
- return c > 3 && r && Object.defineProperty(target, key, r), r;
3000
- }
3001
- var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport.ts";
3002
- var createSimplePeerTransportFactory = (webrtcConfig, iceProvider) => ({
3003
- createTransport: (options) => new SimplePeerTransport({
3004
- ...options,
3005
- webrtcConfig,
3006
- iceProvider
3007
- })
3008
- });
3009
- var SimplePeerTransport = class {
3010
- get isOpen() {
3011
- return this._piped && !this._closed;
2976
+ var BrowserRtcConnectionFactory = class {
2977
+ async initialize() {
3012
2978
  }
3013
- /**
3014
- * @params opts.config formatted as per https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection
3015
- */
3016
- constructor(_params) {
3017
- this._params = _params;
3018
- this._peer = void 0;
3019
- this._closed = false;
3020
- this._piped = false;
3021
- this.closed = new import_async10.Event();
3022
- this.connected = new import_async10.Event();
3023
- this.errors = new import_debug5.ErrorStream();
3024
- this._instanceId = import_keys10.PublicKey.random().toHex();
2979
+ async onConnectionDestroyed() {
3025
2980
  }
3026
- async getStats() {
3027
- const stats = await this._getStats();
3028
- if (!stats) {
3029
- return {
3030
- bytesSent: 0,
3031
- bytesReceived: 0,
3032
- packetsSent: 0,
3033
- packetsReceived: 0,
3034
- rawStats: {}
3035
- };
3036
- }
3037
- return {
3038
- bytesSent: stats.transport.bytesSent,
3039
- bytesReceived: stats.transport.bytesReceived,
3040
- packetsSent: stats.transport.packetsSent,
3041
- packetsReceived: stats.transport.packetsReceived,
3042
- rawStats: stats.raw
3043
- };
2981
+ async createConnection(config) {
2982
+ return new RTCPeerConnection(config);
3044
2983
  }
3045
- async _getStats() {
3046
- if (typeof this._peer?._pc?.getStats !== "function") {
3047
- return null;
3048
- }
3049
- return await this._peer._pc.getStats().then((stats) => {
3050
- const statsEntries = Array.from(stats.entries());
3051
- const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
3052
- const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
3053
- let selectedCandidatePair;
3054
- let remoteCandidate;
3055
- if (candidatePair.length > 0) {
3056
- selectedCandidatePair = candidatePair[0][1];
3057
- remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
2984
+ async initConnection(connection, info) {
2985
+ }
2986
+ };
2987
+ var NodeRtcConnectionFactory = class _NodeRtcConnectionFactory {
2988
+ static {
2989
+ this._createdConnections = 0;
2990
+ }
2991
+ static {
2992
+ this._cleanupMutex = new import_async10.Mutex();
2993
+ }
2994
+ // This should be inside the function to avoid triggering `eval` in the global scope.
2995
+ // eslint-disable-next-line no-new-func
2996
+ // TODO(burdon): Do imports here?
2997
+ async initialize() {
2998
+ }
2999
+ async onConnectionDestroyed() {
3000
+ return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
3001
+ if (--_NodeRtcConnectionFactory._createdConnections === 0) {
3002
+ (await import("#node-datachannel")).cleanup();
3058
3003
  }
3059
- return {
3060
- datachannel: statsEntries.filter((s) => s[1].type === "data-channel")[0][1],
3061
- transport,
3062
- selectedCandidatePair,
3063
- remoteCandidate,
3064
- raw: Object.fromEntries(stats.entries())
3065
- };
3066
3004
  });
3067
3005
  }
3068
- async getDetails() {
3069
- const stats = await this._getStats();
3070
- const rc = stats?.remoteCandidate;
3071
- if (!rc) {
3072
- return "unavailable";
3006
+ async createConnection(config) {
3007
+ return _NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
3008
+ const { RTCPeerConnection: RTCPeerConnection1 } = await import("#node-datachannel/polyfill");
3009
+ _NodeRtcConnectionFactory._createdConnections++;
3010
+ return new RTCPeerConnection1(config);
3011
+ });
3012
+ }
3013
+ async initConnection(connection, info) {
3014
+ if (info.initiator) {
3015
+ connection.onnegotiationneeded?.(null);
3073
3016
  }
3074
- if (rc.candidateType === "relay") {
3075
- return `${rc.ip}:${rc.port}/${rc.protocol} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3017
+ }
3018
+ };
3019
+ var getRtcConnectionFactory = () => {
3020
+ return typeof globalThis.RTCPeerConnection === "undefined" ? new NodeRtcConnectionFactory() : new BrowserRtcConnectionFactory();
3021
+ };
3022
+ var describeSelectedRemoteCandidate = async (connection) => {
3023
+ const stats = connection && await getRtcConnectionStats(connection);
3024
+ const rc = stats?.remoteCandidate;
3025
+ if (!rc) {
3026
+ return "unavailable";
3027
+ }
3028
+ if (rc.candidateType === "relay") {
3029
+ return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
3030
+ }
3031
+ return `${rc.ip}:${rc.port} ${rc.candidateType}`;
3032
+ };
3033
+ var createRtcTransportStats = async (connection, topic) => {
3034
+ const stats = connection && await getRtcConnectionStats(connection, topic);
3035
+ if (!stats) {
3036
+ return {
3037
+ bytesSent: 0,
3038
+ bytesReceived: 0,
3039
+ packetsSent: 0,
3040
+ packetsReceived: 0,
3041
+ rawStats: {}
3042
+ };
3043
+ }
3044
+ return {
3045
+ bytesSent: stats.dataChannel?.bytesSent,
3046
+ bytesReceived: stats.dataChannel?.bytesReceived,
3047
+ packetsSent: 0,
3048
+ packetsReceived: 0,
3049
+ rawStats: stats.raw
3050
+ };
3051
+ };
3052
+ var getRtcConnectionStats = async (connection, channelTopic) => {
3053
+ const stats = await connection.getStats();
3054
+ const statsEntries = Array.from(stats.entries());
3055
+ const transport = statsEntries.find(([_, entry]) => entry.type === "transport")?.[1];
3056
+ const selectedCandidatePair = transport && statsEntries.find(([entryId]) => entryId === transport.selectedCandidatePairId)?.[1];
3057
+ const remoteCandidate = selectedCandidatePair && statsEntries.find(([entryId]) => entryId === selectedCandidatePair.remoteCandidateId)?.[1];
3058
+ const dataChannel = channelTopic && statsEntries.find(([_, entry]) => entry.type === "data-channel" && entry.label === channelTopic)?.[1];
3059
+ return {
3060
+ transport,
3061
+ selectedCandidatePair,
3062
+ dataChannel,
3063
+ remoteCandidate,
3064
+ raw: Object.fromEntries(stats)
3065
+ };
3066
+ };
3067
+ var __dxlog_file13 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-channel.ts";
3068
+ var MAX_MESSAGE_SIZE = 64 * 1024;
3069
+ var MAX_BUFFERED_AMOUNT = 64 * 1024;
3070
+ var RtcTransportChannel = class extends import_context6.Resource {
3071
+ constructor(_connection, _options) {
3072
+ super();
3073
+ this._connection = _connection;
3074
+ this._options = _options;
3075
+ this.closed = new import_async12.Event();
3076
+ this.connected = new import_async12.Event();
3077
+ this.errors = new import_debug5.ErrorStream();
3078
+ this._streamDataFlushedCallback = null;
3079
+ this._isChannelCreationInProgress = false;
3080
+ }
3081
+ get isRtcChannelCreationInProgress() {
3082
+ return this._isChannelCreationInProgress;
3083
+ }
3084
+ onConnectionError(error) {
3085
+ if (this.isOpen) {
3086
+ this.errors.raise(error);
3076
3087
  }
3077
- return `${rc.ip}:${rc.port}/${rc.protocol} ${rc.candidateType}`;
3078
3088
  }
3079
- async open() {
3080
- import_log12.log.trace("dxos.mesh.webrtc-transport.open", import_protocols7.trace.begin({
3081
- id: this._instanceId
3082
- }), {
3089
+ async _open() {
3090
+ (0, import_invariant12.invariant)(!this._isChannelCreationInProgress, void 0, {
3083
3091
  F: __dxlog_file13,
3084
- L: 122,
3092
+ L: 56,
3085
3093
  S: this,
3086
- C: (f, a) => f(...a)
3094
+ A: [
3095
+ "!this._isChannelCreationInProgress",
3096
+ ""
3097
+ ]
3087
3098
  });
3088
- (0, import_log12.log)("created connection", {
3089
- params: this._params
3090
- }, {
3099
+ this._isChannelCreationInProgress = true;
3100
+ this._connection.createDataChannel(this._options.topic).then((channel) => {
3101
+ if (this.isOpen) {
3102
+ this._channel = channel;
3103
+ this._initChannel(this._channel);
3104
+ } else {
3105
+ this._safeCloseChannel(channel);
3106
+ }
3107
+ }).catch((err) => {
3108
+ if (this.isOpen) {
3109
+ this.errors.raise(new import_protocols8.ConnectivityError(`Failed to create a channel: ${err?.message ?? "unknown reason."}`));
3110
+ }
3111
+ }).finally(() => {
3112
+ this._isChannelCreationInProgress = false;
3113
+ });
3114
+ }
3115
+ async _close() {
3116
+ if (this._channel) {
3117
+ this._safeCloseChannel(this._channel);
3118
+ this._channel = void 0;
3119
+ this._stream = void 0;
3120
+ }
3121
+ this.closed.emit();
3122
+ (0, import_log13.log)("closed", void 0, {
3091
3123
  F: __dxlog_file13,
3092
- L: 123,
3124
+ L: 86,
3093
3125
  S: this,
3094
3126
  C: (f, a) => f(...a)
3095
3127
  });
3096
- const providedIceServers = await this._params.iceProvider?.getIceServers();
3097
- if (!this._params.webrtcConfig) {
3098
- this._params.webrtcConfig = {};
3099
- }
3100
- this._params.webrtcConfig.iceServers = [
3101
- ...this._params.webrtcConfig.iceServers ?? [],
3102
- ...providedIceServers ?? []
3103
- ];
3104
- this._peer = new import_simple_peer.default({
3105
- channelName: "dxos.mesh.transport",
3106
- initiator: this._params.initiator,
3107
- wrtc: import_simple_peer.default.WEBRTC_SUPPORT ? void 0 : wrtc ?? (0, import_debug5.raise)(new Error("wrtc not available")),
3108
- config: this._params.webrtcConfig
3109
- });
3110
- this._peer.on("signal", async (data) => {
3111
- (0, import_log12.log)("signal", data, {
3112
- F: __dxlog_file13,
3113
- L: 142,
3114
- S: this,
3115
- C: (f, a) => f(...a)
3116
- });
3117
- await this._params.sendSignal({
3118
- payload: {
3119
- data
3120
- }
3121
- });
3122
- });
3123
- this._peer.on("connect", () => {
3124
- (0, import_log12.log)("connected", void 0, {
3125
- F: __dxlog_file13,
3126
- L: 147,
3127
- S: this,
3128
- C: (f, a) => f(...a)
3129
- });
3130
- this._params.stream.pipe(this._peer).pipe(this._params.stream);
3131
- this._piped = true;
3132
- this.connected.emit();
3133
- });
3134
- this._peer.on("close", async () => {
3135
- (0, import_log12.log)("closed", void 0, {
3136
- F: __dxlog_file13,
3137
- L: 154,
3138
- S: this,
3139
- C: (f, a) => f(...a)
3140
- });
3141
- await this.close();
3142
- });
3143
- this._peer.on("error", async (err) => {
3144
- if (typeof RTCError !== "undefined" && err instanceof RTCError) {
3145
- if (err.errorDetail === "sctp-failure") {
3146
- this.errors.raise(new import_protocols7.ConnectionResetError("sctp-failure from RTCError", err));
3147
- } else {
3148
- import_log12.log.info("unknown RTCError", {
3149
- err
3128
+ }
3129
+ _initChannel(channel) {
3130
+ Object.assign(channel, {
3131
+ onopen: () => {
3132
+ if (!this.isOpen) {
3133
+ import_log13.log.warn("channel opened in a closed transport", {
3134
+ topic: this._options.topic
3150
3135
  }, {
3151
3136
  F: __dxlog_file13,
3152
- L: 165,
3137
+ L: 93,
3153
3138
  S: this,
3154
3139
  C: (f, a) => f(...a)
3155
3140
  });
3156
- this.errors.raise(new import_protocols7.UnknownProtocolError("unknown RTCError", err));
3141
+ this._safeCloseChannel(channel);
3142
+ return;
3157
3143
  }
3158
- } else if ("code" in err) {
3159
- import_log12.log.info("simple-peer error", err, {
3144
+ (0, import_log13.log)("onopen", void 0, {
3160
3145
  F: __dxlog_file13,
3161
- L: 170,
3146
+ L: 98,
3162
3147
  S: this,
3163
3148
  C: (f, a) => f(...a)
3164
3149
  });
3165
- switch (err.code) {
3166
- case "ERR_WEBRTC_SUPPORT":
3167
- this.errors.raise(new import_protocols7.ProtocolError("WebRTC not supported", err));
3168
- break;
3169
- case "ERR_SIGNALING":
3170
- this.errors.raise(new import_protocols7.ConnectivityError("signaling failure", err));
3171
- break;
3172
- case "ERR_ICE_CONNECTION_FAILURE":
3173
- case "ERR_DATA_CHANNEL":
3174
- case "ERR_CONNECTION_FAILURE":
3175
- this.errors.raise(new import_protocols7.ConnectivityError("unknown communication failure", err));
3176
- break;
3177
- // errors due to library issues or improper API usage
3178
- case "ERR_CREATE_OFFER":
3179
- case "ERR_CREATE_ANSWER":
3180
- case "ERR_SET_LOCAL_DESCRIPTION":
3181
- case "ERR_SET_REMOTE_DESCRIPTION":
3182
- case "ERR_ADD_ICE_CANDIDATE":
3183
- this.errors.raise(new import_protocols7.UnknownProtocolError("unknown simple-peer library failure", err));
3184
- break;
3185
- default:
3186
- this.errors.raise(new Error("unknown simple-peer error"));
3187
- break;
3188
- }
3189
- } else {
3190
- import_log12.log.info("unknown peer connection error", err, {
3150
+ const duplex = new import_node_stream2.Duplex({
3151
+ read: () => {
3152
+ },
3153
+ write: (chunk, encoding, callback) => {
3154
+ return this._handleChannelWrite(chunk, callback);
3155
+ }
3156
+ });
3157
+ duplex.pipe(this._options.stream).pipe(duplex);
3158
+ this._stream = duplex;
3159
+ this.connected.emit();
3160
+ },
3161
+ onclose: async () => {
3162
+ (0, import_log13.log)("onclose", void 0, {
3191
3163
  F: __dxlog_file13,
3192
- L: 196,
3164
+ L: 111,
3193
3165
  S: this,
3194
3166
  C: (f, a) => f(...a)
3195
3167
  });
3196
- this.errors.raise(err);
3197
- }
3198
- try {
3199
- if (typeof this._peer?._pc?.getStats === "function") {
3200
- this._peer._pc.getStats().then((stats) => {
3201
- import_log12.log.info("report after webrtc error", {
3202
- config: this._params.webrtcConfig,
3203
- stats: Object.fromEntries(stats.entries())
3204
- }, {
3205
- F: __dxlog_file13,
3206
- L: 204,
3207
- S: this,
3208
- C: (f, a) => f(...a)
3209
- });
3168
+ await this.close();
3169
+ },
3170
+ onmessage: (event) => {
3171
+ if (!this._stream) {
3172
+ import_log13.log.warn("ignoring message on a closed channel", void 0, {
3173
+ F: __dxlog_file13,
3174
+ L: 117,
3175
+ S: this,
3176
+ C: (f, a) => f(...a)
3210
3177
  });
3178
+ return;
3211
3179
  }
3212
- } catch (err2) {
3213
- import_log12.log.catch(err2, void 0, {
3214
- F: __dxlog_file13,
3215
- L: 211,
3216
- S: this,
3217
- C: (f, a) => f(...a)
3218
- });
3180
+ let data = event.data;
3181
+ if (data instanceof ArrayBuffer) {
3182
+ data = Buffer.from(data);
3183
+ }
3184
+ this._stream.push(data);
3185
+ },
3186
+ onerror: (event) => {
3187
+ if (this.isOpen) {
3188
+ const err = event.error instanceof Error ? event.error : new Error(`Datachannel error: ${event.type}.`);
3189
+ this.errors.raise(err);
3190
+ }
3191
+ },
3192
+ onbufferedamountlow: () => {
3193
+ const cb = this._streamDataFlushedCallback;
3194
+ this._streamDataFlushedCallback = null;
3195
+ cb?.();
3219
3196
  }
3220
- await this.close();
3221
- });
3222
- import_log12.log.trace("dxos.mesh.webrtc-transport.open", import_protocols7.trace.end({
3223
- id: this._instanceId
3224
- }), {
3225
- F: __dxlog_file13,
3226
- L: 217,
3227
- S: this,
3228
- C: (f, a) => f(...a)
3229
3197
  });
3230
3198
  }
3231
- async close() {
3232
- (0, import_log12.log)("closing...", void 0, {
3233
- F: __dxlog_file13,
3234
- L: 222,
3235
- S: this,
3236
- C: (f, a) => f(...a)
3237
- });
3238
- if (this._closed) {
3199
+ async _handleChannelWrite(chunk, callback) {
3200
+ if (!this._channel) {
3201
+ import_log13.log.warn("writing to a channel after a connection was closed", void 0, {
3202
+ F: __dxlog_file13,
3203
+ L: 145,
3204
+ S: this,
3205
+ C: (f, a) => f(...a)
3206
+ });
3239
3207
  return;
3240
3208
  }
3241
- this._disconnectStreams();
3242
- this._peer.destroy();
3243
- this._closed = true;
3244
- this.closed.emit();
3245
- (0, import_log12.log)("closed", void 0, {
3246
- F: __dxlog_file13,
3247
- L: 230,
3248
- S: this,
3249
- C: (f, a) => f(...a)
3250
- });
3251
- }
3252
- async onSignal(signal) {
3253
- if (this._closed) {
3209
+ if (chunk.length > MAX_MESSAGE_SIZE) {
3210
+ const error = new Error(`Message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}.`);
3211
+ this.errors.raise(error);
3212
+ callback();
3213
+ return;
3214
+ }
3215
+ try {
3216
+ this._channel.send(chunk);
3217
+ } catch (err) {
3218
+ this.errors.raise(err);
3219
+ callback();
3254
3220
  return;
3255
3221
  }
3256
- (0, import_tiny_invariant.default)(signal.payload.data, "Signal message must contain signal data.");
3257
- (0, import_tiny_invariant.default)(this._peer, "Peer must be initialized before receiving signals.");
3258
- this._peer.signal(signal.payload.data);
3222
+ if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
3223
+ if (this._streamDataFlushedCallback !== null) {
3224
+ import_log13.log.error("consumer trying to write before we are ready for more data", void 0, {
3225
+ F: __dxlog_file13,
3226
+ L: 166,
3227
+ S: this,
3228
+ C: (f, a) => f(...a)
3229
+ });
3230
+ }
3231
+ this._streamDataFlushedCallback = callback;
3232
+ } else {
3233
+ callback();
3234
+ }
3259
3235
  }
3260
- _disconnectStreams() {
3261
- if (this._piped) {
3262
- this._params.stream.unpipe?.(this._peer)?.unpipe?.(this._params.stream);
3236
+ _safeCloseChannel(channel) {
3237
+ try {
3238
+ channel.close();
3239
+ } catch (error) {
3240
+ import_log13.log.catch(error, void 0, {
3241
+ F: __dxlog_file13,
3242
+ L: 178,
3243
+ S: this,
3244
+ C: (f, a) => f(...a)
3245
+ });
3263
3246
  }
3264
3247
  }
3248
+ onSignal(signal) {
3249
+ return this._connection.onSignal(signal);
3250
+ }
3251
+ async getDetails() {
3252
+ return describeSelectedRemoteCandidate(this._connection.currentConnection);
3253
+ }
3254
+ async getStats() {
3255
+ return createRtcTransportStats(this._connection.currentConnection, this._options.topic);
3256
+ }
3265
3257
  };
3266
- _ts_decorate6([
3267
- import_async10.synchronized
3268
- ], SimplePeerTransport.prototype, "open", null);
3269
- _ts_decorate6([
3270
- import_async10.synchronized
3271
- ], SimplePeerTransport.prototype, "close", null);
3272
- _ts_decorate6([
3273
- import_async10.synchronized
3274
- ], SimplePeerTransport.prototype, "onSignal", null);
3275
- var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-service.ts";
3276
- var SimplePeerTransportService = class {
3277
- constructor(_webrtcConfig, _iceProvider) {
3278
- this._webrtcConfig = _webrtcConfig;
3279
- this._iceProvider = _iceProvider;
3280
- this.transports = new import_util9.ComplexMap(import_keys11.PublicKey.hash);
3258
+ var chooseInitiatorPeer = (peer1Key, peer2Key) => peer1Key < peer2Key ? peer1Key : peer2Key;
3259
+ var areSdpEqual = (sdp1, sdp2) => {
3260
+ const sdp1Lines = deduplicatedSdpLines(sdp1);
3261
+ const sdp2Lines = deduplicatedSdpLines(sdp2);
3262
+ if (sdp1Lines.length !== sdp2Lines.length) {
3263
+ return false;
3264
+ }
3265
+ return sdp1Lines.every((line, idx) => line === sdp2Lines[idx]);
3266
+ };
3267
+ var deduplicatedSdpLines = (sdp) => {
3268
+ const deduplicatedLines = [];
3269
+ const seenLines = [];
3270
+ for (const line of sdp.split("\r\n")) {
3271
+ if (line.startsWith("m")) {
3272
+ seenLines.length = 0;
3273
+ }
3274
+ if (seenLines.includes(line)) {
3275
+ continue;
3276
+ }
3277
+ seenLines.push(line);
3278
+ deduplicatedLines.push(line);
3281
3279
  }
3282
- open(request) {
3283
- const rpcStream = new import_codec_protobuf.Stream(({ ready, next, close }) => {
3284
- const duplex = new import_node_stream2.Duplex({
3285
- read: () => {
3286
- const callbacks = [
3287
- ...transportState.writeCallbacks
3288
- ];
3289
- transportState.writeCallbacks.length = 0;
3290
- for (const cb of callbacks) {
3291
- cb();
3292
- }
3293
- },
3294
- write: function(chunk, _, callback) {
3295
- next({
3296
- data: {
3297
- payload: chunk
3298
- }
3299
- });
3300
- callback();
3301
- }
3302
- });
3303
- const transport = new SimplePeerTransport({
3304
- initiator: request.initiator,
3305
- stream: duplex,
3306
- webrtcConfig: this._webrtcConfig,
3307
- sendSignal: async (signal) => {
3308
- next({
3309
- signal: {
3310
- payload: signal
3311
- }
3312
- });
3313
- },
3314
- iceProvider: this._iceProvider
3315
- });
3316
- void transport.open();
3317
- next({
3318
- connection: {
3319
- state: import_bridge.ConnectionState.CONNECTING
3320
- }
3321
- });
3322
- transport.connected.on(() => {
3323
- next({
3324
- connection: {
3325
- state: import_bridge.ConnectionState.CONNECTED
3326
- }
3327
- });
3328
- });
3329
- transport.errors.handle((err) => {
3330
- next({
3331
- connection: {
3332
- state: import_bridge.ConnectionState.CLOSED,
3333
- error: err.toString()
3334
- }
3335
- });
3336
- close(err);
3337
- });
3338
- transport.closed.on(() => {
3339
- next({
3340
- connection: {
3341
- state: import_bridge.ConnectionState.CLOSED
3342
- }
3343
- });
3344
- close();
3345
- });
3346
- const transportState = {
3347
- transport,
3348
- stream: duplex,
3349
- writeCallbacks: [],
3350
- state: "OPEN"
3351
- };
3352
- ready();
3353
- this.transports.set(request.proxyId, transportState);
3354
- });
3355
- return rpcStream;
3356
- }
3357
- async sendSignal({ proxyId, signal }) {
3358
- (0, import_invariant11.invariant)(this.transports.has(proxyId), void 0, {
3359
- F: __dxlog_file14,
3360
- L: 124,
3361
- S: this,
3362
- A: [
3363
- "this.transports.has(proxyId)",
3364
- ""
3365
- ]
3366
- });
3367
- await this.transports.get(proxyId).transport.onSignal(signal);
3368
- }
3369
- async getDetails({ proxyId }) {
3370
- (0, import_invariant11.invariant)(this.transports.has(proxyId), void 0, {
3371
- F: __dxlog_file14,
3372
- L: 129,
3373
- S: this,
3374
- A: [
3375
- "this.transports.has(proxyId)",
3376
- ""
3377
- ]
3378
- });
3379
- return {
3380
- details: await this.transports.get(proxyId).transport.getDetails()
3381
- };
3382
- }
3383
- async getStats({ proxyId }) {
3384
- (0, import_invariant11.invariant)(this.transports.has(proxyId), void 0, {
3385
- F: __dxlog_file14,
3386
- L: 134,
3387
- S: this,
3388
- A: [
3389
- "this.transports.has(proxyId)",
3390
- ""
3391
- ]
3392
- });
3393
- return {
3394
- stats: await this.transports.get(proxyId).transport.getStats()
3395
- };
3396
- }
3397
- async sendData({ proxyId, payload }) {
3398
- if (this.transports.get(proxyId)?.state !== "OPEN") {
3399
- import_log13.log.debug("transport is closed", void 0, {
3280
+ return deduplicatedLines;
3281
+ };
3282
+ function _ts_decorate6(decorators, target, key, desc) {
3283
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3284
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3285
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3286
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
3287
+ }
3288
+ var __dxlog_file14 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-peer-connection.ts";
3289
+ var RtcPeerConnection = class {
3290
+ constructor(_factory, _options) {
3291
+ this._factory = _factory;
3292
+ this._options = _options;
3293
+ this._channelCreatedCallbacks = /* @__PURE__ */ new Map();
3294
+ this._transportChannels = /* @__PURE__ */ new Map();
3295
+ this._dataChannels = /* @__PURE__ */ new Map();
3296
+ this._readyForCandidates = new import_async11.Trigger();
3297
+ this._offerProcessingMutex = new import_async11.Mutex();
3298
+ this._initiator = chooseInitiatorPeer(_options.ownPeerKey, _options.remotePeerKey) === _options.ownPeerKey;
3299
+ }
3300
+ get transportChannelCount() {
3301
+ return this._transportChannels.size;
3302
+ }
3303
+ get currentConnection() {
3304
+ return this._connection;
3305
+ }
3306
+ async createDataChannel(topic) {
3307
+ const connection = await this._openConnection();
3308
+ if (!this._transportChannels.has(topic)) {
3309
+ if (!this._transportChannels.size) {
3310
+ this._lockAndCloseConnection();
3311
+ }
3312
+ throw new Error("Transport closed while connection was being open");
3313
+ }
3314
+ if (this._initiator) {
3315
+ const channel = connection.createDataChannel(topic);
3316
+ this._dataChannels.set(topic, channel);
3317
+ return channel;
3318
+ } else {
3319
+ const existingChannel = this._dataChannels.get(topic);
3320
+ if (existingChannel) {
3321
+ return existingChannel;
3322
+ }
3323
+ (0, import_log12.log)("waiting for initiator-peer to open a data channel", void 0, {
3400
3324
  F: __dxlog_file14,
3401
- L: 140,
3325
+ L: 90,
3402
3326
  S: this,
3403
3327
  C: (f, a) => f(...a)
3404
3328
  });
3405
- }
3406
- (0, import_invariant11.invariant)(this.transports.has(proxyId), void 0, {
3407
- F: __dxlog_file14,
3408
- L: 142,
3409
- S: this,
3410
- A: [
3411
- "this.transports.has(proxyId)",
3412
- ""
3413
- ]
3414
- });
3415
- const state = this.transports.get(proxyId);
3416
- const bufferHasSpace = state.stream.push(payload);
3417
- if (!bufferHasSpace) {
3418
- await new Promise((resolve) => {
3419
- state.writeCallbacks.push(resolve);
3329
+ return new Promise((resolve, reject) => {
3330
+ this._channelCreatedCallbacks.set(topic, {
3331
+ resolve,
3332
+ reject
3333
+ });
3420
3334
  });
3421
3335
  }
3422
3336
  }
3423
- async close({ proxyId }) {
3424
- await this.transports.get(proxyId)?.transport.close();
3425
- await this.transports.get(proxyId)?.stream.end();
3426
- if (this.transports.get(proxyId)) {
3427
- this.transports.get(proxyId).state = "CLOSED";
3337
+ createTransportChannel(options) {
3338
+ const channel = new RtcTransportChannel(this, options);
3339
+ this._transportChannels.set(options.topic, channel);
3340
+ channel.closed.on(() => {
3341
+ this._transportChannels.delete(options.topic);
3342
+ if (this._transportChannels.size === 0) {
3343
+ this._lockAndCloseConnection();
3344
+ }
3345
+ });
3346
+ return channel;
3347
+ }
3348
+ async _openConnection() {
3349
+ if (this._connection) {
3350
+ return this._connection;
3428
3351
  }
3429
- (0, import_log13.log)("Closed.", void 0, {
3352
+ (0, import_log12.log)("initializing connection...", () => ({
3353
+ remotePeer: this._options.remotePeerKey
3354
+ }), {
3430
3355
  F: __dxlog_file14,
3431
- L: 158,
3356
+ L: 115,
3432
3357
  S: this,
3433
3358
  C: (f, a) => f(...a)
3434
3359
  });
3435
- }
3436
- };
3437
- var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/simplepeer-transport-proxy.ts";
3438
- var RPC_TIMEOUT = 1e4;
3439
- var RESP_MIN_THRESHOLD = 500;
3440
- var TIMEOUT_THRESHOLD = 10;
3441
- var SimplePeerTransportProxy = class {
3442
- constructor(_options) {
3443
- this._options = _options;
3444
- this._proxyId = import_keys12.PublicKey.random();
3445
- this._ctx = new import_context6.Context(void 0, {
3446
- F: __dxlog_file15,
3447
- L: 37
3448
- });
3449
- this._timeoutCount = 0;
3450
- this.closed = new import_async11.Event();
3451
- this.connected = new import_async11.Event();
3452
- this.errors = new import_debug6.ErrorStream();
3453
- this._closed = false;
3454
- }
3455
- get isOpen() {
3456
- return !this._closed;
3457
- }
3458
- async open() {
3459
- this._serviceStream = this._options.bridgeService.open({
3460
- proxyId: this._proxyId,
3461
- initiator: this._options.initiator
3462
- }, {
3463
- timeout: RPC_TIMEOUT
3464
- });
3465
- this._serviceStream.waitUntilReady().then(() => {
3466
- this._serviceStream.subscribe(async (event) => {
3467
- (0, import_log14.log)("SimplePeerTransportProxy: event", event, {
3468
- F: __dxlog_file15,
3469
- L: 66,
3360
+ const config = await this._loadConnectionConfig();
3361
+ const connection = await this._factory.createConnection(config);
3362
+ const iceCandidateErrors = [];
3363
+ Object.assign(connection, {
3364
+ onnegotiationneeded: async () => {
3365
+ (0, import_invariant11.invariant)(this._initiator, void 0, {
3366
+ F: __dxlog_file14,
3367
+ L: 130,
3368
+ S: this,
3369
+ A: [
3370
+ "this._initiator",
3371
+ ""
3372
+ ]
3373
+ });
3374
+ if (connection !== this._connection) {
3375
+ this._onConnectionCallbackAfterClose("onnegotiationneeded", connection);
3376
+ return;
3377
+ }
3378
+ (0, import_log12.log)("onnegotiationneeded", void 0, {
3379
+ F: __dxlog_file14,
3380
+ L: 137,
3470
3381
  S: this,
3471
3382
  C: (f, a) => f(...a)
3472
3383
  });
3473
- if (event.connection) {
3474
- await this._handleConnection(event.connection);
3475
- } else if (event.data) {
3476
- this._handleData(event.data);
3477
- } else if (event.signal) {
3478
- await this._handleSignal(event.signal);
3384
+ try {
3385
+ const offer = await connection.createOffer();
3386
+ await connection.setLocalDescription(offer);
3387
+ await this._sendDescription(connection, offer);
3388
+ } catch (err) {
3389
+ this._lockAndAbort(connection, err);
3479
3390
  }
3480
- });
3481
- const proxyStream = new import_node_stream3.Writable({
3482
- write: (chunk, _, callback) => {
3483
- const then = performance.now();
3484
- this._options.bridgeService.sendData({
3485
- proxyId: this._proxyId,
3486
- payload: chunk
3391
+ },
3392
+ // When ICE candidate identified (should be sent to remote peer) and when ICE gathering finalized.
3393
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidate_event
3394
+ onicecandidate: async (event) => {
3395
+ if (connection !== this._connection) {
3396
+ this._onConnectionCallbackAfterClose("onicecandidate", connection);
3397
+ return;
3398
+ }
3399
+ if (event.candidate) {
3400
+ (0, import_log12.log)("onicecandidate", {
3401
+ candidate: event.candidate.candidate
3487
3402
  }, {
3488
- timeout: RPC_TIMEOUT
3489
- }).then(() => {
3490
- if (performance.now() - then > RESP_MIN_THRESHOLD) {
3491
- (0, import_log14.log)("slow response, delaying callback", void 0, {
3492
- F: __dxlog_file15,
3493
- L: 90,
3494
- S: this,
3495
- C: (f, a) => f(...a)
3496
- });
3497
- (0, import_async11.scheduleTask)(this._ctx, () => callback(), RESP_MIN_THRESHOLD);
3498
- } else {
3499
- callback();
3500
- }
3501
- this._timeoutCount = 0;
3502
- }, (err) => {
3503
- if (err instanceof import_protocols8.TimeoutError || err.constructor.name === "TimeoutError") {
3504
- if (this._timeoutCount++ > TIMEOUT_THRESHOLD) {
3505
- throw new import_protocols8.TimeoutError(`too many timeouts (${this._timeoutCount} > ${TIMEOUT_THRESHOLD}`);
3506
- } else {
3507
- (0, import_log14.log)("timeout error, but still invoking callback", void 0, {
3508
- F: __dxlog_file15,
3509
- L: 102,
3510
- S: this,
3511
- C: (f, a) => f(...a)
3512
- });
3513
- callback();
3514
- }
3515
- } else {
3516
- import_log14.log.catch(err, void 0, {
3517
- F: __dxlog_file15,
3518
- L: 106,
3519
- S: this,
3520
- C: (f, a) => f(...a)
3521
- });
3522
- }
3403
+ F: __dxlog_file14,
3404
+ L: 156,
3405
+ S: this,
3406
+ C: (f, a) => f(...a)
3407
+ });
3408
+ await this._sendIceCandidate(event.candidate);
3409
+ } else {
3410
+ (0, import_log12.log)("onicecandidate gathering complete", void 0, {
3411
+ F: __dxlog_file14,
3412
+ L: 159,
3413
+ S: this,
3414
+ C: (f, a) => f(...a)
3523
3415
  });
3524
3416
  }
3525
- });
3526
- proxyStream.on("error", (err) => {
3527
- (0, import_log14.log)("proxystream error", {
3528
- err
3417
+ },
3418
+ // When error occurs while performing ICE negotiations through a STUN or TURN server.
3419
+ // It's ok for some candidates to fail if a working pair is eventually found.
3420
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/icecandidateerror_event
3421
+ onicecandidateerror: (event) => {
3422
+ const { url, errorCode, errorText } = event;
3423
+ iceCandidateErrors.push({
3424
+ url,
3425
+ errorCode,
3426
+ errorText
3427
+ });
3428
+ },
3429
+ // When possible error during ICE gathering.
3430
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event
3431
+ oniceconnectionstatechange: () => {
3432
+ if (connection !== this._connection) {
3433
+ this._onConnectionCallbackAfterClose("oniceconnectionstatechange", connection);
3434
+ return;
3435
+ }
3436
+ (0, import_log12.log)("oniceconnectionstatechange", {
3437
+ state: connection.iceConnectionState
3529
3438
  }, {
3530
- F: __dxlog_file15,
3531
- L: 114,
3439
+ F: __dxlog_file14,
3440
+ L: 179,
3532
3441
  S: this,
3533
3442
  C: (f, a) => f(...a)
3534
3443
  });
3535
- });
3536
- this._options.stream.pipe(proxyStream);
3537
- }, (error) => import_log14.log.catch(error, void 0, {
3538
- F: __dxlog_file15,
3539
- L: 119,
3540
- S: this,
3541
- C: (f, a) => f(...a)
3542
- }));
3444
+ if (connection.iceConnectionState === "failed") {
3445
+ this._lockAndAbort(connection, createIceFailureError(iceCandidateErrors));
3446
+ }
3447
+ },
3448
+ // When new track (or channel) is added.
3449
+ // State: { new, connecting, connected, disconnected, failed, closed }
3450
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionstatechange_event
3451
+ onconnectionstatechange: () => {
3452
+ if (connection !== this._connection) {
3453
+ if (connection.connectionState !== "closed" && connection.connectionState !== "failed") {
3454
+ this._onConnectionCallbackAfterClose("onconnectionstatechange", connection);
3455
+ }
3456
+ return;
3457
+ }
3458
+ (0, import_log12.log)("onconnectionstatechange", {
3459
+ state: connection.connectionState
3460
+ }, {
3461
+ F: __dxlog_file14,
3462
+ L: 196,
3463
+ S: this,
3464
+ C: (f, a) => f(...a)
3465
+ });
3466
+ if (connection.connectionState === "failed") {
3467
+ this._lockAndAbort(connection, new Error("Connection failed."));
3468
+ }
3469
+ },
3470
+ onsignalingstatechange: () => {
3471
+ (0, import_log12.log)("onsignalingstatechange", {
3472
+ state: connection.signalingState
3473
+ }, {
3474
+ F: __dxlog_file14,
3475
+ L: 203,
3476
+ S: this,
3477
+ C: (f, a) => f(...a)
3478
+ });
3479
+ },
3480
+ // When channel is added to connection.
3481
+ // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event
3482
+ ondatachannel: (event) => {
3483
+ (0, import_invariant11.invariant)(!this._initiator, "Initiator is expected to create data channels.", {
3484
+ F: __dxlog_file14,
3485
+ L: 209,
3486
+ S: this,
3487
+ A: [
3488
+ "!this._initiator",
3489
+ "'Initiator is expected to create data channels.'"
3490
+ ]
3491
+ });
3492
+ if (connection !== this._connection) {
3493
+ this._onConnectionCallbackAfterClose("ondatachannel", connection);
3494
+ return;
3495
+ }
3496
+ (0, import_log12.log)("ondatachannel", {
3497
+ label: event.channel.label
3498
+ }, {
3499
+ F: __dxlog_file14,
3500
+ L: 216,
3501
+ S: this,
3502
+ C: (f, a) => f(...a)
3503
+ });
3504
+ this._dataChannels.set(event.channel.label, event.channel);
3505
+ const pendingCallback = this._channelCreatedCallbacks.get(event.channel.label);
3506
+ if (pendingCallback) {
3507
+ this._channelCreatedCallbacks.delete(event.channel.label);
3508
+ pendingCallback.resolve(event.channel);
3509
+ }
3510
+ }
3511
+ });
3512
+ this._connection = connection;
3513
+ this._readyForCandidates.reset();
3514
+ await this._factory.initConnection(connection, {
3515
+ initiator: this._initiator
3516
+ });
3517
+ return this._connection;
3543
3518
  }
3544
- async close() {
3545
- await this._ctx.dispose();
3546
- if (this._closed) {
3547
- return;
3548
- }
3549
- await this._serviceStream.close();
3550
- try {
3551
- await this._options.bridgeService.close({
3552
- proxyId: this._proxyId
3519
+ _lockAndAbort(connection, error) {
3520
+ this._abortConnection(connection, error);
3521
+ }
3522
+ _abortConnection(connection, error) {
3523
+ if (connection !== this._connection) {
3524
+ import_log12.log.error("attempted to abort an inactive connection", {
3525
+ error
3553
3526
  }, {
3554
- timeout: RPC_TIMEOUT
3555
- });
3556
- } catch (err) {
3557
- import_log14.log.catch(err, void 0, {
3558
- F: __dxlog_file15,
3559
- L: 134,
3527
+ F: __dxlog_file14,
3528
+ L: 241,
3560
3529
  S: this,
3561
3530
  C: (f, a) => f(...a)
3562
3531
  });
3532
+ this._safeCloseConnection(connection);
3533
+ return;
3563
3534
  }
3564
- this.closed.emit();
3565
- this._closed = true;
3566
- }
3567
- async onSignal(signal) {
3568
- this._options.bridgeService.sendSignal({
3569
- proxyId: this._proxyId,
3570
- signal
3571
- }, {
3572
- timeout: RPC_TIMEOUT
3573
- }).catch((err) => this.errors.raise(decodeError(err)));
3574
- }
3575
- async _handleConnection(connectionEvent) {
3576
- if (connectionEvent.error) {
3577
- this.errors.raise(decodeError(connectionEvent.error));
3535
+ for (const [topic, pendingCallback] of this._channelCreatedCallbacks.entries()) {
3536
+ pendingCallback.reject(error);
3537
+ this._transportChannels.delete(topic);
3578
3538
  }
3579
- switch (connectionEvent.state) {
3580
- case import_bridge2.ConnectionState.CONNECTED: {
3581
- this.connected.emit();
3582
- break;
3583
- }
3584
- case import_bridge2.ConnectionState.CLOSED: {
3585
- await this.close();
3586
- break;
3587
- }
3539
+ this._channelCreatedCallbacks.clear();
3540
+ for (const channel of this._transportChannels.values()) {
3541
+ channel.onConnectionError(error);
3588
3542
  }
3589
- }
3590
- _handleData(dataEvent) {
3591
- this._options.stream.write((0, import_util10.arrayToBuffer)(dataEvent.payload));
3592
- }
3593
- async _handleSignal(signalEvent) {
3594
- await this._options.sendSignal(signalEvent.payload);
3595
- }
3596
- async getDetails() {
3597
- return (await this._options.bridgeService.getDetails({
3598
- proxyId: this._proxyId
3599
- }, {
3600
- timeout: RPC_TIMEOUT
3601
- })).details;
3602
- }
3603
- async getStats() {
3604
- return (await this._options.bridgeService.getStats({
3605
- proxyId: this._proxyId
3543
+ this._transportChannels.clear();
3544
+ this._safeCloseConnection();
3545
+ (0, import_log12.log)("connection aborted", {
3546
+ reason: error.message
3606
3547
  }, {
3607
- timeout: RPC_TIMEOUT
3608
- })).stats;
3609
- }
3610
- /**
3611
- * Called when underlying proxy service becomes unavailable.
3612
- */
3613
- // TODO(burdon): Option on close method.
3614
- forceClose() {
3615
- void this._serviceStream.close();
3616
- this.closed.emit();
3617
- this._closed = true;
3618
- }
3619
- };
3620
- var SimplePeerTransportProxyFactory = class {
3621
- constructor() {
3622
- this._connections = /* @__PURE__ */ new Set();
3623
- }
3624
- /**
3625
- * Sets the current BridgeService to be used to open connections.
3626
- * Calling this method will close any existing connections.
3627
- */
3628
- setBridgeService(bridgeService) {
3629
- this._bridgeService = bridgeService;
3630
- for (const connection of this._connections) {
3631
- connection.forceClose();
3632
- }
3633
- return this;
3548
+ F: __dxlog_file14,
3549
+ L: 255,
3550
+ S: this,
3551
+ C: (f, a) => f(...a)
3552
+ });
3634
3553
  }
3635
- createTransport(options) {
3636
- (0, import_invariant12.invariant)(this._bridgeService, "SimplePeerTransportProxyFactory is not ready to open connections", {
3637
- F: __dxlog_file15,
3638
- L: 218,
3554
+ _lockAndCloseConnection() {
3555
+ (0, import_invariant11.invariant)(this._transportChannels.size === 0, void 0, {
3556
+ F: __dxlog_file14,
3557
+ L: 260,
3639
3558
  S: this,
3640
3559
  A: [
3641
- "this._bridgeService",
3642
- "'SimplePeerTransportProxyFactory is not ready to open connections'"
3560
+ "this._transportChannels.size === 0",
3561
+ ""
3643
3562
  ]
3644
3563
  });
3645
- const transport = new SimplePeerTransportProxy({
3646
- ...options,
3647
- bridgeService: this._bridgeService
3648
- });
3649
- this._connections.add(transport);
3650
- transport.closed.on(() => this._connections.delete(transport));
3651
- return transport;
3652
- }
3653
- };
3654
- var decodeError = (err) => {
3655
- const message = typeof err === "string" ? err : err.message;
3656
- if (message.includes("CONNECTION_RESET")) {
3657
- return new import_protocols8.ConnectionResetError(message);
3658
- } else if (message.includes("TIMEOUT")) {
3659
- return new import_protocols8.TimeoutError(message);
3660
- } else if (message.includes("PROTOCOL_ERROR")) {
3661
- return new import_protocols8.ProtocolError(message);
3662
- } else if (message.includes("CONNECTIVITY_ERROR")) {
3663
- return new import_protocols8.ConnectivityError(message);
3664
- } else if (message.includes("UNKNOWN_PROTOCOL_ERROR")) {
3665
- return new import_protocols8.UnknownProtocolError(message);
3666
- } else {
3667
- return typeof err === "string" ? new Error(err) : err;
3668
- }
3669
- };
3670
- function _ts_decorate7(decorators, target, key, desc) {
3671
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3672
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
3673
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
3674
- return c > 3 && r && Object.defineProperty(target, key, r), r;
3675
- }
3676
- var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/libdatachannel-transport.ts";
3677
- var DATACHANNEL_LABEL = "dxos.mesh.transport";
3678
- var MAX_BUFFERED_AMOUNT = 64 * 1024;
3679
- var MAX_MESSAGE_SIZE = 64 * 1024;
3680
- var createLibDataChannelTransportFactory = (webrtcConfig, iceProvider) => {
3681
- return {
3682
- createTransport: (options) => new LibDataChannelTransport({
3683
- ...options,
3684
- webrtcConfig,
3685
- iceProvider
3686
- })
3687
- };
3688
- };
3689
- var LibDataChannelTransport = class _LibDataChannelTransport {
3690
- static {
3691
- this._instanceCount = 0;
3692
- }
3693
- constructor(_options) {
3694
- this._options = _options;
3695
- this._closed = false;
3696
- this._connected = false;
3697
- this._writeCallback = null;
3698
- this._readyForCandidates = new import_async12.Trigger();
3699
- this.closed = new import_async12.Event();
3700
- this.connected = new import_async12.Event();
3701
- this.errors = new import_debug7.ErrorStream();
3702
- }
3703
- get isOpen() {
3704
- return !!this._peer && !this._closed;
3705
- }
3706
- async open() {
3707
- if (this._closed) {
3708
- this.errors.raise(new Error("connection already closed"));
3709
- }
3710
- const { RTCPeerConnection } = (await importESM("node-datachannel/polyfill")).default;
3711
- const providedIceServers = await this._options.iceProvider?.getIceServers();
3712
- if (!this._options.webrtcConfig) {
3713
- this._options.webrtcConfig = {};
3714
- }
3715
- this._options.webrtcConfig.iceServers = [
3716
- ...this._options.webrtcConfig.iceServers ?? [],
3717
- ...providedIceServers ?? []
3718
- ];
3719
- this._peer = new RTCPeerConnection(this._options.webrtcConfig);
3720
- this._peer.onicecandidateerror = (event) => {
3721
- import_log15.log.error("peer.onicecandidateerror", {
3722
- event
3723
- }, {
3724
- F: __dxlog_file16,
3725
- L: 93,
3726
- S: this,
3727
- C: (f, a) => f(...a)
3728
- });
3729
- };
3730
- this._peer.onconnectionstatechange = (event) => {
3731
- import_log15.log.debug("peer.onconnectionstatechange", {
3732
- event,
3733
- peerConnectionState: this._peer?.connectionState,
3734
- transportConnectionState: this._connected
3735
- }, {
3736
- F: __dxlog_file16,
3737
- L: 97,
3564
+ if (this._connection) {
3565
+ this._safeCloseConnection();
3566
+ (0, import_log12.log)("connection closed", void 0, {
3567
+ F: __dxlog_file14,
3568
+ L: 263,
3738
3569
  S: this,
3739
3570
  C: (f, a) => f(...a)
3740
3571
  });
3741
- };
3742
- this._peer.onicecandidate = async (event) => {
3743
- import_log15.log.debug("peer.onicecandidate", {
3744
- event
3572
+ }
3573
+ }
3574
+ async onSignal(signal) {
3575
+ const connection = this._connection;
3576
+ if (!connection) {
3577
+ import_log12.log.warn("a signal ignored because the connection was closed", {
3578
+ type: signal.payload.data.type
3745
3579
  }, {
3746
- F: __dxlog_file16,
3747
- L: 107,
3580
+ F: __dxlog_file14,
3581
+ L: 271,
3748
3582
  S: this,
3749
3583
  C: (f, a) => f(...a)
3750
3584
  });
3751
- if (event.candidate) {
3752
- try {
3753
- await this._options.sendSignal({
3754
- payload: {
3755
- data: {
3756
- type: "candidate",
3757
- candidate: {
3758
- candidate: event.candidate.candidate,
3759
- // These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
3760
- sdpMLineIndex: event.candidate.sdpMLineIndex ?? 0,
3761
- sdpMid: event.candidate.sdpMid ?? 0
3762
- }
3763
- }
3764
- }
3765
- });
3766
- } catch (err) {
3767
- import_log15.log.info("signaling error", {
3768
- err
3769
- }, {
3770
- F: __dxlog_file16,
3771
- L: 124,
3772
- S: this,
3773
- C: (f, a) => f(...a)
3774
- });
3775
- }
3585
+ return;
3586
+ }
3587
+ const data = signal.payload.data;
3588
+ switch (data.type) {
3589
+ case "offer": {
3590
+ await this._offerProcessingMutex.executeSynchronized(async () => {
3591
+ if (isRemoteDescriptionSet(connection, data)) {
3592
+ return;
3593
+ }
3594
+ if (connection.connectionState !== "new") {
3595
+ this._abortConnection(connection, new Error(`Received an offer in ${connection.connectionState}.`));
3596
+ return;
3597
+ }
3598
+ try {
3599
+ await connection.setRemoteDescription({
3600
+ type: data.type,
3601
+ sdp: data.sdp
3602
+ });
3603
+ const answer = await connection.createAnswer();
3604
+ await connection.setLocalDescription(answer);
3605
+ await this._sendDescription(connection, answer);
3606
+ this._onSessionNegotiated(connection);
3607
+ } catch (err) {
3608
+ this._abortConnection(connection, new Error("Error handling a remote offer.", {
3609
+ cause: err
3610
+ }));
3611
+ }
3612
+ });
3613
+ break;
3776
3614
  }
3777
- };
3778
- if (this._options.initiator) {
3779
- (0, import_invariant13.invariant)(this._peer, "not open", {
3780
- F: __dxlog_file16,
3781
- L: 130,
3782
- S: this,
3783
- A: [
3784
- "this._peer",
3785
- "'not open'"
3786
- ]
3787
- });
3788
- this._peer.createOffer().then(async (offer) => {
3789
- if (this._closed) {
3790
- return;
3791
- }
3792
- if (this._peer?.connectionState !== "connecting") {
3793
- import_log15.log.error("peer not connecting", {
3794
- peer: this._peer
3795
- }, {
3796
- F: __dxlog_file16,
3797
- L: 141,
3798
- S: this,
3799
- C: (f, a) => f(...a)
3800
- });
3801
- this.errors.raise(new Error("invalid state: peer is initiator, but other peer not in state connecting"));
3802
- }
3803
- import_log15.log.debug("creating offer", {
3804
- peer: this._peer,
3805
- offer
3615
+ case "answer":
3616
+ await this._offerProcessingMutex.executeSynchronized(async () => {
3617
+ try {
3618
+ if (isRemoteDescriptionSet(connection, data)) {
3619
+ return;
3620
+ }
3621
+ if (connection.signalingState !== "have-local-offer") {
3622
+ this._abortConnection(connection, new Error(`Unexpected answer from remote peer, signalingState was ${connection.signalingState}.`));
3623
+ return;
3624
+ }
3625
+ await connection.setRemoteDescription({
3626
+ type: data.type,
3627
+ sdp: data.sdp
3628
+ });
3629
+ this._onSessionNegotiated(connection);
3630
+ } catch (err) {
3631
+ this._abortConnection(connection, new Error("Error handling a remote answer.", {
3632
+ cause: err
3633
+ }));
3634
+ }
3635
+ });
3636
+ break;
3637
+ case "candidate":
3638
+ void this._processIceCandidate(connection, data.candidate);
3639
+ break;
3640
+ default:
3641
+ this._abortConnection(connection, new Error(`Unknown signal type ${data.type}.`));
3642
+ break;
3643
+ }
3644
+ (0, import_log12.log)("signal processed", void 0, {
3645
+ F: __dxlog_file14,
3646
+ L: 330,
3647
+ S: this,
3648
+ C: (f, a) => f(...a)
3649
+ });
3650
+ }
3651
+ async _processIceCandidate(connection, candidate) {
3652
+ try {
3653
+ await this._readyForCandidates.wait();
3654
+ if (connection === this._connection) {
3655
+ (0, import_log12.log)("adding ice candidate", {
3656
+ candidate
3806
3657
  }, {
3807
- F: __dxlog_file16,
3808
- L: 145,
3658
+ F: __dxlog_file14,
3659
+ L: 338,
3809
3660
  S: this,
3810
3661
  C: (f, a) => f(...a)
3811
3662
  });
3812
- await this._peer.setLocalDescription(offer);
3813
- await this._options.sendSignal({
3814
- payload: {
3815
- data: {
3816
- type: offer.type,
3817
- sdp: offer.sdp
3818
- }
3819
- }
3820
- });
3821
- }).catch((err) => {
3822
- this.errors.raise(err);
3663
+ await connection.addIceCandidate(candidate);
3664
+ }
3665
+ } catch (err) {
3666
+ import_log12.log.catch(err, void 0, {
3667
+ F: __dxlog_file14,
3668
+ L: 342,
3669
+ S: this,
3670
+ C: (f, a) => f(...a)
3823
3671
  });
3824
- this._handleChannel(this._peer.createDataChannel(DATACHANNEL_LABEL));
3825
- import_log15.log.debug("created data channel", void 0, {
3826
- F: __dxlog_file16,
3827
- L: 155,
3672
+ }
3673
+ }
3674
+ _onSessionNegotiated(connection) {
3675
+ if (connection === this._connection) {
3676
+ (0, import_log12.log)("ready to process ice candidates", void 0, {
3677
+ F: __dxlog_file14,
3678
+ L: 348,
3828
3679
  S: this,
3829
3680
  C: (f, a) => f(...a)
3830
3681
  });
3831
- this._peer.ondatachannel = () => {
3832
- this.errors.raise(new Error("unexpected ondatachannel event for initiator"));
3833
- };
3682
+ this._readyForCandidates.wake();
3834
3683
  } else {
3835
- this._peer.ondatachannel = (event) => {
3836
- import_log15.log.debug("peer.ondatachannel (non-initiator)", {
3837
- event
3838
- }, {
3839
- F: __dxlog_file16,
3840
- L: 161,
3841
- S: this,
3842
- C: (f, a) => f(...a)
3843
- });
3844
- if (event.channel.label !== DATACHANNEL_LABEL) {
3845
- this.errors.raise(new Error(`unexpected channel label ${event.channel.label}`));
3846
- }
3847
- this._handleChannel(event.channel);
3848
- };
3684
+ import_log12.log.warn("session was negotiated after connection became inactive", void 0, {
3685
+ F: __dxlog_file14,
3686
+ L: 351,
3687
+ S: this,
3688
+ C: (f, a) => f(...a)
3689
+ });
3849
3690
  }
3850
- _LibDataChannelTransport._instanceCount++;
3851
3691
  }
3852
- async close() {
3853
- await this._close();
3854
- if (--_LibDataChannelTransport._instanceCount === 0) {
3855
- (await importESM("node-datachannel")).cleanup();
3856
- }
3692
+ _onConnectionCallbackAfterClose(callback, connection) {
3693
+ import_log12.log.warn("callback invoked after a connection was destroyed, this is probably a bug", {
3694
+ callback,
3695
+ state: connection.connectionState
3696
+ }, {
3697
+ F: __dxlog_file14,
3698
+ L: 356,
3699
+ S: this,
3700
+ C: (f, a) => f(...a)
3701
+ });
3702
+ this._safeCloseConnection(connection);
3857
3703
  }
3858
- async _close() {
3859
- if (this._closed) {
3860
- return;
3861
- }
3862
- await this._disconnectStreams();
3704
+ _safeCloseConnection(connection = this._connection) {
3705
+ const resetFields = this._connection && connection === this._connection;
3863
3706
  try {
3864
- this._peer?.close();
3707
+ connection?.close();
3865
3708
  } catch (err) {
3866
- this.errors.raise(err);
3709
+ import_log12.log.catch(err, void 0, {
3710
+ F: __dxlog_file14,
3711
+ L: 368,
3712
+ S: this,
3713
+ C: (f, a) => f(...a)
3714
+ });
3715
+ }
3716
+ if (resetFields) {
3717
+ this._connection = void 0;
3718
+ this._dataChannels.clear();
3719
+ this._readyForCandidates.wake();
3720
+ void this._factory.onConnectionDestroyed().catch((err) => import_log12.log.catch(err, void 0, {
3721
+ F: __dxlog_file14,
3722
+ L: 374,
3723
+ S: this,
3724
+ C: (f, a) => f(...a)
3725
+ }));
3726
+ for (const [_, pendingCallback] of this._channelCreatedCallbacks.entries()) {
3727
+ pendingCallback.reject("Connection closed.");
3728
+ }
3729
+ this._channelCreatedCallbacks.clear();
3867
3730
  }
3868
- this._peer = void 0;
3869
- this._closed = true;
3870
- this.closed.emit();
3871
3731
  }
3872
- /**
3873
- * Handle data channel events.
3874
- */
3875
- _handleChannel(dataChannel) {
3876
- this._channel = dataChannel;
3877
- this._channel.onopen = () => {
3878
- import_log15.log.debug("channel.onopen", void 0, {
3879
- F: __dxlog_file16,
3880
- L: 206,
3732
+ async _loadConnectionConfig() {
3733
+ const config = {
3734
+ ...this._options.webrtcConfig
3735
+ };
3736
+ try {
3737
+ const providedIceServers = await this._options.iceProvider?.getIceServers() ?? [];
3738
+ if (providedIceServers.length > 0) {
3739
+ config.iceServers = [
3740
+ ...config.iceServers ?? [],
3741
+ ...providedIceServers
3742
+ ];
3743
+ }
3744
+ } catch (error) {
3745
+ import_log12.log.catch(error, void 0, {
3746
+ F: __dxlog_file14,
3747
+ L: 390,
3881
3748
  S: this,
3882
3749
  C: (f, a) => f(...a)
3883
3750
  });
3884
- const duplex = new import_stream.Duplex({
3885
- read: () => {
3886
- },
3887
- write: async (chunk, encoding, callback) => {
3888
- if (chunk.length > MAX_MESSAGE_SIZE) {
3889
- this.errors.raise(new Error(`message too large: ${chunk.length} > ${MAX_MESSAGE_SIZE}`));
3890
- }
3891
- try {
3892
- dataChannel.send(chunk);
3893
- } catch (err) {
3894
- this.errors.raise(err);
3895
- await this._close();
3896
- }
3897
- if (this._channel.bufferedAmount > MAX_BUFFERED_AMOUNT) {
3898
- if (this._writeCallback !== null) {
3899
- import_log15.log.error("consumer trying to write before we are ready for more data", void 0, {
3900
- F: __dxlog_file16,
3901
- L: 223,
3902
- S: this,
3903
- C: (f, a) => f(...a)
3904
- });
3751
+ }
3752
+ return config;
3753
+ }
3754
+ async _sendIceCandidate(candidate) {
3755
+ try {
3756
+ await this._options.sendSignal({
3757
+ payload: {
3758
+ data: {
3759
+ type: "candidate",
3760
+ candidate: {
3761
+ candidate: candidate.candidate,
3762
+ // These fields never seem to be not null, but connecting to Chrome doesn't work if they are.
3763
+ sdpMLineIndex: candidate.sdpMLineIndex ?? "0",
3764
+ sdpMid: candidate.sdpMid ?? "0"
3905
3765
  }
3906
- this._writeCallback = callback;
3907
- } else {
3908
- callback();
3909
3766
  }
3910
3767
  }
3911
3768
  });
3912
- duplex.pipe(this._options.stream).pipe(duplex);
3913
- this._stream = duplex;
3914
- this._connected = true;
3915
- this.connected.emit();
3916
- };
3917
- this._channel.onclose = async (err) => {
3918
- import_log15.log.info("channel.onclose", {
3769
+ } catch (err) {
3770
+ import_log12.log.warn("signaling error", {
3919
3771
  err
3920
3772
  }, {
3921
- F: __dxlog_file16,
3922
- L: 239,
3773
+ F: __dxlog_file14,
3774
+ L: 411,
3923
3775
  S: this,
3924
3776
  C: (f, a) => f(...a)
3925
3777
  });
3926
- await this._close();
3778
+ }
3779
+ }
3780
+ async _sendDescription(connection, description) {
3781
+ if (connection !== this._connection) {
3782
+ return;
3783
+ }
3784
+ const data = {
3785
+ type: description.type,
3786
+ sdp: description.sdp
3927
3787
  };
3928
- this._channel.onerror = async (err) => {
3929
- this.errors.raise(new Error("channel error: " + err.toString()));
3930
- await this._close();
3788
+ await this._options.sendSignal({
3789
+ payload: {
3790
+ data
3791
+ }
3792
+ });
3793
+ }
3794
+ get _connectionInfo() {
3795
+ const connectionInfo = this._connection && {
3796
+ connectionState: this._connection.connectionState,
3797
+ iceConnectionState: this._connection.iceConnectionState,
3798
+ iceGatheringState: this._connection.iceGatheringState,
3799
+ signalingState: this._connection.signalingState,
3800
+ remoteDescription: this._connection.remoteDescription,
3801
+ localDescription: this._connection.localDescription
3931
3802
  };
3932
- this._channel.onbufferedamountlow = () => {
3933
- const cb = this._writeCallback;
3934
- this._writeCallback = null;
3935
- cb?.();
3803
+ return {
3804
+ ...connectionInfo,
3805
+ ts: Date.now(),
3806
+ remotePeerKey: this._options.remotePeerKey,
3807
+ channels: [
3808
+ ...this._transportChannels.keys()
3809
+ ].map((topic) => topic),
3810
+ config: this._connection?.getConfiguration()
3936
3811
  };
3937
- this._channel.onmessage = (event) => {
3938
- let data = event.data;
3939
- if (data instanceof ArrayBuffer) {
3940
- data = Buffer.from(data);
3941
- }
3942
- this._stream.push(data);
3812
+ }
3813
+ get _loggerContext() {
3814
+ return {
3815
+ ownPeerKey: this._options.ownPeerKey,
3816
+ remotePeerKey: this._options.remotePeerKey,
3817
+ initiator: this._initiator,
3818
+ channels: this._transportChannels.size
3943
3819
  };
3944
3820
  }
3945
- async onSignal(signal) {
3946
- (0, import_invariant13.invariant)(this._peer, "not open", {
3947
- F: __dxlog_file16,
3948
- L: 265,
3949
- S: this,
3950
- A: [
3951
- "this._peer",
3952
- "'not open'"
3953
- ]
3954
- });
3821
+ };
3822
+ _ts_decorate6([
3823
+ import_async11.synchronized
3824
+ ], RtcPeerConnection.prototype, "_openConnection", null);
3825
+ _ts_decorate6([
3826
+ import_async11.synchronized
3827
+ ], RtcPeerConnection.prototype, "_lockAndAbort", null);
3828
+ _ts_decorate6([
3829
+ import_async11.synchronized
3830
+ ], RtcPeerConnection.prototype, "_lockAndCloseConnection", null);
3831
+ _ts_decorate6([
3832
+ import_async11.synchronized
3833
+ ], RtcPeerConnection.prototype, "onSignal", null);
3834
+ _ts_decorate6([
3835
+ import_tracing.trace.info()
3836
+ ], RtcPeerConnection.prototype, "_connectionInfo", null);
3837
+ _ts_decorate6([
3838
+ import_log12.logInfo
3839
+ ], RtcPeerConnection.prototype, "_loggerContext", null);
3840
+ RtcPeerConnection = _ts_decorate6([
3841
+ import_tracing.trace.resource()
3842
+ ], RtcPeerConnection);
3843
+ var isRemoteDescriptionSet = (connection, data) => {
3844
+ if (!connection.remoteDescription?.type || connection.remoteDescription?.type !== data.type) {
3845
+ return false;
3846
+ }
3847
+ return areSdpEqual(connection.remoteDescription.sdp, data.sdp);
3848
+ };
3849
+ var createIceFailureError = (details) => {
3850
+ const candidateErrors = details.map(({ url, errorCode, errorText }) => `${errorCode} ${url}: ${errorText}`);
3851
+ return new import_protocols7.ConnectivityError(`ICE failed:
3852
+ ${candidateErrors.join("\n")}`);
3853
+ };
3854
+ var createRtcTransportFactory = (webrtcConfig, iceProvider) => {
3855
+ const connectionFactory = getRtcConnectionFactory();
3856
+ return {
3857
+ createTransport: (options) => {
3858
+ const connection = new RtcPeerConnection(connectionFactory, {
3859
+ ownPeerKey: options.ownPeerKey,
3860
+ remotePeerKey: options.remotePeerKey,
3861
+ sendSignal: options.sendSignal,
3862
+ webrtcConfig,
3863
+ iceProvider
3864
+ });
3865
+ return connection.createTransportChannel(options);
3866
+ }
3867
+ };
3868
+ };
3869
+ var __dxlog_file15 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-proxy.ts";
3870
+ var RPC_TIMEOUT = 1e4;
3871
+ var CLOSE_RPC_TIMEOUT = 3e3;
3872
+ var RESP_MIN_THRESHOLD = 500;
3873
+ var RtcTransportProxy = class extends import_context7.Resource {
3874
+ constructor(_options) {
3875
+ super();
3876
+ this._options = _options;
3877
+ this._proxyId = import_keys10.PublicKey.random();
3878
+ this.closed = new import_async13.Event();
3879
+ this.connected = new import_async13.Event();
3880
+ this.errors = new import_debug6.ErrorStream();
3881
+ }
3882
+ async _open() {
3883
+ let stream;
3955
3884
  try {
3956
- const data = signal.payload.data;
3957
- switch (data.type) {
3958
- case "offer": {
3959
- if (this._peer.connectionState !== "new") {
3960
- import_log15.log.error("received offer but peer not in state new", {
3961
- peer: this._peer
3962
- }, {
3963
- F: __dxlog_file16,
3964
- L: 272,
3965
- S: this,
3966
- C: (f, a) => f(...a)
3967
- });
3968
- this.errors.raise(new Error("invalid signalling state: received offer when peer is not in state new"));
3969
- break;
3970
- }
3971
- try {
3972
- await this._peer.setRemoteDescription({
3973
- type: data.type,
3974
- sdp: data.sdp
3975
- });
3976
- const answer = await this._peer.createAnswer();
3977
- await this._peer.setLocalDescription(answer);
3978
- await this._options.sendSignal({
3979
- payload: {
3980
- data: {
3981
- type: answer.type,
3982
- sdp: answer.sdp
3983
- }
3984
- }
3985
- });
3986
- this._readyForCandidates.wake();
3987
- } catch (err) {
3988
- import_log15.log.error("cannot handle offer from signalling server", {
3989
- err
3990
- }, {
3991
- F: __dxlog_file16,
3992
- L: 284,
3993
- S: this,
3994
- C: (f, a) => f(...a)
3995
- });
3996
- this.errors.raise(new Error("error handling offer"));
3997
- }
3998
- break;
3885
+ stream = this._options.bridgeService.open({
3886
+ proxyId: this._proxyId,
3887
+ remotePeerKey: this._options.remotePeerKey,
3888
+ ownPeerKey: this._options.ownPeerKey,
3889
+ topic: this._options.topic,
3890
+ initiator: this._options.initiator ?? false
3891
+ }, {
3892
+ timeout: RPC_TIMEOUT
3893
+ });
3894
+ } catch (error) {
3895
+ this.errors.raise(error);
3896
+ return;
3897
+ }
3898
+ this._serviceStream = stream;
3899
+ stream.waitUntilReady().then(() => {
3900
+ stream.subscribe(async (event) => {
3901
+ (0, import_log14.log)("rtc transport proxy event", event, {
3902
+ F: __dxlog_file15,
3903
+ L: 66,
3904
+ S: this,
3905
+ C: (f, a) => f(...a)
3906
+ });
3907
+ if (event.connection) {
3908
+ await this._handleConnection(event.connection);
3909
+ } else if (event.data) {
3910
+ this._handleData(event.data);
3911
+ } else if (event.signal) {
3912
+ await this._handleSignal(event.signal);
3999
3913
  }
4000
- case "answer":
4001
- try {
4002
- await this._peer.setRemoteDescription({
4003
- type: data.type,
4004
- sdp: data.sdp
4005
- });
4006
- this._readyForCandidates.wake();
4007
- } catch (err) {
4008
- import_log15.log.error("cannot handle answer from signalling server", {
4009
- err
4010
- }, {
4011
- F: __dxlog_file16,
4012
- L: 295,
4013
- S: this,
4014
- C: (f, a) => f(...a)
4015
- });
4016
- this.errors.raise(new Error("error handling answer"));
4017
- }
4018
- break;
4019
- case "candidate":
4020
- await this._readyForCandidates.wait();
4021
- await this._peer.addIceCandidate({
4022
- candidate: data.candidate.candidate
4023
- });
4024
- break;
4025
- default:
4026
- import_log15.log.error("unhandled signal type", {
4027
- type: data.type,
4028
- signal
3914
+ }, (err) => {
3915
+ (0, import_log14.log)("rtc bridge stream closed", {
3916
+ err
3917
+ }, {
3918
+ F: __dxlog_file15,
3919
+ L: 76,
3920
+ S: this,
3921
+ C: (f, a) => f(...a)
3922
+ });
3923
+ if (err) {
3924
+ this._raiseIfOpen(err);
3925
+ } else {
3926
+ void this.close();
3927
+ }
3928
+ });
3929
+ const connectorStream = new import_node_stream3.Writable({
3930
+ write: (chunk, _, callback) => {
3931
+ const sendStartMs = Date.now();
3932
+ this._options.bridgeService.sendData({
3933
+ proxyId: this._proxyId,
3934
+ payload: chunk
4029
3935
  }, {
4030
- F: __dxlog_file16,
4031
- L: 306,
4032
- S: this,
4033
- C: (f, a) => f(...a)
3936
+ timeout: RPC_TIMEOUT
3937
+ }).then(() => {
3938
+ if (Date.now() - sendStartMs > RESP_MIN_THRESHOLD) {
3939
+ (0, import_log14.log)("slow response, delaying callback", void 0, {
3940
+ F: __dxlog_file15,
3941
+ L: 93,
3942
+ S: this,
3943
+ C: (f, a) => f(...a)
3944
+ });
3945
+ (0, import_async13.scheduleTask)(this._ctx, () => callback(), RESP_MIN_THRESHOLD);
3946
+ } else {
3947
+ callback();
3948
+ }
3949
+ }, (err) => {
3950
+ callback();
3951
+ this._raiseIfOpen(err);
4034
3952
  });
4035
- this.errors.raise(new Error(`unhandled signal type ${data.type}`));
3953
+ }
3954
+ });
3955
+ connectorStream.on("error", (err) => {
3956
+ this._raiseIfOpen(err);
3957
+ });
3958
+ this._options.stream.pipe(connectorStream);
3959
+ }, (error) => {
3960
+ if (error) {
3961
+ this._raiseIfOpen(error);
3962
+ } else {
3963
+ void this.close();
4036
3964
  }
3965
+ });
3966
+ }
3967
+ async _close() {
3968
+ try {
3969
+ await this._serviceStream?.close();
3970
+ this._serviceStream = void 0;
4037
3971
  } catch (err) {
4038
- import_log15.log.catch(err, void 0, {
4039
- F: __dxlog_file16,
4040
- L: 310,
3972
+ import_log14.log.catch(err, void 0, {
3973
+ F: __dxlog_file15,
3974
+ L: 128,
3975
+ S: this,
3976
+ C: (f, a) => f(...a)
3977
+ });
3978
+ }
3979
+ try {
3980
+ await this._options.bridgeService.close({
3981
+ proxyId: this._proxyId
3982
+ }, {
3983
+ timeout: CLOSE_RPC_TIMEOUT
3984
+ });
3985
+ } catch (err) {
3986
+ import_log14.log.catch(err, void 0, {
3987
+ F: __dxlog_file15,
3988
+ L: 134,
4041
3989
  S: this,
4042
3990
  C: (f, a) => f(...a)
4043
3991
  });
4044
3992
  }
3993
+ this.closed.emit();
4045
3994
  }
4046
- async getDetails() {
4047
- const stats = await this._getStats();
4048
- const rc = stats?.remoteCandidate;
4049
- if (!rc) {
4050
- return "unavailable";
3995
+ async onSignal(signal) {
3996
+ this._options.bridgeService.sendSignal({
3997
+ proxyId: this._proxyId,
3998
+ signal
3999
+ }, {
4000
+ timeout: RPC_TIMEOUT
4001
+ }).catch((err) => this._raiseIfOpen(decodeError(err)));
4002
+ }
4003
+ async _handleConnection(connectionEvent) {
4004
+ if (connectionEvent.error) {
4005
+ this.errors.raise(decodeError(connectionEvent.error));
4006
+ return;
4007
+ }
4008
+ switch (connectionEvent.state) {
4009
+ case import_bridge.ConnectionState.CONNECTED: {
4010
+ this.connected.emit();
4011
+ break;
4012
+ }
4013
+ case import_bridge.ConnectionState.CLOSED: {
4014
+ await this.close();
4015
+ break;
4016
+ }
4017
+ }
4018
+ }
4019
+ _handleData(dataEvent) {
4020
+ try {
4021
+ this._options.stream.write((0, import_util9.arrayToBuffer)(dataEvent.payload));
4022
+ } catch (error) {
4023
+ this._raiseIfOpen(error);
4024
+ }
4025
+ }
4026
+ async _handleSignal(signalEvent) {
4027
+ try {
4028
+ await this._options.sendSignal(signalEvent.payload);
4029
+ } catch (error) {
4030
+ const type = signalEvent.payload.payload.data?.type;
4031
+ if (type === "offer" || type === "answer") {
4032
+ this._raiseIfOpen(new import_protocols9.ConnectivityError(`Session establishment failed: ${type} couldn't be sent.`));
4033
+ }
4051
4034
  }
4052
- if (rc.candidateType === "relay") {
4053
- return `${rc.ip}:${rc.port} relay for ${rc.relatedAddress}:${rc.relatedPort}`;
4035
+ }
4036
+ async getDetails() {
4037
+ try {
4038
+ const response = await this._options.bridgeService.getDetails({
4039
+ proxyId: this._proxyId
4040
+ }, {
4041
+ timeout: RPC_TIMEOUT
4042
+ });
4043
+ return response.details;
4044
+ } catch (err) {
4045
+ return "bridge-svc unreachable";
4054
4046
  }
4055
- return `${rc.ip}:${rc.port} ${rc.candidateType}`;
4056
4047
  }
4057
4048
  async getStats() {
4058
- const stats = await this._getStats();
4059
- if (!stats) {
4049
+ try {
4050
+ const response = await this._options.bridgeService.getStats({
4051
+ proxyId: this._proxyId
4052
+ }, {
4053
+ timeout: RPC_TIMEOUT
4054
+ });
4055
+ return response.stats;
4056
+ } catch (err) {
4060
4057
  return {
4061
4058
  bytesSent: 0,
4062
4059
  bytesReceived: 0,
4063
4060
  packetsSent: 0,
4064
4061
  packetsReceived: 0,
4065
- rawStats: {}
4062
+ rawStats: "bridge-svc unreachable"
4066
4063
  };
4067
4064
  }
4068
- return {
4069
- bytesSent: stats.transport.bytesSent,
4070
- bytesReceived: stats.transport.bytesReceived,
4071
- packetsSent: 0,
4072
- packetsReceived: 0,
4073
- rawStats: stats.raw
4074
- };
4075
4065
  }
4076
- async _getStats() {
4077
- (0, import_invariant13.invariant)(this._peer, "not open", {
4078
- F: __dxlog_file16,
4079
- L: 350,
4066
+ _raiseIfOpen(error) {
4067
+ if (this.isOpen) {
4068
+ this.errors.raise(error);
4069
+ } else {
4070
+ import_log14.log.info("error swallowed because transport was closed", {
4071
+ message: error.message
4072
+ }, {
4073
+ F: __dxlog_file15,
4074
+ L: 215,
4075
+ S: this,
4076
+ C: (f, a) => f(...a)
4077
+ });
4078
+ }
4079
+ }
4080
+ /**
4081
+ * Called when underlying proxy service becomes unavailable.
4082
+ */
4083
+ forceClose() {
4084
+ void this._serviceStream?.close();
4085
+ this.closed.emit();
4086
+ }
4087
+ };
4088
+ var RtcTransportProxyFactory = class {
4089
+ constructor() {
4090
+ this._connections = /* @__PURE__ */ new Set();
4091
+ }
4092
+ /**
4093
+ * Sets the current BridgeService to be used to open connections.
4094
+ * Calling this method will close any existing connections.
4095
+ */
4096
+ setBridgeService(bridgeService) {
4097
+ this._bridgeService = bridgeService;
4098
+ for (const connection of this._connections) {
4099
+ connection.forceClose();
4100
+ }
4101
+ return this;
4102
+ }
4103
+ createTransport(options) {
4104
+ (0, import_invariant13.invariant)(this._bridgeService, "RtcTransportProxyFactory is not ready to open connections", {
4105
+ F: __dxlog_file15,
4106
+ L: 245,
4080
4107
  S: this,
4081
4108
  A: [
4082
- "this._peer",
4083
- "'not open'"
4109
+ "this._bridgeService",
4110
+ "'RtcTransportProxyFactory is not ready to open connections'"
4084
4111
  ]
4085
4112
  });
4086
- const stats = await this._peer.getStats();
4087
- const statsEntries = Array.from(stats.entries());
4088
- const transport = statsEntries.filter((s) => s[1].type === "transport")[0][1];
4089
- const candidatePair = statsEntries.filter((s) => s[0] === transport.selectedCandidatePairId);
4090
- let selectedCandidatePair;
4091
- let remoteCandidate;
4092
- if (candidatePair.length > 0) {
4093
- selectedCandidatePair = candidatePair[0][1];
4094
- remoteCandidate = statsEntries.filter((s) => s[0] === selectedCandidatePair.remoteCandidateId)[0][1];
4095
- }
4096
- return {
4097
- transport,
4098
- selectedCandidatePair,
4099
- remoteCandidate,
4100
- raw: Object.fromEntries(stats)
4101
- };
4102
- }
4103
- async _disconnectStreams() {
4104
- this._options.stream.unpipe?.(this._stream)?.unpipe?.(this._options.stream);
4113
+ const transport = new RtcTransportProxy({
4114
+ ...options,
4115
+ bridgeService: this._bridgeService
4116
+ });
4117
+ this._connections.add(transport);
4118
+ transport.closed.on(() => this._connections.delete(transport));
4119
+ return transport;
4105
4120
  }
4106
4121
  };
4107
- _ts_decorate7([
4108
- import_async12.synchronized
4109
- ], LibDataChannelTransport.prototype, "_close", null);
4110
- var importESM = Function("path", "return import(path)");
4111
- var __dxlog_file17 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/tcp-transport.ts";
4112
- var TcpTransportFactory = {
4113
- createTransport: (options) => new TcpTransport(options)
4122
+ var decodeError = (err) => {
4123
+ const message = typeof err === "string" ? err : err.message;
4124
+ if (message.includes("CONNECTION_RESET")) {
4125
+ return new import_protocols9.ConnectionResetError(message);
4126
+ } else if (message.includes("TIMEOUT")) {
4127
+ return new import_protocols9.TimeoutError(message);
4128
+ } else if (message.includes("CONNECTIVITY_ERROR")) {
4129
+ return new import_protocols9.ConnectivityError(message);
4130
+ } else {
4131
+ return typeof err === "string" ? new Error(err) : err;
4132
+ }
4114
4133
  };
4115
- var TcpTransport = class {
4116
- constructor(options) {
4117
- this.options = options;
4118
- this._server = void 0;
4119
- this._socket = void 0;
4120
- this._connected = false;
4121
- this._closed = false;
4122
- this.closed = new import_async13.Event();
4123
- this.connected = new import_async13.Event();
4124
- this.errors = new import_debug8.ErrorStream();
4134
+ var __dxlog_file16 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/transport/webrtc/rtc-transport-service.ts";
4135
+ var RtcTransportService = class {
4136
+ constructor(webrtcConfig, iceProvider, _transportFactory = createRtcTransportFactory(webrtcConfig, iceProvider)) {
4137
+ this._transportFactory = _transportFactory;
4138
+ this._openTransports = new import_util10.ComplexMap(import_keys11.PublicKey.hash);
4125
4139
  }
4126
- get isOpen() {
4127
- return this._connected && !this._closed;
4140
+ hasOpenTransports() {
4141
+ return this._openTransports.size > 0;
4128
4142
  }
4129
- async open() {
4130
- (0, import_log16.log)("opening", void 0, {
4131
- F: __dxlog_file17,
4132
- L: 39,
4133
- S: this,
4134
- C: (f, a) => f(...a)
4135
- });
4136
- if (this.options.initiator) {
4137
- setTimeout(async () => {
4138
- const { Server } = await import("node:net");
4139
- this._server = new Server((socket) => {
4140
- (0, import_log16.log)("new connection", void 0, {
4141
- F: __dxlog_file17,
4142
- L: 47,
4143
- S: this,
4144
- C: (f, a) => f(...a)
4145
- });
4146
- if (this._connected) {
4147
- socket.destroy();
4148
- }
4149
- this._handleSocket(socket);
4150
- });
4151
- this._server.on("listening", () => {
4152
- const { port } = this._server.address();
4153
- (0, import_log16.log)("listening", {
4154
- port
4155
- }, {
4156
- F: __dxlog_file17,
4157
- L: 56,
4158
- S: this,
4159
- C: (f, a) => f(...a)
4160
- });
4161
- void this.options.sendSignal({
4162
- payload: {
4163
- port
4143
+ open(request) {
4144
+ const existingTransport = this._openTransports.get(request.proxyId);
4145
+ if (existingTransport) {
4146
+ import_log15.log.error("requesting a new transport bridge for an existing proxy", void 0, {
4147
+ F: __dxlog_file16,
4148
+ L: 53,
4149
+ S: this,
4150
+ C: (f, a) => f(...a)
4151
+ });
4152
+ void this._safeCloseTransport(existingTransport);
4153
+ this._openTransports.delete(request.proxyId);
4154
+ }
4155
+ return new import_codec_protobuf.Stream(({ ready, next, close }) => {
4156
+ const pushNewState = createStateUpdater(next);
4157
+ const transportStream = new import_node_stream4.Duplex({
4158
+ read: () => {
4159
+ const callbacks = [
4160
+ ...transportState.writeProcessedCallbacks
4161
+ ];
4162
+ transportState.writeProcessedCallbacks.length = 0;
4163
+ callbacks.forEach((cb) => cb());
4164
+ },
4165
+ write: function(chunk, _, callback) {
4166
+ next({
4167
+ data: {
4168
+ payload: chunk
4164
4169
  }
4165
- }).catch((err) => {
4166
- if (!this._closed) {
4167
- this.errors.raise(err);
4170
+ });
4171
+ callback();
4172
+ }
4173
+ });
4174
+ const transport = this._transportFactory.createTransport({
4175
+ initiator: request.initiator,
4176
+ topic: request.topic,
4177
+ ownPeerKey: request.ownPeerKey,
4178
+ remotePeerKey: request.remotePeerKey,
4179
+ stream: transportStream,
4180
+ sendSignal: async (signal) => {
4181
+ next({
4182
+ signal: {
4183
+ payload: signal
4168
4184
  }
4169
4185
  });
4170
- });
4171
- this._server.on("error", (err) => {
4172
- this.errors.raise(err);
4173
- });
4174
- this._server.listen(0);
4186
+ }
4175
4187
  });
4176
- }
4188
+ const transportState = {
4189
+ proxyId: request.proxyId,
4190
+ transport,
4191
+ connectorStream: transportStream,
4192
+ writeProcessedCallbacks: []
4193
+ };
4194
+ pushNewState(import_bridge2.ConnectionState.CONNECTING);
4195
+ transport.connected.on(() => pushNewState(import_bridge2.ConnectionState.CONNECTED));
4196
+ transport.errors.handle(async (err) => {
4197
+ pushNewState(import_bridge2.ConnectionState.CLOSED, err);
4198
+ void this._safeCloseTransport(transportState);
4199
+ close(err);
4200
+ });
4201
+ transport.closed.on(async () => {
4202
+ pushNewState(import_bridge2.ConnectionState.CLOSED);
4203
+ void this._safeCloseTransport(transportState);
4204
+ close();
4205
+ });
4206
+ this._openTransports.set(request.proxyId, transportState);
4207
+ transport.open().catch(async (err) => {
4208
+ pushNewState(import_bridge2.ConnectionState.CLOSED, err);
4209
+ void this._safeCloseTransport(transportState);
4210
+ close(err);
4211
+ });
4212
+ ready();
4213
+ });
4177
4214
  }
4178
- async close() {
4179
- (0, import_log16.log)("closing", void 0, {
4180
- F: __dxlog_file17,
4181
- L: 78,
4215
+ async sendSignal({ proxyId, signal }) {
4216
+ const transport = this._openTransports.get(proxyId);
4217
+ (0, import_invariant14.invariant)(transport, void 0, {
4218
+ F: __dxlog_file16,
4219
+ L: 121,
4182
4220
  S: this,
4183
- C: (f, a) => f(...a)
4221
+ A: [
4222
+ "transport",
4223
+ ""
4224
+ ]
4184
4225
  });
4185
- this._socket?.destroy();
4186
- this._server?.close();
4187
- this._closed = true;
4226
+ await transport.transport.onSignal(signal);
4188
4227
  }
4189
- async onSignal({ payload }) {
4190
- (0, import_log16.log)("received signal", {
4191
- payload
4192
- }, {
4193
- F: __dxlog_file17,
4194
- L: 85,
4228
+ async getDetails({ proxyId }) {
4229
+ const transport = this._openTransports.get(proxyId);
4230
+ (0, import_invariant14.invariant)(transport, void 0, {
4231
+ F: __dxlog_file16,
4232
+ L: 128,
4195
4233
  S: this,
4196
- C: (f, a) => f(...a)
4197
- });
4198
- if (this.options.initiator || this._connected) {
4199
- return;
4200
- }
4201
- const socket = new import_node_net.Socket();
4202
- this._handleSocket(socket);
4203
- socket.connect({
4204
- port: payload.port,
4205
- host: "localhost"
4234
+ A: [
4235
+ "transport",
4236
+ ""
4237
+ ]
4206
4238
  });
4239
+ return {
4240
+ details: await transport.transport.getDetails()
4241
+ };
4207
4242
  }
4208
- async getDetails() {
4209
- if (this.options.initiator) {
4210
- const { port: port2, address: address2 } = this._server?.address();
4211
- return `LISTEN ${address2}:${port2}`;
4212
- }
4213
- const { port, address } = this._socket?.address();
4214
- return `ACCEPT ${address}:${port}`;
4215
- }
4216
- async getStats() {
4243
+ async getStats({ proxyId }) {
4244
+ const transport = this._openTransports.get(proxyId);
4245
+ (0, import_invariant14.invariant)(transport, void 0, {
4246
+ F: __dxlog_file16,
4247
+ L: 135,
4248
+ S: this,
4249
+ A: [
4250
+ "transport",
4251
+ ""
4252
+ ]
4253
+ });
4217
4254
  return {
4218
- bytesSent: 0,
4219
- bytesReceived: 0,
4220
- packetsSent: 0,
4221
- packetsReceived: 0
4255
+ stats: await transport.transport.getStats()
4222
4256
  };
4223
4257
  }
4224
- _handleSocket(socket) {
4225
- (0, import_log16.log)("handling socket", {
4226
- remotePort: socket.remotePort,
4227
- localPort: socket.localPort
4228
- }, {
4229
- F: __dxlog_file17,
4230
- L: 115,
4258
+ async sendData({ proxyId, payload }) {
4259
+ const transport = this._openTransports.get(proxyId);
4260
+ (0, import_invariant14.invariant)(transport, void 0, {
4261
+ F: __dxlog_file16,
4262
+ L: 142,
4231
4263
  S: this,
4232
- C: (f, a) => f(...a)
4264
+ A: [
4265
+ "transport",
4266
+ ""
4267
+ ]
4233
4268
  });
4234
- this._socket = socket;
4235
- this._socket.on("connect", () => {
4236
- (0, import_log16.log)("connected to", {
4237
- port: this._socket?.remotePort
4269
+ const bufferHasSpace = transport.connectorStream.push(payload);
4270
+ if (!bufferHasSpace) {
4271
+ await new Promise((resolve) => {
4272
+ transport.writeProcessedCallbacks.push(resolve);
4273
+ });
4274
+ }
4275
+ }
4276
+ async close({ proxyId }) {
4277
+ const transport = this._openTransports.get(proxyId);
4278
+ if (!transport) {
4279
+ return;
4280
+ }
4281
+ this._openTransports.delete(proxyId);
4282
+ await this._safeCloseTransport(transport);
4283
+ }
4284
+ async _safeCloseTransport(transport) {
4285
+ if (this._openTransports.get(transport.proxyId) === transport) {
4286
+ this._openTransports.delete(transport.proxyId);
4287
+ }
4288
+ transport.writeProcessedCallbacks.forEach((cb) => cb());
4289
+ try {
4290
+ await transport.transport.close();
4291
+ } catch (error) {
4292
+ import_log15.log.warn("transport close error", {
4293
+ message: error?.message
4238
4294
  }, {
4239
- F: __dxlog_file17,
4240
- L: 119,
4295
+ F: __dxlog_file16,
4296
+ L: 172,
4241
4297
  S: this,
4242
4298
  C: (f, a) => f(...a)
4243
4299
  });
4244
- this._connected = true;
4245
- });
4246
- this._socket.on("error", (err) => {
4247
- this.errors.raise(err);
4248
- });
4249
- this._socket.on("close", () => {
4250
- this.closed.emit();
4300
+ }
4301
+ try {
4302
+ transport.connectorStream.end();
4303
+ } catch (error) {
4304
+ import_log15.log.warn("connectorStream close error", {
4305
+ message: error?.message
4306
+ }, {
4307
+ F: __dxlog_file16,
4308
+ L: 177,
4309
+ S: this,
4310
+ C: (f, a) => f(...a)
4311
+ });
4312
+ }
4313
+ (0, import_log15.log)("closed", void 0, {
4314
+ F: __dxlog_file16,
4315
+ L: 179,
4316
+ S: this,
4317
+ C: (f, a) => f(...a)
4251
4318
  });
4252
- this.connected.emit();
4253
- this.options.stream.pipe(this._socket).pipe(this.options.stream);
4254
4319
  }
4255
4320
  };
4321
+ var createStateUpdater = (next) => {
4322
+ return (state, err) => {
4323
+ next({
4324
+ connection: {
4325
+ state,
4326
+ ...err ? {
4327
+ error: err.message
4328
+ } : void 0
4329
+ }
4330
+ });
4331
+ };
4332
+ };
4256
4333
  var createTeleportProtocolFactory = (onConnection, defaultParams) => {
4257
4334
  return (params) => {
4258
4335
  const teleport = new import_teleport.Teleport({
@@ -4282,26 +4359,21 @@ var createTeleportProtocolFactory = (onConnection, defaultParams) => {
4282
4359
  ConnectionState,
4283
4360
  EventType,
4284
4361
  FullyConnectedTopology,
4285
- LibDataChannelTransport,
4286
4362
  MAX_CONCURRENT_INITIATING_CONNECTIONS,
4287
4363
  MMSTTopology,
4288
4364
  MemoryTransport,
4289
4365
  MemoryTransportFactory,
4290
- SimplePeerTransport,
4291
- SimplePeerTransportProxy,
4292
- SimplePeerTransportProxyFactory,
4293
- SimplePeerTransportService,
4366
+ RtcTransportProxy,
4367
+ RtcTransportProxyFactory,
4368
+ RtcTransportService,
4294
4369
  StarTopology,
4295
4370
  Swarm,
4296
4371
  SwarmMapper,
4297
4372
  SwarmMessenger,
4298
4373
  SwarmNetworkManager,
4299
- TcpTransport,
4300
- TcpTransportFactory,
4301
4374
  TransportKind,
4302
4375
  createIceProvider,
4303
- createLibDataChannelTransportFactory,
4304
- createSimplePeerTransportFactory,
4376
+ createRtcTransportFactory,
4305
4377
  createTeleportProtocolFactory
4306
4378
  });
4307
- //# sourceMappingURL=chunk-4YAYC7WN.cjs.map
4379
+ //# sourceMappingURL=chunk-MCPADZS5.cjs.map