@dxos/network-manager 0.6.12-main.ed7cda7 → 0.6.12-staging.0b4bb48

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 (155) hide show
  1. package/dist/lib/browser/{chunk-YOKKEU6T.mjs → chunk-XYSYUN63.mjs} +998 -1192
  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 +27 -18
  6. package/dist/lib/browser/testing/index.mjs.map +3 -3
  7. package/dist/lib/node/{chunk-7ZWQLO5T.cjs → chunk-4YAYC7WN.cjs} +1166 -1233
  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 +29 -20
  13. package/dist/lib/node/testing/index.cjs.map +3 -3
  14. package/dist/types/src/signal/integration.test.d.ts +2 -0
  15. package/dist/types/src/signal/integration.test.d.ts.map +1 -0
  16. package/dist/types/src/signal/swarm-messenger.test.d.ts +2 -0
  17. package/dist/types/src/signal/swarm-messenger.test.d.ts.map +1 -0
  18. package/dist/types/src/swarm/connection.d.ts.map +1 -1
  19. package/dist/types/src/swarm/swarm.d.ts +1 -1
  20. package/dist/types/src/testing/test-builder.d.ts +2 -2
  21. package/dist/types/src/testing/test-builder.d.ts.map +1 -1
  22. package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
  23. package/dist/types/src/tests/property-test-suite.d.ts.map +1 -1
  24. package/dist/types/src/tests/tcp-transport.test.d.ts +2 -0
  25. package/dist/types/src/tests/tcp-transport.test.d.ts.map +1 -0
  26. package/dist/types/src/tests/utils.d.ts.map +1 -1
  27. package/dist/types/src/transport/index.d.ts +5 -1
  28. package/dist/types/src/transport/index.d.ts.map +1 -1
  29. package/dist/types/src/transport/libdatachannel-transport.d.ts +42 -0
  30. package/dist/types/src/transport/libdatachannel-transport.d.ts.map +1 -0
  31. package/dist/types/src/transport/libdatachannel-transport.test.d.ts +2 -0
  32. package/dist/types/src/transport/libdatachannel-transport.test.d.ts.map +1 -0
  33. package/dist/types/src/transport/memory-transport.d.ts +2 -2
  34. package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
  35. package/dist/types/src/transport/memory-transport.test.d.ts +2 -0
  36. package/dist/types/src/transport/memory-transport.test.d.ts.map +1 -0
  37. package/dist/types/src/transport/simplepeer-simple-peer.d.ts +2 -0
  38. package/dist/types/src/transport/simplepeer-simple-peer.d.ts.map +1 -0
  39. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts +2 -0
  40. package/dist/types/src/transport/simplepeer-transport-proxy-test.d.ts.map +1 -0
  41. package/dist/types/src/transport/{webrtc/rtc-transport-proxy.d.ts → simplepeer-transport-proxy.d.ts} +12 -10
  42. package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +1 -0
  43. package/dist/types/src/transport/{webrtc/rtc-transport-service.d.ts → simplepeer-transport-service.d.ts} +7 -9
  44. package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +1 -0
  45. package/dist/types/src/transport/simplepeer-transport.d.ts +36 -0
  46. package/dist/types/src/transport/simplepeer-transport.d.ts.map +1 -0
  47. package/dist/types/src/transport/simplepeer-transport.test.d.ts +2 -0
  48. package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +1 -0
  49. package/dist/types/src/transport/{tcp/tcp-transport.browser.d.ts → tcp-transport.browser.d.ts} +3 -3
  50. package/dist/types/src/transport/tcp-transport.browser.d.ts.map +1 -0
  51. package/dist/types/src/transport/{tcp/tcp-transport.d.ts → tcp-transport.d.ts} +3 -3
  52. package/dist/types/src/transport/tcp-transport.d.ts.map +1 -0
  53. package/dist/types/src/transport/transport.d.ts +6 -7
  54. package/dist/types/src/transport/transport.d.ts.map +1 -1
  55. package/dist/types/src/transport/webrtc.d.ts +6 -0
  56. package/dist/types/src/transport/webrtc.d.ts.map +1 -0
  57. package/package.json +30 -53
  58. package/src/globals.d.ts +7 -0
  59. package/src/signal/ice.test.ts +3 -1
  60. package/src/signal/{integration.node.test.ts → integration.test.ts} +15 -9
  61. package/src/signal/{swarm-messenger.node.test.ts → swarm-messenger.test.ts} +23 -13
  62. package/src/swarm/connection-limiter.test.ts +6 -3
  63. package/src/swarm/connection.test.ts +38 -63
  64. package/src/swarm/connection.ts +5 -5
  65. package/src/swarm/swarm.test.ts +11 -9
  66. package/src/swarm/swarm.ts +1 -1
  67. package/src/testing/test-builder.ts +28 -12
  68. package/src/tests/basic-test-suite.ts +33 -34
  69. package/src/tests/memory-transport.test.ts +42 -40
  70. package/src/tests/property-test-suite.ts +22 -21
  71. package/src/tests/tcp-transport.test.ts +67 -0
  72. package/src/tests/utils.ts +2 -3
  73. package/src/tests/webrtc-transport.test.ts +9 -9
  74. package/src/transport/index.ts +5 -1
  75. package/src/transport/libdatachannel-transport.test.ts +100 -0
  76. package/src/transport/libdatachannel-transport.ts +376 -0
  77. package/src/transport/memory-transport.test.ts +74 -0
  78. package/src/transport/memory-transport.ts +0 -2
  79. package/src/transport/simplepeer-simple-peer.ts +26 -0
  80. package/src/transport/simplepeer-transport-proxy-test.ts +181 -0
  81. package/src/transport/simplepeer-transport-proxy.ts +246 -0
  82. package/src/transport/simplepeer-transport-service.ts +160 -0
  83. package/src/transport/simplepeer-transport.test.ts +61 -0
  84. package/src/transport/simplepeer-transport.ts +250 -0
  85. package/src/transport/{tcp/tcp-transport.browser.ts → tcp-transport.browser.ts} +3 -7
  86. package/src/transport/{tcp/tcp-transport.ts → tcp-transport.ts} +1 -3
  87. package/src/transport/transport.ts +7 -8
  88. package/src/transport/webrtc.ts +15 -0
  89. package/src/typings.d.ts +2 -8
  90. package/dist/lib/browser/chunk-GW3YM55A.mjs +0 -14
  91. package/dist/lib/browser/chunk-GW3YM55A.mjs.map +0 -7
  92. package/dist/lib/browser/chunk-YOKKEU6T.mjs.map +0 -7
  93. package/dist/lib/browser/transport/tcp/index.mjs +0 -39
  94. package/dist/lib/browser/transport/tcp/index.mjs.map +0 -7
  95. package/dist/lib/node/chunk-7ZWQLO5T.cjs.map +0 -7
  96. package/dist/lib/node/transport/tcp/index.cjs +0 -191
  97. package/dist/lib/node/transport/tcp/index.cjs.map +0 -7
  98. package/dist/lib/node-esm/chunk-4VO725JT.mjs +0 -4383
  99. package/dist/lib/node-esm/chunk-4VO725JT.mjs.map +0 -7
  100. package/dist/lib/node-esm/index.mjs +0 -50
  101. package/dist/lib/node-esm/index.mjs.map +0 -7
  102. package/dist/lib/node-esm/meta.json +0 -1
  103. package/dist/lib/node-esm/testing/index.mjs +0 -280
  104. package/dist/lib/node-esm/testing/index.mjs.map +0 -7
  105. package/dist/lib/node-esm/transport/tcp/index.mjs +0 -159
  106. package/dist/lib/node-esm/transport/tcp/index.mjs.map +0 -7
  107. package/dist/types/src/signal/integration.node.test.d.ts +0 -2
  108. package/dist/types/src/signal/integration.node.test.d.ts.map +0 -1
  109. package/dist/types/src/signal/swarm-messenger.node.test.d.ts +0 -2
  110. package/dist/types/src/signal/swarm-messenger.node.test.d.ts.map +0 -1
  111. package/dist/types/src/tests/tcp-transport.node.test.d.ts +0 -2
  112. package/dist/types/src/tests/tcp-transport.node.test.d.ts.map +0 -1
  113. package/dist/types/src/transport/tcp/index.d.ts +0 -2
  114. package/dist/types/src/transport/tcp/index.d.ts.map +0 -1
  115. package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +0 -1
  116. package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +0 -1
  117. package/dist/types/src/transport/webrtc/index.d.ts +0 -4
  118. package/dist/types/src/transport/webrtc/index.d.ts.map +0 -1
  119. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +0 -14
  120. package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +0 -1
  121. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +0 -68
  122. package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +0 -1
  123. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +0 -33
  124. package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +0 -1
  125. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +0 -2
  126. package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +0 -1
  127. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +0 -4
  128. package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +0 -1
  129. package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +0 -1
  130. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +0 -2
  131. package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +0 -1
  132. package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +0 -1
  133. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +0 -4
  134. package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +0 -1
  135. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +0 -2
  136. package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +0 -1
  137. package/dist/types/src/transport/webrtc/test-utils.d.ts +0 -5
  138. package/dist/types/src/transport/webrtc/test-utils.d.ts.map +0 -1
  139. package/dist/types/src/transport/webrtc/utils.d.ts +0 -3
  140. package/dist/types/src/transport/webrtc/utils.d.ts.map +0 -1
  141. package/src/tests/tcp-transport.node.test.ts +0 -65
  142. package/src/transport/tcp/index.ts +0 -5
  143. package/src/transport/webrtc/index.ts +0 -7
  144. package/src/transport/webrtc/rtc-connection-factory.ts +0 -82
  145. package/src/transport/webrtc/rtc-peer-connection.ts +0 -472
  146. package/src/transport/webrtc/rtc-transport-channel.test.ts +0 -176
  147. package/src/transport/webrtc/rtc-transport-channel.ts +0 -195
  148. package/src/transport/webrtc/rtc-transport-factory.ts +0 -28
  149. package/src/transport/webrtc/rtc-transport-proxy.test.ts +0 -413
  150. package/src/transport/webrtc/rtc-transport-proxy.ts +0 -264
  151. package/src/transport/webrtc/rtc-transport-service.ts +0 -192
  152. package/src/transport/webrtc/rtc-transport-stats.ts +0 -67
  153. package/src/transport/webrtc/rtc-transport.test.ts +0 -198
  154. package/src/transport/webrtc/test-utils.ts +0 -22
  155. package/src/transport/webrtc/utils.ts +0 -36
@@ -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(PublicKey.from(slowPeer.peerKey));
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(PublicKey.from(fastPeer.peerKey));
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;
@@ -53,13 +54,14 @@ describe('Swarm', () => {
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:
@@ -2,11 +2,13 @@
2
2
  // Copyright 2021 DXOS.org
3
3
  //
4
4
 
5
- import { onTestFinished, expect, test } from 'vitest';
5
+ import { expect } from 'chai';
6
+ import waitForExpect from 'wait-for-expect';
6
7
 
7
8
  import { asyncTimeout } from '@dxos/async';
8
9
  import { PublicKey } from '@dxos/keys';
9
10
  import { log } from '@dxos/log';
11
+ import { afterTest, test } from '@dxos/test';
10
12
  import { range } from '@dxos/util';
11
13
 
12
14
  import { exchangeMessages, joinSwarm, leaveSwarm, openAndCloseAfterTest } from './utils';
@@ -23,7 +25,7 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
23
25
  return;
24
26
  }
25
27
 
26
- test.skip('joins swarm, sends messages, and cleanly exits', async () => {
28
+ test('joins swarm, sends messages, and cleanly exits', async () => {
27
29
  const peer1 = testBuilder.createPeer();
28
30
  const peer2 = testBuilder.createPeer();
29
31
  await openAndCloseAfterTest([peer1, peer2]);
@@ -32,24 +34,24 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
32
34
  const [swarm1, swarm2] = await joinSwarm([peer1, peer2], topic, () => new FullyConnectedTopology());
33
35
  await exchangeMessages(swarm1, swarm2);
34
36
  await leaveSwarm([peer1, peer2], topic);
35
- });
37
+ }).tag('flaky');
36
38
 
37
39
  // TODO(burdon): Test with more peers (configure and test messaging).
38
- test.skip('joins swarm with star topology', async () => {
40
+ test('joins swarm with star topology', async () => {
39
41
  const peer1 = testBuilder.createPeer();
40
- onTestFinished(() => peer1.close());
42
+ afterTest(() => peer1.close());
41
43
  const peer2 = testBuilder.createPeer();
42
- onTestFinished(() => peer2.close());
44
+ afterTest(() => peer2.close());
43
45
  await openAndCloseAfterTest([peer1, peer2]);
44
46
 
45
47
  const topic = PublicKey.random();
46
48
  const [swarm1, swarm2] = await joinSwarm([peer1, peer2], topic, () => new StarTopology(peer1.peerId)); // NOTE: Same peer.
47
49
  await exchangeMessages(swarm1, swarm2);
48
50
  await leaveSwarm([peer1, peer2], topic);
49
- });
51
+ }).tag('flaky');
50
52
 
51
53
  // TODO(burdon): Fails when trying to reconnect to same topic.
52
- test.skip('joins swarm multiple times', async () => {
54
+ test('joins swarm multiple times', async () => {
53
55
  const peer1 = testBuilder.createPeer();
54
56
  const peer2 = testBuilder.createPeer();
55
57
  await openAndCloseAfterTest([peer1, peer2]);
@@ -73,9 +75,9 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
73
75
  await exchangeMessages(swarm1, swarm2);
74
76
  await leaveSwarm([peer1, peer2], topic2);
75
77
  }
76
- });
78
+ }).tag('flaky');
77
79
 
78
- test.skip('joins multiple swarms', async () => {
80
+ test('joins multiple swarms', async () => {
79
81
  // TODO(burdon): N peers.
80
82
  // TODO(burdon): Merge with test below.
81
83
  const peer1 = testBuilder.createPeer();
@@ -85,9 +87,9 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
85
87
  const numSwarms = 5;
86
88
  const topics = Array.from(Array(numSwarms)).map(() => PublicKey.random());
87
89
  expect(topics).to.have.length(numSwarms);
88
- });
90
+ }).tag('flaky');
89
91
 
90
- test.skip('joins multiple swarms concurrently', async () => {
92
+ test('joins multiple swarms concurrently', async () => {
91
93
  const createSwarm = async () => {
92
94
  const topicA = PublicKey.random();
93
95
  const peer1a = testBuilder.createPeer();
@@ -107,9 +109,9 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
107
109
  test1.swarm1a.protocol.testConnection(test1.peer2a.peerId),
108
110
  test2.swarm1a.protocol.testConnection(test2.peer2a.peerId),
109
111
  ]);
110
- });
112
+ }).tag('flaky');
111
113
 
112
- test.skip('peers reconnect after and error in connection', async () => {
114
+ test('peers reconnect after and error in connection', async () => {
113
115
  const peer1 = testBuilder.createPeer();
114
116
  const peer2 = testBuilder.createPeer();
115
117
  await openAndCloseAfterTest([peer1, peer2]);
@@ -129,9 +131,9 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
129
131
  await exchangeMessages(swarm1, swarm2);
130
132
 
131
133
  await leaveSwarm([peer1, peer2], topic);
132
- });
134
+ }).tag('flaky');
133
135
 
134
- test.skip('going offline and back online', { timeout: 2_000 }, async () => {
136
+ test('going offline and back online', async () => {
135
137
  const peer1 = testBuilder.createPeer();
136
138
  const peer2 = testBuilder.createPeer();
137
139
  await openAndCloseAfterTest([peer1, peer2]);
@@ -156,31 +158,28 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
156
158
  await peerLeft;
157
159
 
158
160
  // Wait for peer to be removed from the swarm.
159
- await expect
160
- .poll(() => !!peer2._networkManager.getSwarm(topic)!._peers.get({ peerKey: peer1.peerId.toHex() })?.advertizing, {
161
- timeout: 1_000,
162
- })
163
- .toBe(false);
161
+ await waitForExpect(() => {
162
+ expect(!!peer2._networkManager.getSwarm(topic)!._peers.get({ peerKey: peer1.peerId.toHex() })?.advertizing).to.be
163
+ .false;
164
+ }, 1_000);
164
165
 
165
166
  await peer1.goOnline();
166
167
 
167
- await expect
168
- .poll(() => peer1._networkManager.getSwarm(topic)?._peers.get({ peerKey: peer2.peerId.toHex() })?.advertizing, {
169
- timeout: 2_000,
170
- })
171
- .toBe(true);
172
- await expect
173
- .poll(() => peer2._networkManager.getSwarm(topic)?._peers.get({ peerKey: peer1.peerId.toHex() })?.advertizing, {
174
- timeout: 2_000,
175
- })
176
- .toBe(true);
168
+ await waitForExpect(() => {
169
+ expect(peer1._networkManager.getSwarm(topic)?._peers.get({ peerKey: peer2.peerId.toHex() })?.advertizing).to.be
170
+ .true;
171
+ expect(peer2._networkManager.getSwarm(topic)?._peers.get({ peerKey: peer1.peerId.toHex() })?.advertizing).to.be
172
+ .true;
173
+ }, 2_000);
177
174
 
178
175
  await exchangeMessages(swarm1, swarm2);
179
176
  await leaveSwarm([peer1, peer2], topic);
180
- });
177
+ })
178
+ .tag('flaky')
179
+ .timeout(2_000);
181
180
 
182
181
  // TODO(mykola): Fails with large amount of peers ~10.
183
- test.skip('many peers and connections', async () => {
182
+ test('many peers and connections', async () => {
184
183
  const numTopics = 2;
185
184
  const peersPerTopic = 3;
186
185
  const swarmsAllPeersConnected: Promise<any>[] = [];
@@ -208,5 +207,5 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
208
207
  );
209
208
 
210
209
  await asyncTimeout(Promise.all(swarmsAllPeersConnected), 2_000);
211
- });
210
+ }).tag('stress');
212
211
  };