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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/dist/lib/browser/{chunk-MKIVP7G3.mjs → chunk-XYSYUN63.mjs} +1064 -1248
  2. package/dist/lib/browser/chunk-XYSYUN63.mjs.map +7 -0
  3. package/dist/lib/browser/index.mjs +19 -10
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/browser/testing/index.mjs +32 -22
  6. package/dist/lib/browser/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/{chunk-D6P7ACEM.cjs → chunk-4YAYC7WN.cjs} +1207 -1264
  8. package/dist/lib/node/chunk-4YAYC7WN.cjs.map +7 -0
  9. package/dist/lib/node/index.cjs +37 -27
  10. package/dist/lib/node/index.cjs.map +2 -2
  11. package/dist/lib/node/meta.json +1 -1
  12. package/dist/lib/node/testing/index.cjs +34 -24
  13. package/dist/lib/node/testing/index.cjs.map +3 -3
  14. package/dist/types/src/network-manager.d.ts +1 -2
  15. package/dist/types/src/network-manager.d.ts.map +1 -1
  16. package/dist/types/src/signal/ice.d.ts.map +1 -1
  17. package/dist/types/src/signal/integration.test.d.ts +2 -0
  18. package/dist/types/src/signal/integration.test.d.ts.map +1 -0
  19. package/dist/types/src/signal/swarm-messenger.test.d.ts +2 -0
  20. package/dist/types/src/signal/swarm-messenger.test.d.ts.map +1 -0
  21. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  22. package/dist/types/src/swarm/swarm.d.ts +1 -1
  23. package/dist/types/src/testing/test-builder.d.ts +2 -2
  24. package/dist/types/src/testing/test-builder.d.ts.map +1 -1
  25. package/dist/types/src/testing/test-wire-protocol.d.ts +2 -1
  26. package/dist/types/src/testing/test-wire-protocol.d.ts.map +1 -1
  27. package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
  28. package/dist/types/src/tests/property-test-suite.d.ts.map +1 -1
  29. package/dist/types/src/tests/tcp-transport.test.d.ts +2 -0
  30. package/dist/types/src/tests/tcp-transport.test.d.ts.map +1 -0
  31. package/dist/types/src/tests/utils.d.ts.map +1 -1
  32. package/dist/types/src/transport/index.d.ts +5 -1
  33. package/dist/types/src/transport/index.d.ts.map +1 -1
  34. package/dist/types/src/transport/libdatachannel-transport.d.ts +42 -0
  35. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -0
  36. package/dist/types/src/transport/libdatachannel-transport.test.d.ts +2 -0
  37. package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +1 -0
  38. package/dist/types/src/transport/memory-transport.d.ts +2 -2
  39. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  40. package/dist/types/src/transport/memory-transport.test.d.ts +2 -0
  41. package/dist/types/src/transport/memory-transport.test.d.ts.map +1 -0
  42. package/dist/types/src/transport/simplepeer-simple-peer.d.ts +2 -0
  43. package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +1 -0
  44. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +2 -0
  45. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +1 -0
  46. package/dist/types/src/transport/{webrtc/rtc-transport-proxy.d.ts → simplepeer-transport-proxy.d.ts} +12 -10
  47. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -0
  48. package/dist/types/src/transport/{webrtc/rtc-transport-service.d.ts → simplepeer-transport-service.d.ts} +7 -9
  49. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -0
  50. package/dist/types/src/transport/simplepeer-transport.d.ts +36 -0
  51. package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -0
  52. package/dist/types/src/transport/simplepeer-transport.test.d.ts +2 -0
  53. package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +1 -0
  54. package/dist/types/src/transport/{tcp/tcp-transport.browser.d.ts → tcp-transport.browser.d.ts} +3 -3
  55. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -0
  56. package/dist/types/src/transport/{tcp/tcp-transport.d.ts → tcp-transport.d.ts} +3 -3
  57. package/dist/types/src/transport/tcp-transport.d.ts.map +1 -0
  58. package/dist/types/src/transport/transport.d.ts +6 -7
  59. package/dist/types/src/transport/transport.d.ts.map +1 -1
  60. package/dist/types/src/transport/webrtc.d.ts +6 -0
  61. package/dist/types/src/transport/webrtc.d.ts.map +1 -0
  62. package/package.json +30 -55
  63. package/src/globals.d.ts +7 -0
  64. package/src/network-manager.ts +13 -5
  65. package/src/signal/ice.test.ts +3 -1
  66. package/src/signal/ice.ts +1 -6
  67. package/src/signal/{integration.node.test.ts → integration.test.ts} +15 -9
  68. package/src/signal/{swarm-messenger.node.test.ts → swarm-messenger.test.ts} +23 -13
  69. package/src/swarm/connection-limiter.test.ts +6 -3
  70. package/src/swarm/connection.test.ts +38 -63
  71. package/src/swarm/connection.ts +5 -5
  72. package/src/swarm/swarm.test.ts +12 -10
  73. package/src/swarm/swarm.ts +1 -1
  74. package/src/testing/test-builder.ts +29 -13
  75. package/src/testing/test-wire-protocol.ts +4 -1
  76. package/src/tests/basic-test-suite.ts +33 -34
  77. package/src/tests/memory-transport.test.ts +42 -40
  78. package/src/tests/property-test-suite.ts +22 -21
  79. package/src/tests/tcp-transport.test.ts +67 -0
  80. package/src/tests/utils.ts +2 -3
  81. package/src/tests/webrtc-transport.test.ts +9 -9
  82. package/src/transport/index.ts +5 -1
  83. package/src/transport/libdatachannel-transport.test.ts +100 -0
  84. package/src/transport/libdatachannel-transport.ts +376 -0
  85. package/src/transport/memory-transport.test.ts +74 -0
  86. package/src/transport/memory-transport.ts +0 -2
  87. package/src/transport/simplepeer-simple-peer.ts +26 -0
  88. package/src/transport/simplepeer-transport-proxy-test.ts +181 -0
  89. package/src/transport/simplepeer-transport-proxy.ts +246 -0
  90. package/src/transport/simplepeer-transport-service.ts +160 -0
  91. package/src/transport/simplepeer-transport.test.ts +61 -0
  92. package/src/transport/simplepeer-transport.ts +250 -0
  93. package/src/transport/{tcp/tcp-transport.browser.ts → tcp-transport.browser.ts} +3 -7
  94. package/src/transport/{tcp/tcp-transport.ts → tcp-transport.ts} +1 -3
  95. package/src/transport/transport.ts +7 -8
  96. package/src/transport/webrtc.ts +15 -0
  97. package/src/typings.d.ts +2 -8
  98. package/dist/lib/browser/chunk-GW3YM55A.mjs +0 -14
  99. package/dist/lib/browser/chunk-GW3YM55A.mjs.map +0 -7
  100. package/dist/lib/browser/chunk-MKIVP7G3.mjs.map +0 -7
  101. package/dist/lib/browser/transport/tcp/index.mjs +0 -39
  102. package/dist/lib/browser/transport/tcp/index.mjs.map +0 -7
  103. package/dist/lib/node/chunk-D6P7ACEM.cjs.map +0 -7
  104. package/dist/lib/node/transport/tcp/index.cjs +0 -191
  105. package/dist/lib/node/transport/tcp/index.cjs.map +0 -7
  106. package/dist/lib/node-esm/chunk-22DA2US6.mjs +0 -4373
  107. package/dist/lib/node-esm/chunk-22DA2US6.mjs.map +0 -7
  108. package/dist/lib/node-esm/index.mjs +0 -50
  109. package/dist/lib/node-esm/index.mjs.map +0 -7
  110. package/dist/lib/node-esm/meta.json +0 -1
  111. package/dist/lib/node-esm/testing/index.mjs +0 -279
  112. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  113. package/dist/lib/node-esm/transport/tcp/index.mjs +0 -159
  114. package/dist/lib/node-esm/transport/tcp/index.mjs.map +0 -7
  115. package/dist/types/src/signal/integration.node.test.d.ts +0 -2
  116. package/dist/types/src/signal/integration.node.test.d.ts.map +0 -1
  117. package/dist/types/src/signal/swarm-messenger.node.test.d.ts +0 -2
  118. package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +0 -1
  119. package/dist/types/src/tests/tcp-transport.node.test.d.ts +0 -2
  120. package/dist/types/src/tests/tcp-transport.node.test.d.ts.map +0 -1
  121. package/dist/types/src/transport/tcp/index.d.ts +0 -2
  122. package/dist/types/src/transport/tcp/index.d.ts.map +0 -1
  123. package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +0 -1
  124. package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +0 -1
  125. package/dist/types/src/transport/webrtc/index.d.ts +0 -4
  126. package/dist/types/src/transport/webrtc/index.d.ts.map +0 -1
  127. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +0 -14
  128. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +0 -1
  129. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +0 -68
  130. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +0 -1
  131. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +0 -33
  132. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +0 -1
  133. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +0 -2
  134. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +0 -1
  135. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +0 -4
  136. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +0 -1
  137. package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +0 -1
  138. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +0 -2
  139. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +0 -1
  140. package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +0 -1
  141. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +0 -4
  142. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +0 -1
  143. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +0 -2
  144. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +0 -1
  145. package/dist/types/src/transport/webrtc/test-utils.d.ts +0 -5
  146. package/dist/types/src/transport/webrtc/test-utils.d.ts.map +0 -1
  147. package/dist/types/src/transport/webrtc/utils.d.ts +0 -3
  148. package/dist/types/src/transport/webrtc/utils.d.ts.map +0 -1
  149. package/src/tests/tcp-transport.node.test.ts +0 -65
  150. package/src/transport/tcp/index.ts +0 -5
  151. package/src/transport/webrtc/index.ts +0 -7
  152. package/src/transport/webrtc/rtc-connection-factory.ts +0 -82
  153. package/src/transport/webrtc/rtc-peer-connection.ts +0 -472
  154. package/src/transport/webrtc/rtc-transport-channel.test.ts +0 -176
  155. package/src/transport/webrtc/rtc-transport-channel.ts +0 -195
  156. package/src/transport/webrtc/rtc-transport-factory.ts +0 -28
  157. package/src/transport/webrtc/rtc-transport-proxy.test.ts +0 -413
  158. package/src/transport/webrtc/rtc-transport-proxy.ts +0 -264
  159. package/src/transport/webrtc/rtc-transport-service.ts +0 -192
  160. package/src/transport/webrtc/rtc-transport-stats.ts +0 -67
  161. package/src/transport/webrtc/rtc-transport.test.ts +0 -198
  162. package/src/transport/webrtc/test-utils.ts +0 -22
  163. package/src/transport/webrtc/utils.ts +0 -36
@@ -2,8 +2,10 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
+ import { expect } from 'chai';
5
6
  import fetchMock from 'fetch-mock';
6
- import { afterEach, test, expect, describe } from 'vitest';
7
+
8
+ import { test, describe } from '@dxos/test';
7
9
 
8
10
  import { createIceProvider } from './ice';
9
11
 
package/src/signal/ice.ts CHANGED
@@ -24,12 +24,7 @@ export const createIceProvider = (iceProviders: Runtime.Services.IceProvider[]):
24
24
  iceProviders.map(({ urls }) =>
25
25
  asyncTimeout(fetch(urls, { method: 'GET' }), 10_000)
26
26
  .then((response) => response.json())
27
- .catch((err) => {
28
- const isDev = typeof window !== 'undefined' && window.location.href.includes('localhost');
29
- if (!isDev) {
30
- log.error('Failed to fetch ICE servers from provider', { urls, err });
31
- }
32
- }),
27
+ .catch((err) => log.error('Failed to fetch ICE servers from provider', { urls, err })),
33
28
  ),
34
29
  )
35
30
  )
@@ -2,11 +2,15 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { afterAll, onTestFinished, beforeAll, describe, expect, test } from 'vitest';
5
+ // @dxos/test platform=nodejs
6
+
7
+ import { expect } from 'earljs';
8
+ import waitForExpect from 'wait-for-expect';
6
9
 
7
10
  import { PublicKey } from '@dxos/keys';
8
11
  import { Messenger, type PeerInfo, WebsocketSignalManager } from '@dxos/messaging';
9
12
  import { runTestSignalServer, type SignalServerRunner } from '@dxos/signal';
13
+ import { afterAll, afterTest, beforeAll, describe, test } from '@dxos/test';
10
14
 
11
15
  import { type SignalMessage } from './signal-messenger';
12
16
  import { SwarmMessenger } from './swarm-messenger';
@@ -31,15 +35,13 @@ describe('Signal Integration Test', () => {
31
35
  }) => {
32
36
  const signalManager = new WebsocketSignalManager([{ server: broker.url() }]);
33
37
  await signalManager.open();
34
- onTestFinished(async () => {
35
- await signalManager.close();
36
- });
38
+ afterTest(() => signalManager.close());
37
39
 
38
40
  const messenger = new Messenger({
39
41
  signalManager,
40
42
  });
41
43
  messenger.open();
42
- onTestFinished(() => messenger.close());
44
+ afterTest(() => messenger.close());
43
45
  await messenger.listen({
44
46
  peer,
45
47
  onMessage: async (message) => await messageRouter.receiveMessage(message),
@@ -94,7 +96,7 @@ describe('Signal Integration Test', () => {
94
96
  offer: {},
95
97
  },
96
98
  }),
97
- ).toEqual(expect.objectContaining({ accept: true }));
99
+ ).toBeAnObjectWith({ accept: true });
98
100
 
99
101
  expect(
100
102
  await peerNetworking2.messageRouter.offer({
@@ -106,7 +108,7 @@ describe('Signal Integration Test', () => {
106
108
  offer: {},
107
109
  },
108
110
  }),
109
- ).toEqual(expect.objectContaining({ accept: true }));
111
+ ).toBeAnObjectWith({ accept: true });
110
112
 
111
113
  {
112
114
  const message: SignalMessage = {
@@ -121,7 +123,9 @@ describe('Signal Integration Test', () => {
121
123
  };
122
124
  await peerNetworking1.messageRouter.signal(message);
123
125
 
124
- await expect.poll(() => peerNetworking2.receivedSignals[0]).toEqual(expect.objectContaining(message));
126
+ await waitForExpect(() => {
127
+ expect(peerNetworking2.receivedSignals[0]).toBeAnObjectWith(message);
128
+ });
125
129
  }
126
130
 
127
131
  {
@@ -137,7 +141,9 @@ describe('Signal Integration Test', () => {
137
141
  };
138
142
  await peerNetworking2.messageRouter.signal(message);
139
143
 
140
- await expect.poll(() => peerNetworking1.receivedSignals[0]).toEqual(expect.objectContaining(message));
144
+ await waitForExpect(() => {
145
+ expect(peerNetworking1.receivedSignals[0]).toBeAnObjectWith(message);
146
+ });
141
147
  }
142
148
  });
143
149
  });
@@ -2,18 +2,22 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import { afterAll, beforeAll, beforeEach, describe, expect, test, onTestFinished } from 'vitest';
5
+ // @dxos/test platform=nodejs
6
+
7
+ import { expect } from 'earljs';
8
+ import waitForExpect from 'wait-for-expect';
6
9
 
7
10
  import { type Awaited } from '@dxos/async';
8
11
  import { PublicKey } from '@dxos/keys';
9
12
  import { Messenger, WebsocketSignalManager } from '@dxos/messaging';
10
13
  import { type Answer } from '@dxos/protocols/proto/dxos/mesh/swarm';
11
14
  import { runTestSignalServer } from '@dxos/signal';
15
+ import { afterAll, beforeAll, describe, test, afterTest } from '@dxos/test';
12
16
 
13
17
  import { type OfferMessage, type SignalMessage } from './signal-messenger';
14
18
  import { SwarmMessenger } from './swarm-messenger';
15
19
 
16
- describe('SwarmMessenger', { timeout: 7000 }, () => {
20
+ describe('SwarmMessenger', () => {
17
21
  let topic: PublicKey;
18
22
 
19
23
  let broker1: Awaited<ReturnType<typeof runTestSignalServer>>;
@@ -44,9 +48,7 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
44
48
  const peer = { peerKey: PublicKey.random().toHex() };
45
49
  const signalManager = new WebsocketSignalManager([{ server: signalApiUrl }]);
46
50
  await signalManager.open();
47
- onTestFinished(async () => {
48
- await signalManager.close();
49
- });
51
+ afterTest(() => signalManager.close());
50
52
 
51
53
  const messenger = new Messenger({ signalManager });
52
54
  await messenger.listen({
@@ -104,8 +106,10 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
104
106
  };
105
107
  await router2.signal(msg);
106
108
 
107
- await expect.poll(() => received[0]).toEqual(expect.objectContaining(msg));
108
- });
109
+ await waitForExpect(() => {
110
+ expect(received[0]).toBeAnObjectWith(msg);
111
+ }, 4_000);
112
+ }).timeout(5_000);
109
113
 
110
114
  test('offer/answer', async () => {
111
115
  const {
@@ -135,7 +139,7 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
135
139
  data: { offer: {} },
136
140
  });
137
141
  expect(answer.accept).toEqual(true);
138
- });
142
+ }).timeout(5_000);
139
143
 
140
144
  test('signaling between 3 clients', async () => {
141
145
  const received1: SignalMessage[] = [];
@@ -194,7 +198,9 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
194
198
  data: { signal: { payload: { msg: '1to3' } }, signalBatch: undefined },
195
199
  };
196
200
  await router1.signal(msg1to3);
197
- await expect.poll(() => received3[0]).toEqual(expect.objectContaining(msg1to3));
201
+ await waitForExpect(() => {
202
+ expect(received3[0]).toBeAnObjectWith(msg1to3);
203
+ }, 4_000);
198
204
 
199
205
  // sending signal from peer2 to peer3.
200
206
  const msg2to3: SignalMessage = {
@@ -205,7 +211,9 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
205
211
  data: { signal: { payload: { msg: '2to3' } }, signalBatch: undefined },
206
212
  };
207
213
  await router2.signal(msg2to3);
208
- await expect.poll(() => received3[1]).toEqual(expect.objectContaining(msg2to3));
214
+ await waitForExpect(() => {
215
+ expect(received3[1]).toBeAnObjectWith(msg2to3);
216
+ }, 4_000);
209
217
 
210
218
  // sending signal from peer3 to peer1.
211
219
  const msg3to1: SignalMessage = {
@@ -216,8 +224,10 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
216
224
  data: { signal: { payload: { msg: '3to1' } }, signalBatch: undefined },
217
225
  };
218
226
  await router3.signal(msg3to1);
219
- await expect.poll(() => received1[0]).toEqual(expect.objectContaining(msg3to1));
220
- });
227
+ await waitForExpect(() => {
228
+ expect(received1[0]).toBeAnObjectWith(msg3to1);
229
+ }, 4_000);
230
+ }).timeout(5_000);
221
231
 
222
232
  test('two offers', async () => {
223
233
  const {
@@ -263,5 +273,5 @@ describe('SwarmMessenger', { timeout: 7000 }, () => {
263
273
  data: { offer: {} },
264
274
  });
265
275
  expect(answer2.accept).toEqual(true);
266
- });
276
+ }).timeout(5_000);
267
277
  });
@@ -1,14 +1,17 @@
1
1
  //
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
-
5
- import { describe, expect, test } from 'vitest';
4
+ import chai, { expect } from 'chai';
5
+ import chaiAsPromised from 'chai-as-promised';
6
6
 
7
7
  import { asyncTimeout } from '@dxos/async';
8
8
  import { PublicKey } from '@dxos/keys';
9
+ import { describe, test } from '@dxos/test';
9
10
 
10
11
  import { ConnectionLimiter } from './connection-limiter';
11
12
 
13
+ chai.use(chaiAsPromised);
14
+
12
15
  describe('ConnectionLimiter', () => {
13
16
  function* setupPeers(
14
17
  limiter: ConnectionLimiter,
@@ -34,7 +37,7 @@ describe('ConnectionLimiter', () => {
34
37
  test('rejects if done is called', async () => {
35
38
  const limiter = new ConnectionLimiter({ maxConcurrentInitConnections: 1 });
36
39
  const [first] = setupPeers(limiter);
37
- const testPromise = expect(first.connecting()).rejects.toBeInstanceOf(Error);
40
+ const testPromise = expect(first.connecting()).to.be.rejected;
38
41
  first.doneConnecting();
39
42
  await testPromise;
40
43
  });
@@ -2,103 +2,78 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { describe, test } from 'vitest';
6
-
7
5
  import { sleep } from '@dxos/async';
8
6
  import { PublicKey } from '@dxos/keys';
7
+ import { describe, test } from '@dxos/test';
9
8
 
10
9
  import { Connection } from './connection';
11
10
  import { TestWireProtocol } from '../testing/test-wire-protocol';
12
- import { createRtcTransportFactory } from '../transport';
13
- import { chooseInitiatorPeer } from '../transport/webrtc/utils';
11
+ import { createLibDataChannelTransportFactory, createSimplePeerTransportFactory } from '../transport';
14
12
 
15
13
  describe('Connection', () => {
16
- test('responder opens after initiator', async () => {
17
- const { initiator, responder } = createPeerKeys();
18
- await connectionTest({
19
- fastConnectionKey: initiator,
20
- slowConnectionKey: responder,
21
- });
22
- });
23
-
24
14
  test('initiator opens after responder', async () => {
25
- const { initiator, responder } = createPeerKeys();
26
- await connectionTest({
27
- fastConnectionKey: responder,
28
- slowConnectionKey: initiator,
29
- });
30
- });
31
-
32
- const connectionTest = async (setup: { fastConnectionKey: PublicKey; slowConnectionKey: PublicKey }) => {
33
15
  const [topic, sessionId] = PublicKey.randomSequence();
34
- const slowPeer = { peerKey: setup.slowConnectionKey.toHex() };
35
- const fastPeer = { peerKey: setup.fastConnectionKey.toHex() };
36
-
37
- const slowPeerProtocol = new TestWireProtocol();
38
- const slowConnection = new Connection(
16
+ const peer1 = { peerKey: PublicKey.random().toHex() };
17
+ const peer2 = { peerKey: PublicKey.random().toHex() };
18
+ const protocol1 = new TestWireProtocol(PublicKey.from(peer1.peerKey));
19
+ const connection1 = new Connection(
39
20
  topic,
40
- slowPeer,
41
- fastPeer,
21
+ peer1,
22
+ peer2,
42
23
  sessionId,
43
24
  true,
44
25
  {
45
- offer: async (msg) => ({ accept: true }),
26
+ offer: async (msg) => {
27
+ return { accept: true };
28
+ },
46
29
  signal: async (msg) => {
47
- await fastConnection.signal(msg);
30
+ await connection2.signal(msg);
48
31
  },
49
32
  },
50
- slowPeerProtocol.factory({
33
+ protocol1.factory({
51
34
  initiator: true,
52
- localPeerId: PublicKey.from(slowPeer.peerKey),
53
- remotePeerId: PublicKey.from(fastPeer.peerKey),
35
+ localPeerId: PublicKey.from(peer1.peerKey),
36
+ remotePeerId: PublicKey.from(peer2.peerKey),
54
37
  topic,
55
38
  }),
56
- createRtcTransportFactory(),
39
+ // TODO(nf): configure better
40
+ process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
57
41
  );
58
42
 
59
- const fastPeerProtocol = new TestWireProtocol();
60
- const fastConnection = new Connection(
43
+ const protocol2 = new TestWireProtocol(PublicKey.from(peer2.peerKey));
44
+ const connection2 = new Connection(
61
45
  topic,
62
- fastPeer,
63
- slowPeer,
46
+ peer2,
47
+ peer1,
64
48
  sessionId,
65
49
  false,
66
50
  {
67
- offer: async (msg) => ({ accept: true }),
51
+ offer: async (msg) => {
52
+ return { accept: true };
53
+ },
68
54
  signal: async (msg) => {
69
- await slowConnection.signal(msg);
55
+ await connection1.signal(msg);
70
56
  },
71
57
  },
72
- fastPeerProtocol.factory({
58
+ protocol2.factory({
73
59
  initiator: false,
74
- localPeerId: PublicKey.from(fastPeer.peerKey),
75
- remotePeerId: PublicKey.from(slowPeer.peerKey),
60
+ localPeerId: PublicKey.from(peer2.peerKey),
61
+ remotePeerId: PublicKey.from(peer1.peerKey),
76
62
  topic,
77
63
  }),
78
- createRtcTransportFactory(),
64
+ // TODO(nf): configure better
65
+ process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
79
66
  );
80
67
 
81
- fastConnection.initiate();
82
- await fastConnection.openConnection();
83
- await sleep(200);
84
-
85
- slowConnection.initiate();
86
- await slowConnection.openConnection();
68
+ connection2.initiate();
69
+ await connection2.openConnection();
70
+ await sleep(100);
87
71
 
72
+ connection1.initiate();
73
+ await connection1.openConnection();
88
74
  await Promise.all([
89
- slowPeerProtocol.testConnection(PublicKey.from(fastPeer.peerKey), 'test message 1'),
90
- fastPeerProtocol.testConnection(PublicKey.from(slowPeer.peerKey), 'test message 2'),
75
+ protocol1.testConnection(PublicKey.from(peer2.peerKey), 'test message 1'),
76
+ protocol2.testConnection(PublicKey.from(peer1.peerKey), 'test message 2'),
91
77
  ]);
92
- };
93
-
94
- const createPeerKeys = () => {
95
- const peer1 = PublicKey.random();
96
- const peer2 = PublicKey.random();
97
- const initiator = PublicKey.fromHex(chooseInitiatorPeer(peer1.toHex(), peer2.toHex()));
98
- if (initiator.equals(peer1)) {
99
- return { initiator: peer1, responder: peer2 };
100
- } else {
101
- return { initiator: peer2, responder: peer1 };
102
- }
103
- };
78
+ });
104
79
  });
@@ -15,6 +15,7 @@ import {
15
15
  ConnectionResetError,
16
16
  ConnectivityError,
17
17
  TimeoutError,
18
+ UnknownProtocolError,
18
19
  trace,
19
20
  } from '@dxos/protocols';
20
21
  import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
@@ -201,15 +202,14 @@ export class Connection {
201
202
 
202
203
  invariant(!this._transport);
203
204
  this._transport = this._transportFactory.createTransport({
204
- ownPeerKey: this.localInfo.peerKey,
205
- remotePeerKey: this.remoteInfo.peerKey,
206
- topic: this.topic.toHex(),
207
205
  initiator: this.initiator,
208
206
  stream: this._protocol.stream,
209
207
  sendSignal: async (signal) => this._sendSignal(signal),
210
208
  sessionId: this.sessionId,
211
209
  });
212
210
 
211
+ await this._transport.open();
212
+
213
213
  this._transport.connected.once(async () => {
214
214
  this._changeState(ConnectionState.CONNECTED);
215
215
  await this.connectedTimeoutContext.dispose();
@@ -238,6 +238,8 @@ export class Connection {
238
238
  } else if (err instanceof ConnectivityError) {
239
239
  log.info('aborting due to transport ConnectivityError');
240
240
  this.abort().catch((err) => this.errors.raise(err));
241
+ } else if (err instanceof UnknownProtocolError) {
242
+ log.warn('unsure what to do with UnknownProtocolError, will keep on truckin', { err });
241
243
  }
242
244
 
243
245
  if (this._state !== ConnectionState.CLOSED && this._state !== ConnectionState.CLOSING) {
@@ -246,8 +248,6 @@ export class Connection {
246
248
  }
247
249
  });
248
250
 
249
- await this._transport.open();
250
-
251
251
  // Replay signals that were received before transport was created.
252
252
  for (const signal of this._incomingSignalBuffer) {
253
253
  void this._transport.onSignal(signal); // TODO(burdon): Remove async?
@@ -2,7 +2,7 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import { onTestFinished, describe, expect, test } from 'vitest';
5
+ import { expect } from 'chai';
6
6
 
7
7
  import { asyncTimeout, sleep } from '@dxos/async';
8
8
  import { PublicKey } from '@dxos/keys';
@@ -13,6 +13,7 @@ import {
13
13
  type PeerInfo,
14
14
  type SignalManager,
15
15
  } from '@dxos/messaging';
16
+ import { afterTest, describe, test } from '@dxos/test';
16
17
  import { ComplexSet } from '@dxos/util';
17
18
 
18
19
  import { ConnectionState } from './connection';
@@ -20,7 +21,7 @@ import { ConnectionLimiter } from './connection-limiter';
20
21
  import { Swarm } from './swarm';
21
22
  import { TestWireProtocol } from '../testing/test-wire-protocol';
22
23
  import { FullyConnectedTopology } from '../topology';
23
- import { createRtcTransportFactory } from '../transport';
24
+ import { createLibDataChannelTransportFactory, createSimplePeerTransportFactory } from '../transport';
24
25
 
25
26
  type TestPeer = {
26
27
  swarm: Swarm;
@@ -46,20 +47,21 @@ describe('Swarm', () => {
46
47
  signalManager?: SignalManager;
47
48
  initiationDelay?: number;
48
49
  }): Promise<TestPeer> => {
49
- const protocol = new TestWireProtocol();
50
+ const protocol = new TestWireProtocol(PublicKey.from(peer.peerKey));
50
51
  const swarm = new Swarm(
51
52
  topic,
52
53
  peer,
53
54
  new FullyConnectedTopology(),
54
55
  protocol.factory,
55
56
  new Messenger({ signalManager }),
56
- createRtcTransportFactory(),
57
+ // TODO(nf): configure better
58
+ process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
57
59
  undefined,
58
60
  connectionLimiter,
59
61
  initiationDelay,
60
62
  );
61
63
 
62
- onTestFinished(async () => {
64
+ afterTest(async () => {
63
65
  await swarm.destroy();
64
66
  await signalManager.close();
65
67
  });
@@ -79,7 +81,7 @@ describe('Swarm', () => {
79
81
  expect(peer2.swarm.connections.length).to.equal(0);
80
82
 
81
83
  await connectSwarms(peer1, peer2);
82
- });
84
+ }).timeout(5_000);
83
85
 
84
86
  test('two peers try to originate connections to each other simultaneously', async () => {
85
87
  const topic = PublicKey.random();
@@ -91,7 +93,7 @@ describe('Swarm', () => {
91
93
  expect(peer2.swarm.connections.length).to.equal(0);
92
94
 
93
95
  await connectSwarms(peer1, peer2);
94
- });
96
+ }).timeout(5_000);
95
97
 
96
98
  test('with simultaneous connections one of the peers drops initiated connection', async () => {
97
99
  const topic = PublicKey.random();
@@ -109,9 +111,9 @@ describe('Swarm', () => {
109
111
 
110
112
  await connectSwarms(peer1, peer2);
111
113
  await asyncTimeout(connectionDisplaced!, 1000);
112
- });
114
+ }).timeout(5_000);
113
115
 
114
- test('second peer discovered after delay', { timeout: 10_000 }, async () => {
116
+ test('second peer discovered after delay', async () => {
115
117
  const topic = PublicKey.random();
116
118
 
117
119
  const peer1 = await setupSwarm({ topic });
@@ -124,7 +126,7 @@ describe('Swarm', () => {
124
126
  expect(peer2.swarm.connections.length).to.equal(0);
125
127
 
126
128
  await connectSwarms(peer1, peer2, () => sleep(15));
127
- });
129
+ }).timeout(10_000);
128
130
 
129
131
  test('connection limiter', async () => {
130
132
  // remotePeer1 <--> peer (connectionLimiter: max = 1) <--> remotePeer2
@@ -29,7 +29,7 @@ const getClassName = (obj: any) => Object.getPrototypeOf(obj).constructor.name;
29
29
 
30
30
  /**
31
31
  * A single peer's view of the swarm.
32
- * Manages a set of peers subscribed on the same topic.
32
+ * Manages a set of connections implemented by simple-peer instances.
33
33
  * Routes signal events and maintains swarm topology.
34
34
  */
35
35
  export class Swarm {
@@ -16,12 +16,19 @@ import { type Runtime } from '@dxos/protocols/proto/dxos/config';
16
16
  import { createLinkedPorts, createProtoRpcPeer, type ProtoRpcPeer } from '@dxos/rpc';
17
17
  import { ComplexMap } from '@dxos/util';
18
18
 
19
- import { TcpTransportFactory } from '#tcp-transport';
20
19
  import { type TestTeleportExtensionFactory, TestWireProtocol } from './test-wire-protocol';
21
20
  import { SwarmNetworkManager } from '../network-manager';
22
21
  import { FullyConnectedTopology } from '../topology';
23
- import { MemoryTransportFactory, type TransportFactory, TransportKind } from '../transport';
24
- import { createRtcTransportFactory, RtcTransportProxyFactory, RtcTransportService } from '../transport';
22
+ import {
23
+ createLibDataChannelTransportFactory,
24
+ createSimplePeerTransportFactory,
25
+ MemoryTransportFactory,
26
+ SimplePeerTransportProxyFactory,
27
+ SimplePeerTransportService,
28
+ type TransportFactory,
29
+ TransportKind,
30
+ } from '../transport';
31
+ import { TcpTransportFactory } from '../transport/tcp-transport';
25
32
 
26
33
  // Signal server will be started by the setup script.
27
34
  const port = process.env.SIGNAL_PORT ?? 4000;
@@ -78,12 +85,18 @@ export class TestPeer {
78
85
  constructor(
79
86
  private readonly testBuilder: TestBuilder,
80
87
  public readonly peerId: PublicKey,
81
- public readonly transport: TransportKind = testBuilder.options.signalHosts
82
- ? TransportKind.WEB_RTC
83
- : TransportKind.MEMORY,
88
+ public readonly transport?: TransportKind,
84
89
  ) {
85
90
  this._signalManager = this.testBuilder.createSignalManager();
86
- this._networkManager = this.createNetworkManager(this.transport);
91
+ if (!transport) {
92
+ if (this.testBuilder.options.signalHosts) {
93
+ // TODO(nf): configure better
94
+ transport = process.env.MOCHA_ENV === 'nodejs' ? TransportKind.LIBDATACHANNEL : TransportKind.SIMPLE_PEER;
95
+ } else {
96
+ transport = TransportKind.MEMORY;
97
+ }
98
+ }
99
+ this._networkManager = this.createNetworkManager(transport);
87
100
  }
88
101
 
89
102
  // TODO(burdon): Move to TestBuilder.
@@ -97,10 +110,13 @@ export class TestPeer {
97
110
  case TransportKind.TCP:
98
111
  transportFactory = TcpTransportFactory;
99
112
  break;
100
- case TransportKind.WEB_RTC:
101
- transportFactory = createRtcTransportFactory();
113
+ case TransportKind.SIMPLE_PEER:
114
+ transportFactory = createSimplePeerTransportFactory();
115
+ break;
116
+ case TransportKind.LIBDATACHANNEL:
117
+ transportFactory = createLibDataChannelTransportFactory();
102
118
  break;
103
- case TransportKind.WEB_RTC_PROXY:
119
+ case TransportKind.SIMPLE_PEER_PROXY:
104
120
  {
105
121
  // Simulates bridge to shared worker.
106
122
  const [proxyPort, servicePort] = createLinkedPorts();
@@ -121,14 +137,14 @@ export class TestPeer {
121
137
  exposed: {
122
138
  BridgeService: schema.getService('dxos.mesh.bridge.BridgeService'),
123
139
  },
124
- handlers: { BridgeService: new RtcTransportService() },
140
+ handlers: { BridgeService: new SimplePeerTransportService() },
125
141
  noHandshake: true,
126
142
  encodingOptions: {
127
143
  preserveAny: true,
128
144
  },
129
145
  });
130
146
 
131
- transportFactory = new RtcTransportProxyFactory().setBridgeService(this._proxy.rpc.BridgeService);
147
+ transportFactory = new SimplePeerTransportProxyFactory().setBridgeService(this._proxy.rpc.BridgeService);
132
148
  }
133
149
  break;
134
150
  default:
@@ -203,7 +219,7 @@ export class TestSwarmConnection {
203
219
  ) {
204
220
  // TODO(burdon): Configure plugins.
205
221
  // TODO(burdon): Prevent reuse?
206
- this.protocol = new TestWireProtocol(this.extensionFactory);
222
+ this.protocol = new TestWireProtocol(this.peer.peerId, this.extensionFactory);
207
223
  }
208
224
 
209
225
  // TODO(burdon): Need to create new plugin instance per swarm?
@@ -29,7 +29,10 @@ export class TestWireProtocol {
29
29
  ({ remotePeerId, extension }) => remotePeerId.toHex() + extension,
30
30
  );
31
31
 
32
- constructor(private readonly _extensionFactory: TestTeleportExtensionFactory = () => []) {}
32
+ constructor(
33
+ public readonly peerId: PublicKey,
34
+ private readonly _extensionFactory: TestTeleportExtensionFactory = () => [],
35
+ ) {}
33
36
 
34
37
  readonly factory = createTeleportProtocolFactory(async (teleport) => {
35
38
  log('create', { remotePeerId: teleport.remotePeerId });