@dxos/network-manager 0.6.13 → 0.6.14-main.2b6a0f3

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 (164) hide show
  1. package/dist/lib/browser/chunk-GW3YM55A.mjs +14 -0
  2. package/dist/lib/browser/chunk-GW3YM55A.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-XYSYUN63.mjs → chunk-V3IRGRVX.mjs} +1501 -1655
  4. package/dist/lib/browser/chunk-V3IRGRVX.mjs.map +7 -0
  5. package/dist/lib/browser/index.mjs +347 -22
  6. package/dist/lib/browser/index.mjs.map +4 -4
  7. package/dist/lib/browser/meta.json +1 -1
  8. package/dist/lib/browser/testing/index.mjs +22 -32
  9. package/dist/lib/browser/testing/index.mjs.map +3 -3
  10. package/dist/lib/browser/transport/tcp/index.mjs +39 -0
  11. package/dist/lib/browser/transport/tcp/index.mjs.map +7 -0
  12. package/dist/lib/node/{chunk-4YAYC7WN.cjs → chunk-4TTFBX3M.cjs} +1504 -1782
  13. package/dist/lib/node/chunk-4TTFBX3M.cjs.map +7 -0
  14. package/dist/lib/node/index.cjs +356 -37
  15. package/dist/lib/node/index.cjs.map +4 -4
  16. package/dist/lib/node/meta.json +1 -1
  17. package/dist/lib/node/testing/index.cjs +24 -34
  18. package/dist/lib/node/testing/index.cjs.map +3 -3
  19. package/dist/lib/node/transport/tcp/index.cjs +191 -0
  20. package/dist/lib/node/transport/tcp/index.cjs.map +7 -0
  21. package/dist/lib/node-esm/chunk-6MN5JVRP.mjs +4035 -0
  22. package/dist/lib/node-esm/chunk-6MN5JVRP.mjs.map +7 -0
  23. package/dist/lib/node-esm/index.mjs +382 -0
  24. package/dist/lib/node-esm/index.mjs.map +7 -0
  25. package/dist/lib/node-esm/meta.json +1 -0
  26. package/dist/lib/node-esm/testing/index.mjs +279 -0
  27. package/dist/lib/node-esm/testing/index.mjs.map +7 -0
  28. package/dist/lib/node-esm/transport/tcp/index.mjs +159 -0
  29. package/dist/lib/node-esm/transport/tcp/index.mjs.map +7 -0
  30. package/dist/types/src/network-manager.d.ts +2 -1
  31. package/dist/types/src/network-manager.d.ts.map +1 -1
  32. package/dist/types/src/signal/ice.d.ts.map +1 -1
  33. package/dist/types/src/signal/integration.node.test.d.ts +2 -0
  34. package/dist/types/src/signal/integration.node.test.d.ts.map +1 -0
  35. package/dist/types/src/signal/swarm-messenger.node.test.d.ts +2 -0
  36. package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +1 -0
  37. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  38. package/dist/types/src/swarm/swarm.d.ts +1 -1
  39. package/dist/types/src/testing/test-builder.d.ts +2 -2
  40. package/dist/types/src/testing/test-builder.d.ts.map +1 -1
  41. package/dist/types/src/testing/test-wire-protocol.d.ts +1 -2
  42. package/dist/types/src/testing/test-wire-protocol.d.ts.map +1 -1
  43. package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
  44. package/dist/types/src/tests/property-test-suite.d.ts.map +1 -1
  45. package/dist/types/src/tests/tcp-transport.node.test.d.ts +2 -0
  46. package/dist/types/src/tests/tcp-transport.node.test.d.ts.map +1 -0
  47. package/dist/types/src/tests/utils.d.ts.map +1 -1
  48. package/dist/types/src/transport/index.d.ts +1 -5
  49. package/dist/types/src/transport/index.d.ts.map +1 -1
  50. package/dist/types/src/transport/memory-transport.d.ts +2 -2
  51. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  52. package/dist/types/src/transport/tcp/index.d.ts +2 -0
  53. package/dist/types/src/transport/tcp/index.d.ts.map +1 -0
  54. package/dist/types/src/transport/{tcp-transport.browser.d.ts → tcp/tcp-transport.browser.d.ts} +3 -3
  55. package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +1 -0
  56. package/dist/types/src/transport/{tcp-transport.d.ts → tcp/tcp-transport.d.ts} +3 -3
  57. package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +1 -0
  58. package/dist/types/src/transport/transport.d.ts +7 -6
  59. package/dist/types/src/transport/transport.d.ts.map +1 -1
  60. package/dist/types/src/transport/webrtc/index.d.ts +4 -0
  61. package/dist/types/src/transport/webrtc/index.d.ts.map +1 -0
  62. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +14 -0
  63. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +1 -0
  64. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +68 -0
  65. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +1 -0
  66. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +33 -0
  67. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +1 -0
  68. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +2 -0
  69. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +1 -0
  70. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +4 -0
  71. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +1 -0
  72. package/dist/types/src/transport/{simplepeer-transport-proxy.d.ts → webrtc/rtc-transport-proxy.d.ts} +10 -12
  73. package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +1 -0
  74. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +2 -0
  75. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +1 -0
  76. package/dist/types/src/transport/{simplepeer-transport-service.d.ts → webrtc/rtc-transport-service.d.ts} +9 -7
  77. package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +1 -0
  78. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +4 -0
  79. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +1 -0
  80. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +2 -0
  81. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +1 -0
  82. package/dist/types/src/transport/webrtc/test-utils.d.ts +5 -0
  83. package/dist/types/src/transport/webrtc/test-utils.d.ts.map +1 -0
  84. package/dist/types/src/transport/webrtc/utils.d.ts +3 -0
  85. package/dist/types/src/transport/webrtc/utils.d.ts.map +1 -0
  86. package/package.json +56 -30
  87. package/src/network-manager.ts +5 -13
  88. package/src/signal/ice.test.ts +1 -3
  89. package/src/signal/ice.ts +6 -1
  90. package/src/signal/{integration.test.ts → integration.node.test.ts} +9 -15
  91. package/src/signal/{swarm-messenger.test.ts → swarm-messenger.node.test.ts} +13 -23
  92. package/src/swarm/connection-limiter.test.ts +3 -6
  93. package/src/swarm/connection.test.ts +63 -38
  94. package/src/swarm/connection.ts +5 -5
  95. package/src/swarm/swarm.test.ts +10 -12
  96. package/src/swarm/swarm.ts +1 -1
  97. package/src/testing/test-builder.ts +13 -29
  98. package/src/testing/test-wire-protocol.ts +1 -4
  99. package/src/tests/basic-test-suite.ts +34 -33
  100. package/src/tests/memory-transport.test.ts +40 -42
  101. package/src/tests/property-test-suite.ts +21 -22
  102. package/src/tests/tcp-transport.node.test.ts +65 -0
  103. package/src/tests/utils.ts +3 -2
  104. package/src/tests/webrtc-transport.test.ts +9 -9
  105. package/src/transport/index.ts +1 -5
  106. package/src/transport/memory-transport.ts +2 -0
  107. package/src/transport/tcp/index.ts +5 -0
  108. package/src/transport/{tcp-transport.browser.ts → tcp/tcp-transport.browser.ts} +7 -3
  109. package/src/transport/{tcp-transport.ts → tcp/tcp-transport.ts} +3 -1
  110. package/src/transport/transport.ts +8 -7
  111. package/src/transport/webrtc/index.ts +7 -0
  112. package/src/transport/webrtc/rtc-connection-factory.ts +82 -0
  113. package/src/transport/webrtc/rtc-peer-connection.ts +472 -0
  114. package/src/transport/webrtc/rtc-transport-channel.test.ts +176 -0
  115. package/src/transport/webrtc/rtc-transport-channel.ts +195 -0
  116. package/src/transport/webrtc/rtc-transport-factory.ts +28 -0
  117. package/src/transport/webrtc/rtc-transport-proxy.test.ts +413 -0
  118. package/src/transport/webrtc/rtc-transport-proxy.ts +264 -0
  119. package/src/transport/webrtc/rtc-transport-service.ts +192 -0
  120. package/src/transport/webrtc/rtc-transport-stats.ts +67 -0
  121. package/src/transport/webrtc/rtc-transport.test.ts +198 -0
  122. package/src/transport/webrtc/test-utils.ts +22 -0
  123. package/src/transport/webrtc/utils.ts +36 -0
  124. package/src/typings.d.ts +8 -2
  125. package/dist/lib/browser/chunk-XYSYUN63.mjs.map +0 -7
  126. package/dist/lib/node/chunk-4YAYC7WN.cjs.map +0 -7
  127. package/dist/types/src/signal/integration.test.d.ts +0 -2
  128. package/dist/types/src/signal/integration.test.d.ts.map +0 -1
  129. package/dist/types/src/signal/swarm-messenger.test.d.ts +0 -2
  130. package/dist/types/src/signal/swarm-messenger.test.d.ts.map +0 -1
  131. package/dist/types/src/tests/tcp-transport.test.d.ts +0 -2
  132. package/dist/types/src/tests/tcp-transport.test.d.ts.map +0 -1
  133. package/dist/types/src/transport/libdatachannel-transport.d.ts +0 -42
  134. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +0 -1
  135. package/dist/types/src/transport/libdatachannel-transport.test.d.ts +0 -2
  136. package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +0 -1
  137. package/dist/types/src/transport/memory-transport.test.d.ts +0 -2
  138. package/dist/types/src/transport/memory-transport.test.d.ts.map +0 -1
  139. package/dist/types/src/transport/simplepeer-simple-peer.d.ts +0 -2
  140. package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +0 -1
  141. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +0 -2
  142. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +0 -1
  143. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +0 -1
  144. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +0 -1
  145. package/dist/types/src/transport/simplepeer-transport.d.ts +0 -36
  146. package/dist/types/src/transport/simplepeer-transport.d.ts.map +0 -1
  147. package/dist/types/src/transport/simplepeer-transport.test.d.ts +0 -2
  148. package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +0 -1
  149. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +0 -1
  150. package/dist/types/src/transport/tcp-transport.d.ts.map +0 -1
  151. package/dist/types/src/transport/webrtc.d.ts +0 -6
  152. package/dist/types/src/transport/webrtc.d.ts.map +0 -1
  153. package/src/globals.d.ts +0 -7
  154. package/src/tests/tcp-transport.test.ts +0 -67
  155. package/src/transport/libdatachannel-transport.test.ts +0 -100
  156. package/src/transport/libdatachannel-transport.ts +0 -376
  157. package/src/transport/memory-transport.test.ts +0 -74
  158. package/src/transport/simplepeer-simple-peer.ts +0 -26
  159. package/src/transport/simplepeer-transport-proxy-test.ts +0 -181
  160. package/src/transport/simplepeer-transport-proxy.ts +0 -246
  161. package/src/transport/simplepeer-transport-service.ts +0 -160
  162. package/src/transport/simplepeer-transport.test.ts +0 -61
  163. package/src/transport/simplepeer-transport.ts +0 -250
  164. package/src/transport/webrtc.ts +0 -15
@@ -6,28 +6,358 @@ import {
6
6
  ConnectionState,
7
7
  EventType,
8
8
  FullyConnectedTopology,
9
- LibDataChannelTransport,
10
9
  MAX_CONCURRENT_INITIATING_CONNECTIONS,
11
- MMSTTopology,
12
10
  MemoryTransport,
13
11
  MemoryTransportFactory,
14
- SimplePeerTransport,
15
- SimplePeerTransportProxy,
16
- SimplePeerTransportProxyFactory,
17
- SimplePeerTransportService,
18
- StarTopology,
12
+ RtcTransportProxy,
13
+ RtcTransportProxyFactory,
14
+ RtcTransportService,
19
15
  Swarm,
20
16
  SwarmMapper,
21
17
  SwarmMessenger,
22
18
  SwarmNetworkManager,
23
- TcpTransport,
24
- TcpTransportFactory,
25
19
  TransportKind,
26
- createIceProvider,
27
- createLibDataChannelTransportFactory,
28
- createSimplePeerTransportFactory,
20
+ createRtcTransportFactory,
29
21
  createTeleportProtocolFactory
30
- } from "./chunk-XYSYUN63.mjs";
22
+ } from "./chunk-V3IRGRVX.mjs";
23
+ import {
24
+ Buffer
25
+ } from "./chunk-GW3YM55A.mjs";
26
+
27
+ // packages/core/mesh/network-manager/src/signal/ice.ts
28
+ import { asyncTimeout } from "@dxos/async";
29
+ import { log } from "@dxos/log";
30
+ import { isNotNullOrUndefined } from "@dxos/util";
31
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/signal/ice.ts";
32
+ var createIceProvider = (iceProviders) => {
33
+ let cachedIceServers;
34
+ return {
35
+ getIceServers: async () => {
36
+ if (cachedIceServers) {
37
+ return cachedIceServers;
38
+ }
39
+ cachedIceServers = (await Promise.all(iceProviders.map(({ urls }) => asyncTimeout(fetch(urls, {
40
+ method: "GET"
41
+ }), 1e4).then((response) => response.json()).catch((err) => {
42
+ const isDev = typeof window !== "undefined" && window.location.href.includes("localhost");
43
+ if (!isDev) {
44
+ log.error("Failed to fetch ICE servers from provider", {
45
+ urls,
46
+ err
47
+ }, {
48
+ F: __dxlog_file,
49
+ L: 30,
50
+ S: void 0,
51
+ C: (f, a) => f(...a)
52
+ });
53
+ }
54
+ })))).filter(isNotNullOrUndefined).map(({ iceServers }) => iceServers).flat();
55
+ return cachedIceServers;
56
+ }
57
+ };
58
+ };
59
+
60
+ // packages/core/mesh/network-manager/src/topology/mmst-topology.ts
61
+ import { invariant } from "@dxos/invariant";
62
+ import { log as log2 } from "@dxos/log";
63
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/mmst-topology.ts";
64
+ var MIN_UPDATE_INTERVAL = 1e3 * 10;
65
+ var MAX_CHANGES_PER_UPDATE = 1;
66
+ var MMSTTopology = class {
67
+ constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 } = {}) {
68
+ this._sampleCollected = false;
69
+ this._lastAction = /* @__PURE__ */ new Date(0);
70
+ this._originateConnections = originateConnections;
71
+ this._maxPeers = maxPeers;
72
+ this._sampleSize = sampleSize;
73
+ }
74
+ init(controller) {
75
+ invariant(!this._controller, "Already initialized", {
76
+ F: __dxlog_file2,
77
+ L: 49,
78
+ S: this,
79
+ A: [
80
+ "!this._controller",
81
+ "'Already initialized'"
82
+ ]
83
+ });
84
+ this._controller = controller;
85
+ }
86
+ update() {
87
+ invariant(this._controller, "Not initialized", {
88
+ F: __dxlog_file2,
89
+ L: 54,
90
+ S: this,
91
+ A: [
92
+ "this._controller",
93
+ "'Not initialized'"
94
+ ]
95
+ });
96
+ const { connected, candidates } = this._controller.getState();
97
+ if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {
98
+ log2("Running the algorithm.", void 0, {
99
+ F: __dxlog_file2,
100
+ L: 58,
101
+ S: this,
102
+ C: (f, a) => f(...a)
103
+ });
104
+ this._sampleCollected = true;
105
+ this._runAlgorithm();
106
+ }
107
+ }
108
+ forceUpdate() {
109
+ this._lastAction = /* @__PURE__ */ new Date(0);
110
+ this.update();
111
+ }
112
+ async onOffer(peer) {
113
+ invariant(this._controller, "Not initialized", {
114
+ F: __dxlog_file2,
115
+ L: 70,
116
+ S: this,
117
+ A: [
118
+ "this._controller",
119
+ "'Not initialized'"
120
+ ]
121
+ });
122
+ const { connected } = this._controller.getState();
123
+ const accept = connected.length < this._maxPeers;
124
+ log2(`Offer ${peer} accept=${accept}`, void 0, {
125
+ F: __dxlog_file2,
126
+ L: 73,
127
+ S: this,
128
+ C: (f, a) => f(...a)
129
+ });
130
+ return accept;
131
+ }
132
+ async destroy() {
133
+ }
134
+ _runAlgorithm() {
135
+ invariant(this._controller, "Not initialized", {
136
+ F: __dxlog_file2,
137
+ L: 82,
138
+ S: this,
139
+ A: [
140
+ "this._controller",
141
+ "'Not initialized'"
142
+ ]
143
+ });
144
+ const { connected, candidates, ownPeerId } = this._controller.getState();
145
+ if (connected.length > this._maxPeers) {
146
+ log2(`disconnect ${connected.length - this._maxPeers} peers.`, void 0, {
147
+ F: __dxlog_file2,
148
+ L: 88,
149
+ S: this,
150
+ C: (f, a) => f(...a)
151
+ });
152
+ const sorted = sortByXorDistance(connected, ownPeerId).reverse().slice(0, this._maxPeers - connected.length);
153
+ invariant(sorted.length === 0, void 0, {
154
+ F: __dxlog_file2,
155
+ L: 92,
156
+ S: this,
157
+ A: [
158
+ "sorted.length === 0",
159
+ ""
160
+ ]
161
+ });
162
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
163
+ log2(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
164
+ F: __dxlog_file2,
165
+ L: 95,
166
+ S: this,
167
+ C: (f, a) => f(...a)
168
+ });
169
+ }
170
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
171
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
172
+ log2(`Disconnect ${peer}.`, void 0, {
173
+ F: __dxlog_file2,
174
+ L: 100,
175
+ S: this,
176
+ C: (f, a) => f(...a)
177
+ });
178
+ this._controller.disconnect(peer);
179
+ }
180
+ this._lastAction = /* @__PURE__ */ new Date();
181
+ } else {
182
+ log2("rate limited disconnect", void 0, {
183
+ F: __dxlog_file2,
184
+ L: 105,
185
+ S: this,
186
+ C: (f, a) => f(...a)
187
+ });
188
+ }
189
+ } else if (connected.length < this._originateConnections) {
190
+ log2(`connect ${this._originateConnections - connected.length} peers.`, void 0, {
191
+ F: __dxlog_file2,
192
+ L: 109,
193
+ S: this,
194
+ C: (f, a) => f(...a)
195
+ });
196
+ const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);
197
+ const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);
198
+ if (sorted.length > MAX_CHANGES_PER_UPDATE) {
199
+ log2(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`, void 0, {
200
+ F: __dxlog_file2,
201
+ L: 114,
202
+ S: this,
203
+ C: (f, a) => f(...a)
204
+ });
205
+ }
206
+ if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {
207
+ for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {
208
+ log2(`Connect ${peer}.`, void 0, {
209
+ F: __dxlog_file2,
210
+ L: 118,
211
+ S: this,
212
+ C: (f, a) => f(...a)
213
+ });
214
+ this._controller.connect(peer);
215
+ }
216
+ this._lastAction = /* @__PURE__ */ new Date();
217
+ } else {
218
+ log2("rate limited connect", void 0, {
219
+ F: __dxlog_file2,
220
+ L: 123,
221
+ S: this,
222
+ C: (f, a) => f(...a)
223
+ });
224
+ }
225
+ }
226
+ }
227
+ toString() {
228
+ return "MMSTTopology";
229
+ }
230
+ };
231
+ var sortByXorDistance = (keys, reference) => {
232
+ const sorted = keys.sort((a, b) => {
233
+ return compareXor(distXor(a.asBuffer(), reference.asBuffer()), distXor(b.asBuffer(), reference.asBuffer()));
234
+ });
235
+ log2("Sorted keys", {
236
+ keys,
237
+ reference,
238
+ sorted
239
+ }, {
240
+ F: __dxlog_file2,
241
+ L: 137,
242
+ S: void 0,
243
+ C: (f, a) => f(...a)
244
+ });
245
+ return sorted;
246
+ };
247
+ var distXor = (a, b) => {
248
+ const maxLength = Math.max(a.length, b.length);
249
+ const result = Buffer.allocUnsafe(maxLength);
250
+ for (let i = 0; i < maxLength; i++) {
251
+ result[i] = (a[i] || 0) ^ (b[i] || 0);
252
+ }
253
+ return result;
254
+ };
255
+ var compareXor = (a, b) => {
256
+ const maxLength = Math.max(a.length, b.length);
257
+ for (let i = 0; i < maxLength; i++) {
258
+ if ((a[i] || 0) === (b[i] || 0)) {
259
+ continue;
260
+ }
261
+ return (a[i] || 0) < (b[i] || 0) ? -1 : 1;
262
+ }
263
+ return 0;
264
+ };
265
+
266
+ // packages/core/mesh/network-manager/src/topology/star-topology.ts
267
+ import { invariant as invariant2 } from "@dxos/invariant";
268
+ import { log as log3 } from "@dxos/log";
269
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/core/mesh/network-manager/src/topology/star-topology.ts";
270
+ var StarTopology = class {
271
+ constructor(_centralPeer) {
272
+ this._centralPeer = _centralPeer;
273
+ }
274
+ toString() {
275
+ return `StarTopology(${this._centralPeer.truncate()})`;
276
+ }
277
+ init(controller) {
278
+ invariant2(!this._controller, "Already initialized.", {
279
+ F: __dxlog_file3,
280
+ L: 21,
281
+ S: this,
282
+ A: [
283
+ "!this._controller",
284
+ "'Already initialized.'"
285
+ ]
286
+ });
287
+ this._controller = controller;
288
+ }
289
+ update() {
290
+ invariant2(this._controller, "Not initialized.", {
291
+ F: __dxlog_file3,
292
+ L: 26,
293
+ S: this,
294
+ A: [
295
+ "this._controller",
296
+ "'Not initialized.'"
297
+ ]
298
+ });
299
+ const { candidates, connected, ownPeerId } = this._controller.getState();
300
+ if (!ownPeerId.equals(this._centralPeer)) {
301
+ log3("leaf peer dropping all connections apart from central peer.", void 0, {
302
+ F: __dxlog_file3,
303
+ L: 29,
304
+ S: this,
305
+ C: (f, a) => f(...a)
306
+ });
307
+ for (const peer of connected) {
308
+ if (!peer.equals(this._centralPeer)) {
309
+ log3("dropping connection", {
310
+ peer
311
+ }, {
312
+ F: __dxlog_file3,
313
+ L: 34,
314
+ S: this,
315
+ C: (f, a) => f(...a)
316
+ });
317
+ this._controller.disconnect(peer);
318
+ }
319
+ }
320
+ }
321
+ for (const peer of candidates) {
322
+ if (peer.equals(this._centralPeer) || ownPeerId.equals(this._centralPeer)) {
323
+ log3("connecting to peer", {
324
+ peer
325
+ }, {
326
+ F: __dxlog_file3,
327
+ L: 43,
328
+ S: this,
329
+ C: (f, a) => f(...a)
330
+ });
331
+ this._controller.connect(peer);
332
+ }
333
+ }
334
+ }
335
+ async onOffer(peer) {
336
+ invariant2(this._controller, "Not initialized.", {
337
+ F: __dxlog_file3,
338
+ L: 50,
339
+ S: this,
340
+ A: [
341
+ "this._controller",
342
+ "'Not initialized.'"
343
+ ]
344
+ });
345
+ const { ownPeerId } = this._controller.getState();
346
+ log3("offer", {
347
+ peer,
348
+ isCentral: peer.equals(this._centralPeer),
349
+ isSelfCentral: ownPeerId.equals(this._centralPeer)
350
+ }, {
351
+ F: __dxlog_file3,
352
+ L: 52,
353
+ S: this,
354
+ C: (f, a) => f(...a)
355
+ });
356
+ return ownPeerId.equals(this._centralPeer) || peer.equals(this._centralPeer);
357
+ }
358
+ async destroy() {
359
+ }
360
+ };
31
361
  export {
32
362
  Connection,
33
363
  ConnectionLimiter,
@@ -35,26 +365,21 @@ export {
35
365
  ConnectionState,
36
366
  EventType,
37
367
  FullyConnectedTopology,
38
- LibDataChannelTransport,
39
368
  MAX_CONCURRENT_INITIATING_CONNECTIONS,
40
369
  MMSTTopology,
41
370
  MemoryTransport,
42
371
  MemoryTransportFactory,
43
- SimplePeerTransport,
44
- SimplePeerTransportProxy,
45
- SimplePeerTransportProxyFactory,
46
- SimplePeerTransportService,
372
+ RtcTransportProxy,
373
+ RtcTransportProxyFactory,
374
+ RtcTransportService,
47
375
  StarTopology,
48
376
  Swarm,
49
377
  SwarmMapper,
50
378
  SwarmMessenger,
51
379
  SwarmNetworkManager,
52
- TcpTransport,
53
- TcpTransportFactory,
54
380
  TransportKind,
55
381
  createIceProvider,
56
- createLibDataChannelTransportFactory,
57
- createSimplePeerTransportFactory,
382
+ createRtcTransportFactory,
58
383
  createTeleportProtocolFactory
59
384
  };
60
385
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": [],
4
- "sourcesContent": [],
5
- "mappings": "",
6
- "names": []
3
+ "sources": ["../../../src/signal/ice.ts", "../../../src/topology/mmst-topology.ts", "../../../src/topology/star-topology.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { asyncTimeout } from '@dxos/async';\nimport { log } from '@dxos/log';\nimport { type Runtime } from '@dxos/protocols/proto/dxos/config';\nimport { isNotNullOrUndefined } from '@dxos/util';\n\nexport interface IceProvider {\n getIceServers: () => Promise<RTCIceServer[]>;\n}\n\nexport const createIceProvider = (iceProviders: Runtime.Services.IceProvider[]): IceProvider => {\n let cachedIceServers: RTCIceServer[];\n return {\n getIceServers: async () => {\n if (cachedIceServers) {\n return cachedIceServers;\n }\n\n cachedIceServers = (\n await Promise.all(\n iceProviders.map(({ urls }) =>\n asyncTimeout(fetch(urls, { method: 'GET' }), 10_000)\n .then((response) => response.json())\n .catch((err) => {\n const isDev = typeof window !== 'undefined' && window.location.href.includes('localhost');\n if (!isDev) {\n log.error('Failed to fetch ICE servers from provider', { urls, err });\n }\n }),\n ),\n )\n )\n .filter(isNotNullOrUndefined)\n .map(({ iceServers }: { iceServers: RTCIceServer[] }) => iceServers)\n .flat();\n\n return cachedIceServers;\n },\n };\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SwarmController, type Topology } from './topology';\n\nconst MIN_UPDATE_INTERVAL = 1000 * 10;\nconst MAX_CHANGES_PER_UPDATE = 1;\n\nexport interface MMSTTopologyOptions {\n /**\n * Number of connections the peer will originate by itself.\n */\n originateConnections?: number;\n\n /**\n * Maximum number of connections allowed, all other connections will be dropped.\n */\n maxPeers?: number;\n\n /**\n * Size of random sample from which peer candidates are selected.\n */\n sampleSize?: number;\n}\n\nexport class MMSTTopology implements Topology {\n private readonly _originateConnections: number;\n private readonly _maxPeers: number;\n private readonly _sampleSize: number;\n\n private _controller?: SwarmController;\n\n private _sampleCollected = false;\n\n private _lastAction = new Date(0);\n\n constructor({ originateConnections = 2, maxPeers = 4, sampleSize = 10 }: MMSTTopologyOptions = {}) {\n this._originateConnections = originateConnections;\n this._maxPeers = maxPeers;\n this._sampleSize = sampleSize;\n }\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized');\n const { connected, candidates } = this._controller.getState();\n // Run the algorithms if we have first candidates, ran it before, or have more connections than needed.\n if (this._sampleCollected || connected.length > this._maxPeers || candidates.length > 0) {\n log('Running the algorithm.');\n this._sampleCollected = true;\n this._runAlgorithm();\n }\n }\n\n forceUpdate() {\n this._lastAction = new Date(0);\n this.update();\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized');\n const { connected } = this._controller.getState();\n const accept = connected.length < this._maxPeers;\n log(`Offer ${peer} accept=${accept}`);\n return accept;\n }\n\n async destroy(): Promise<void> {\n // Nothing to do.\n }\n\n private _runAlgorithm() {\n invariant(this._controller, 'Not initialized');\n const { connected, candidates, ownPeerId } = this._controller.getState();\n\n // TODO(nf): does this rate limiting/flap dampening logic belong here or in the SwarmController?\n if (connected.length > this._maxPeers) {\n // Disconnect extra peers.\n log(`disconnect ${connected.length - this._maxPeers} peers.`);\n const sorted = sortByXorDistance(connected, ownPeerId)\n .reverse()\n .slice(0, this._maxPeers - connected.length);\n invariant(sorted.length === 0);\n\n if (sorted.length > MAX_CHANGES_PER_UPDATE) {\n log(`want to disconnect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);\n }\n\n if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {\n for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {\n log(`Disconnect ${peer}.`);\n this._controller.disconnect(peer);\n }\n this._lastAction = new Date();\n } else {\n log('rate limited disconnect');\n }\n } else if (connected.length < this._originateConnections) {\n // Connect new peers to reach desired quota.\n log(`connect ${this._originateConnections - connected.length} peers.`);\n const sample = candidates.sort(() => Math.random() - 0.5).slice(0, this._sampleSize);\n const sorted = sortByXorDistance(sample, ownPeerId).slice(0, this._originateConnections - connected.length);\n\n if (sorted.length > MAX_CHANGES_PER_UPDATE) {\n log(`want to connect ${sorted.length} peers but limited to ${MAX_CHANGES_PER_UPDATE}`);\n }\n if (Date.now() - this._lastAction.getTime() > MIN_UPDATE_INTERVAL) {\n for (const peer of sorted.slice(0, MAX_CHANGES_PER_UPDATE)) {\n log(`Connect ${peer}.`);\n this._controller.connect(peer);\n }\n this._lastAction = new Date();\n } else {\n log('rate limited connect');\n }\n }\n }\n\n toString() {\n return 'MMSTTopology';\n }\n}\n\nconst sortByXorDistance = (keys: PublicKey[], reference: PublicKey): PublicKey[] => {\n const sorted = keys.sort((a, b) => {\n return compareXor(distXor(a.asBuffer(), reference.asBuffer()), distXor(b.asBuffer(), reference.asBuffer()));\n });\n log('Sorted keys', { keys, reference, sorted });\n return sorted;\n};\n\nconst distXor = (a: Buffer, b: Buffer) => {\n const maxLength = Math.max(a.length, b.length);\n const result = Buffer.allocUnsafe(maxLength);\n for (let i = 0; i < maxLength; i++) {\n result[i] = (a[i] || 0) ^ (b[i] || 0);\n }\n return result;\n};\n\nconst compareXor = (a: Buffer, b: Buffer) => {\n const maxLength = Math.max(a.length, b.length);\n for (let i = 0; i < maxLength; i++) {\n if ((a[i] || 0) === (b[i] || 0)) {\n continue;\n }\n return (a[i] || 0) < (b[i] || 0) ? -1 : 1;\n }\n return 0;\n};\n", "//\n// Copyright 2020 DXOS.org\n//\n\nimport { invariant } from '@dxos/invariant';\nimport { type PublicKey } from '@dxos/keys';\nimport { log } from '@dxos/log';\n\nimport { type SwarmController, type Topology } from './topology';\n\nexport class StarTopology implements Topology {\n private _controller?: SwarmController;\n\n constructor(private readonly _centralPeer: PublicKey) {}\n\n toString() {\n return `StarTopology(${this._centralPeer.truncate()})`;\n }\n\n init(controller: SwarmController): void {\n invariant(!this._controller, 'Already initialized.');\n this._controller = controller;\n }\n\n update(): void {\n invariant(this._controller, 'Not initialized.');\n const { candidates, connected, ownPeerId } = this._controller.getState();\n if (!ownPeerId.equals(this._centralPeer)) {\n log('leaf peer dropping all connections apart from central peer.');\n\n // Drop all connections other than central peer.\n for (const peer of connected) {\n if (!peer.equals(this._centralPeer)) {\n log('dropping connection', { peer });\n this._controller.disconnect(peer);\n }\n }\n }\n\n for (const peer of candidates) {\n // Connect to central peer.\n if (peer.equals(this._centralPeer) || ownPeerId.equals(this._centralPeer)) {\n log('connecting to peer', { peer });\n this._controller.connect(peer);\n }\n }\n }\n\n async onOffer(peer: PublicKey): Promise<boolean> {\n invariant(this._controller, 'Not initialized.');\n const { ownPeerId } = this._controller.getState();\n log('offer', {\n peer,\n isCentral: peer.equals(this._centralPeer),\n isSelfCentral: ownPeerId.equals(this._centralPeer),\n });\n return ownPeerId.equals(this._centralPeer) || peer.equals(this._centralPeer);\n }\n\n async destroy(): Promise<void> {\n // Nothing to do.\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["asyncTimeout", "log", "isNotNullOrUndefined", "createIceProvider", "iceProviders", "cachedIceServers", "getIceServers", "Promise", "all", "map", "urls", "fetch", "method", "then", "response", "json", "catch", "err", "isDev", "window", "location", "href", "includes", "error", "filter", "iceServers", "flat", "invariant", "log", "MIN_UPDATE_INTERVAL", "MAX_CHANGES_PER_UPDATE", "MMSTTopology", "constructor", "originateConnections", "maxPeers", "sampleSize", "_sampleCollected", "_lastAction", "Date", "_originateConnections", "_maxPeers", "_sampleSize", "init", "controller", "_controller", "update", "connected", "candidates", "getState", "length", "_runAlgorithm", "forceUpdate", "onOffer", "peer", "accept", "destroy", "ownPeerId", "sorted", "sortByXorDistance", "reverse", "slice", "now", "getTime", "disconnect", "sample", "sort", "Math", "random", "connect", "toString", "keys", "reference", "a", "b", "compareXor", "distXor", "asBuffer", "maxLength", "max", "result", "Buffer", "allocUnsafe", "i", "invariant", "log", "StarTopology", "constructor", "_centralPeer", "toString", "truncate", "init", "controller", "_controller", "update", "candidates", "connected", "ownPeerId", "getState", "equals", "peer", "disconnect", "connect", "onOffer", "isCentral", "isSelfCentral", "destroy"]
7
7
  }