@dxos/network-manager 0.6.13-main.ed424a1 → 0.6.13

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