@dxos/network-manager 0.6.13 → 0.6.14-main.69511f5

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