@dxos/network-manager 2.33.9-dev.7d11f506 → 2.33.9-dev.9bbef4e2

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 (158) hide show
  1. package/dist/src/network-manager.blueprint-test.d.ts +3 -1
  2. package/dist/src/network-manager.blueprint-test.d.ts.map +1 -1
  3. package/dist/src/network-manager.blueprint-test.js +46 -17
  4. package/dist/src/network-manager.blueprint-test.js.map +1 -1
  5. package/dist/src/network-manager.browser-test.js +1 -1
  6. package/dist/src/network-manager.browser-test.js.map +1 -1
  7. package/dist/src/network-manager.d.ts.map +1 -1
  8. package/dist/src/network-manager.js +13 -12
  9. package/dist/src/network-manager.js.map +1 -1
  10. package/dist/src/network-manager.test.js +5 -4
  11. package/dist/src/network-manager.test.js.map +1 -1
  12. package/dist/src/proto/gen/dxos/credentials.d.ts +39 -0
  13. package/dist/src/proto/gen/dxos/credentials.d.ts.map +1 -1
  14. package/dist/src/proto/gen/dxos/halo/keys.d.ts +44 -2
  15. package/dist/src/proto/gen/dxos/halo/keys.d.ts.map +1 -1
  16. package/dist/src/proto/gen/dxos/halo/keys.js +4 -0
  17. package/dist/src/proto/gen/dxos/halo/keys.js.map +1 -1
  18. package/dist/src/proto/gen/dxos/mesh/signal.d.ts +74 -16
  19. package/dist/src/proto/gen/dxos/mesh/signal.d.ts.map +1 -1
  20. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts +79 -0
  21. package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts.map +1 -0
  22. package/dist/src/proto/gen/dxos/mesh/signalMessage.js +3 -0
  23. package/dist/src/proto/gen/dxos/mesh/signalMessage.js.map +1 -0
  24. package/dist/src/proto/gen/google/protobuf.d.ts +8 -2
  25. package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
  26. package/dist/src/proto/gen/index.d.ts +17 -4
  27. package/dist/src/proto/gen/index.d.ts.map +1 -1
  28. package/dist/src/proto/gen/index.js +1 -1
  29. package/dist/src/proto/gen/index.js.map +1 -1
  30. package/dist/src/proto/substitutions.d.ts +4 -0
  31. package/dist/src/proto/substitutions.d.ts.map +1 -1
  32. package/dist/src/proto/substitutions.js +3 -1
  33. package/dist/src/proto/substitutions.js.map +1 -1
  34. package/dist/src/protocol-factory.js +3 -3
  35. package/dist/src/protocol-factory.js.map +1 -1
  36. package/dist/src/signal/in-memory-signal-manager.d.ts +7 -7
  37. package/dist/src/signal/in-memory-signal-manager.d.ts.map +1 -1
  38. package/dist/src/signal/in-memory-signal-manager.js +34 -13
  39. package/dist/src/signal/in-memory-signal-manager.js.map +1 -1
  40. package/dist/src/signal/index.d.ts +1 -2
  41. package/dist/src/signal/index.d.ts.map +1 -1
  42. package/dist/src/signal/index.js +1 -2
  43. package/dist/src/signal/index.js.map +1 -1
  44. package/dist/src/signal/integration.test.d.ts +2 -0
  45. package/dist/src/signal/integration.test.d.ts.map +1 -0
  46. package/dist/src/signal/integration.test.js +102 -0
  47. package/dist/src/signal/integration.test.js.map +1 -0
  48. package/dist/src/signal/message-router.d.ts +20 -8
  49. package/dist/src/signal/message-router.d.ts.map +1 -1
  50. package/dist/src/signal/message-router.js +96 -17
  51. package/dist/src/signal/message-router.js.map +1 -1
  52. package/dist/src/signal/message-router.test.js +125 -22
  53. package/dist/src/signal/message-router.test.js.map +1 -1
  54. package/dist/src/signal/signal-client.d.ts +33 -17
  55. package/dist/src/signal/signal-client.d.ts.map +1 -1
  56. package/dist/src/signal/signal-client.js +102 -82
  57. package/dist/src/signal/signal-client.js.map +1 -1
  58. package/dist/src/signal/signal-client.test.js +60 -75
  59. package/dist/src/signal/signal-client.test.js.map +1 -1
  60. package/dist/src/signal/{websocket-signal-manager.d.ts → signal-manager-impl.d.ts} +13 -11
  61. package/dist/src/signal/signal-manager-impl.d.ts.map +1 -0
  62. package/dist/src/signal/signal-manager-impl.js +151 -0
  63. package/dist/src/signal/signal-manager-impl.js.map +1 -0
  64. package/dist/src/signal/signal-manager.d.ts +12 -11
  65. package/dist/src/signal/signal-manager.d.ts.map +1 -1
  66. package/dist/src/signal/signal-rpc-client.d.ts +19 -0
  67. package/dist/src/signal/signal-rpc-client.d.ts.map +1 -0
  68. package/dist/src/signal/signal-rpc-client.js +108 -0
  69. package/dist/src/signal/signal-rpc-client.js.map +1 -0
  70. package/dist/src/signal/signal-rpc-client.test.d.ts +2 -0
  71. package/dist/src/signal/signal-rpc-client.test.d.ts.map +1 -0
  72. package/dist/src/signal/signal-rpc-client.test.js +74 -0
  73. package/dist/src/signal/signal-rpc-client.test.js.map +1 -0
  74. package/dist/src/swarm/connection.d.ts +3 -3
  75. package/dist/src/swarm/connection.d.ts.map +1 -1
  76. package/dist/src/swarm/connection.js +8 -11
  77. package/dist/src/swarm/connection.js.map +1 -1
  78. package/dist/src/swarm/swarm.d.ts +6 -7
  79. package/dist/src/swarm/swarm.d.ts.map +1 -1
  80. package/dist/src/swarm/swarm.js +29 -25
  81. package/dist/src/swarm/swarm.js.map +1 -1
  82. package/dist/src/swarm/swarm.test.js +156 -115
  83. package/dist/src/swarm/swarm.test.js.map +1 -1
  84. package/dist/src/testing/test-protocol.d.ts.map +1 -1
  85. package/dist/src/testing/test-protocol.js +3 -3
  86. package/dist/src/testing/test-protocol.js.map +1 -1
  87. package/dist/src/topology/fully-connected-topology.d.ts +0 -1
  88. package/dist/src/topology/fully-connected-topology.d.ts.map +1 -1
  89. package/dist/src/topology/fully-connected-topology.js +4 -9
  90. package/dist/src/topology/fully-connected-topology.js.map +1 -1
  91. package/dist/src/topology/mmst-topology.d.ts +0 -1
  92. package/dist/src/topology/mmst-topology.d.ts.map +1 -1
  93. package/dist/src/topology/mmst-topology.js +6 -11
  94. package/dist/src/topology/mmst-topology.js.map +1 -1
  95. package/dist/src/topology/star-topology.d.ts +0 -1
  96. package/dist/src/topology/star-topology.d.ts.map +1 -1
  97. package/dist/src/topology/star-topology.js +5 -10
  98. package/dist/src/topology/star-topology.js.map +1 -1
  99. package/dist/src/topology/topology.d.ts +0 -6
  100. package/dist/src/topology/topology.d.ts.map +1 -1
  101. package/dist/src/transport/in-memory-transport.d.ts +2 -2
  102. package/dist/src/transport/in-memory-transport.d.ts.map +1 -1
  103. package/dist/src/transport/in-memory-transport.js +2 -2
  104. package/dist/src/transport/in-memory-transport.js.map +1 -1
  105. package/dist/src/transport/transport.d.ts +3 -3
  106. package/dist/src/transport/transport.d.ts.map +1 -1
  107. package/dist/src/transport/webrtc-transport.d.ts +3 -3
  108. package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
  109. package/dist/src/transport/webrtc-transport.js +3 -3
  110. package/dist/src/transport/webrtc-transport.js.map +1 -1
  111. package/dist/tests-setup.js +1 -1
  112. package/dist/tsconfig.tsbuildinfo +1 -1
  113. package/package.json +17 -12
  114. package/src/network-manager.blueprint-test.ts +57 -22
  115. package/src/network-manager.browser-test.ts +1 -1
  116. package/src/network-manager.test.ts +8 -7
  117. package/src/network-manager.ts +10 -10
  118. package/src/proto/defs/dxos/mesh/signal.proto +54 -23
  119. package/src/proto/defs/dxos/mesh/signalMessage.proto +51 -0
  120. package/src/proto/gen/dxos/credentials.ts +40 -0
  121. package/src/proto/gen/dxos/halo/keys.ts +45 -2
  122. package/src/proto/gen/dxos/mesh/signal.ts +73 -16
  123. package/src/proto/gen/dxos/mesh/signalMessage.ts +83 -0
  124. package/src/proto/gen/google/protobuf.ts +9 -2
  125. package/src/proto/gen/index.ts +18 -5
  126. package/src/proto/substitutions.ts +3 -1
  127. package/src/protocol-factory.ts +1 -1
  128. package/src/signal/in-memory-signal-manager.ts +38 -13
  129. package/src/signal/index.ts +1 -2
  130. package/src/signal/integration.test.ts +117 -0
  131. package/src/signal/message-router.test.ts +169 -58
  132. package/src/signal/message-router.ts +120 -27
  133. package/src/signal/signal-client.test.ts +70 -90
  134. package/src/signal/signal-client.ts +120 -87
  135. package/src/signal/signal-manager-impl.ts +166 -0
  136. package/src/signal/signal-manager.ts +12 -12
  137. package/src/signal/signal-rpc-client.test.ts +86 -0
  138. package/src/signal/signal-rpc-client.ts +121 -0
  139. package/src/swarm/connection.ts +6 -9
  140. package/src/swarm/swarm.test.ts +208 -167
  141. package/src/swarm/swarm.ts +26 -22
  142. package/src/testing/test-protocol.ts +1 -1
  143. package/src/topology/fully-connected-topology.ts +2 -10
  144. package/src/topology/mmst-topology.ts +2 -10
  145. package/src/topology/star-topology.ts +2 -8
  146. package/src/topology/topology.ts +0 -7
  147. package/src/transport/in-memory-transport.ts +3 -3
  148. package/src/transport/transport.ts +3 -3
  149. package/src/transport/webrtc-transport.ts +4 -4
  150. package/dist/src/signal/websocket-rpc.d.ts +0 -30
  151. package/dist/src/signal/websocket-rpc.d.ts.map +0 -1
  152. package/dist/src/signal/websocket-rpc.js +0 -203
  153. package/dist/src/signal/websocket-rpc.js.map +0 -1
  154. package/dist/src/signal/websocket-signal-manager.d.ts.map +0 -1
  155. package/dist/src/signal/websocket-signal-manager.js +0 -134
  156. package/dist/src/signal/websocket-signal-manager.js.map +0 -1
  157. package/src/signal/websocket-rpc.ts +0 -208
  158. package/src/signal/websocket-signal-manager.ts +0 -158
@@ -12,7 +12,7 @@ import { Protocol } from '@dxos/mesh-protocol';
12
12
  import { PublicKey } from '@dxos/protocols';
13
13
  import { afterTest } from '@dxos/testutils';
14
14
 
15
- import { Message } from '../proto/gen/dxos/mesh/signal';
15
+ import { SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
16
16
  import { SignalMessaging } from '../signal';
17
17
  import { MessageRouter } from '../signal/message-router';
18
18
  import { FullyConnectedTopology } from '../topology';
@@ -21,173 +21,214 @@ import { Swarm } from './swarm';
21
21
 
22
22
  const log = debug('dxos:network-manager:swarm:test');
23
23
 
24
- class MockSignalConnection implements SignalMessaging {
25
- constructor (
26
- readonly _swarm: () => Swarm,
27
- readonly _delay = 10
28
- ) {}
29
-
30
- async offer (msg: Message) {
31
- await sleep(this._delay);
32
- return this._swarm().onOffer(msg);
24
+ describe('Swarm', () => {
25
+ class MockSignalConnection implements SignalMessaging {
26
+ constructor (
27
+ readonly _swarm: () => Swarm,
28
+ readonly _delay = 10
29
+ ) {}
30
+
31
+ async offer (msg: SignalMessage) {
32
+ await sleep(this._delay);
33
+ return this._swarm().onOffer(msg);
34
+ }
35
+
36
+ async signal (msg: SignalMessage) {
37
+ await sleep(this._delay);
38
+ await this._swarm().onSignal(msg);
39
+ }
33
40
  }
34
41
 
35
- async signal (msg: Message) {
36
- await sleep(this._delay);
37
- await this._swarm().onSignal(msg);
38
- }
39
- }
40
-
41
- const setup = ({ router = false } = {}) => {
42
- const topic = PublicKey.random();
43
- const peerId1 = PublicKey.random();
44
- const peerId2 = PublicKey.random();
45
- // eslint-disable-next-line prefer-const
46
- let swarm1: Swarm;
47
- // eslint-disable-next-line prefer-const
48
- let swarm2: Swarm;
49
-
50
- const mr1: MessageRouter = new MessageRouter({
51
- sendMessage: msg => mr2.receiveMessage(msg),
52
- onSignal: msg => swarm1.onSignal(msg),
53
- onOffer: msg => swarm1.onOffer(msg)
54
- });
55
-
56
- const mr2: MessageRouter = new MessageRouter({
57
- sendMessage: msg => mr1.receiveMessage(msg),
58
- onSignal: msg => swarm2.onSignal(msg),
59
- onOffer: msg => swarm2.onOffer(msg)
60
- });
61
-
62
- const sm1: SignalMessaging = router ? mr1 : new MockSignalConnection(() => swarm2);
63
-
64
- const sm2: SignalMessaging = router ? mr2 : new MockSignalConnection(() => swarm1);
65
-
66
- swarm1 = new Swarm(
67
- topic,
68
- peerId1,
69
- new FullyConnectedTopology(),
70
- () => new Protocol(),
71
- sm1,
72
- () => {},
73
- createWebRTCTransportFactory(),
74
- undefined
75
- );
76
-
77
- swarm2 = new Swarm(
78
- topic,
79
- peerId2,
80
- new FullyConnectedTopology(),
81
- () => new Protocol(),
82
- sm2,
83
- () => {},
84
- createWebRTCTransportFactory(),
85
- undefined
86
- );
87
-
88
- afterTest(async () => {
42
+ const setup = ({ router = false } = {}) => {
43
+ const topic = PublicKey.random();
44
+ const peerId1 = PublicKey.random();
45
+ const peerId2 = PublicKey.random();
46
+ // eslint-disable-next-line prefer-const
47
+ let swarm1: Swarm;
48
+ // eslint-disable-next-line prefer-const
49
+ let swarm2: Swarm;
50
+
51
+ const mr1: MessageRouter = new MessageRouter({
52
+ sendMessage: msg => mr2.receiveMessage(msg),
53
+ onSignal: msg => swarm1.onSignal(msg),
54
+ onOffer: msg => swarm1.onOffer(msg)
55
+ });
56
+ afterTest(() => mr1.destroy());
57
+
58
+ const mr2: MessageRouter = new MessageRouter({
59
+ sendMessage: msg => mr1.receiveMessage(msg),
60
+ onSignal: msg => swarm2.onSignal(msg),
61
+ onOffer: msg => swarm2.onOffer(msg)
62
+ });
63
+ afterTest(() => mr2.destroy());
64
+
65
+ const sm1: SignalMessaging = router ? mr1 : new MockSignalConnection(() => swarm2);
66
+
67
+ const sm2: SignalMessaging = router ? mr2 : new MockSignalConnection(() => swarm1);
68
+
69
+ swarm1 = new Swarm(
70
+ topic,
71
+ peerId1,
72
+ new FullyConnectedTopology(),
73
+ () => new Protocol(),
74
+ sm1,
75
+ createWebRTCTransportFactory(),
76
+ undefined
77
+ );
78
+
79
+ swarm2 = new Swarm(
80
+ topic,
81
+ peerId2,
82
+ new FullyConnectedTopology(),
83
+ () => new Protocol(),
84
+ sm2,
85
+ createWebRTCTransportFactory(),
86
+ undefined
87
+ );
88
+
89
+ afterTest(async () => {
90
+ await swarm1.destroy();
91
+ await swarm2.destroy();
92
+ });
93
+
94
+ return { swarm1, swarm2, peerId1, peerId2 };
95
+ };
96
+
97
+ test('connects two peers in a swarm', async () => {
98
+ const { swarm1, swarm2, peerId1, peerId2 } = setup();
99
+
100
+ expect(swarm1.connections.length).toEqual(0);
101
+ expect(swarm2.connections.length).toEqual(0);
102
+
103
+ const promise = Promise.all([
104
+ promiseTimeout(swarm1.connected.waitForCount(1), 3000, new Error('Swarm1 connect timeout.')),
105
+ promiseTimeout(swarm2.connected.waitForCount(1), 3000, new Error('Swarm2 connect timeout.'))
106
+ ]);
107
+
108
+ // Behavior of the Signal Server.
109
+ swarm1.onSwarmEvent({
110
+ peerAvailable: {
111
+ peer: peerId1.asUint8Array(),
112
+ since: new Date()
113
+ }
114
+ });
115
+
116
+ swarm1.onSwarmEvent({
117
+ peerAvailable: {
118
+ peer: peerId2.asUint8Array(),
119
+ since: new Date()
120
+ }
121
+ });
122
+
123
+ log('Candidates changed');
124
+ await promise;
125
+ log('Swarms connected');
126
+
127
+ const swarm1Connection = swarm1.connections[0];
128
+ const swarm2Connection = swarm2.connections[0];
129
+ const onData = mockFn<(data: Buffer) => void>().returns(undefined);
130
+ (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
131
+
132
+ const data = Buffer.from('1234');
133
+ (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
134
+ await waitForExpect(() => {
135
+ expect(onData).toHaveBeenCalledWith([data]);
136
+ });
137
+ }).timeout(5_000);
138
+
139
+ test('two peers try to originate connections to each other simultaneously', async () => {
140
+ const { swarm1, swarm2, peerId1, peerId2 } = setup();
141
+
142
+ expect(swarm1.connections.length).toEqual(0);
143
+ expect(swarm2.connections.length).toEqual(0);
144
+
145
+ swarm1.onSwarmEvent({
146
+ peerAvailable: {
147
+ peer: peerId2.asUint8Array(),
148
+ since: new Date()
149
+ }
150
+ });
151
+
152
+ swarm2.onSwarmEvent({
153
+ peerAvailable: {
154
+ peer: peerId1.asUint8Array(),
155
+ since: new Date()
156
+ }
157
+ });
158
+
159
+ await Promise.all([
160
+ swarm1.connected.waitForCount(1),
161
+ swarm2.connected.waitForCount(1)
162
+ ]);
163
+ }).timeout(5_000);
164
+
165
+ test('second peer discovered after delay', async () => {
166
+ const { swarm1, swarm2, peerId1, peerId2 } = setup();
167
+
168
+ expect(swarm1.connections.length).toEqual(0);
169
+ expect(swarm2.connections.length).toEqual(0);
170
+
171
+ swarm1.onSwarmEvent({
172
+ peerAvailable: {
173
+ peer: peerId2.asUint8Array(),
174
+ since: new Date()
175
+ }
176
+ });
177
+ await sleep(15);
178
+ swarm2.onSwarmEvent({
179
+ peerAvailable: {
180
+ peer: peerId1.asUint8Array(),
181
+ since: new Date()
182
+ }
183
+ });
184
+
185
+ await Promise.all([
186
+ swarm1.connected.waitForCount(1),
187
+ swarm1.connected.waitForCount(1)
188
+ ]);
189
+
190
+ const swarm1Connection = swarm1.connections[0];
191
+ const swarm2Connection = swarm2.connections[0];
192
+ const onData = mockFn<(data: Buffer) => void>().returns(undefined);
193
+ (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
194
+
195
+ const data = Buffer.from('1234');
196
+ (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
197
+ await waitForExpect(() => {
198
+ expect(onData).toHaveBeenCalledWith([data]);
199
+ });
200
+ }).timeout(5_000);
201
+
202
+ test('swarming with message router', async () => {
203
+ const { swarm1, swarm2, peerId2 } = setup({ router: true });
204
+
205
+ const promise = Promise.all([
206
+ promiseTimeout(swarm1.connected.waitForCount(1), 3000, new Error('Swarm1 connect timeout.')),
207
+ promiseTimeout(swarm2.connected.waitForCount(1), 3000, new Error('Swarm2 connect timeout.'))
208
+ ]);
209
+
210
+ swarm1.onSwarmEvent({
211
+ peerAvailable: {
212
+ peer: peerId2.asUint8Array(),
213
+ since: new Date()
214
+ }
215
+ });
216
+
217
+ log('Candidates changed');
218
+ await promise;
219
+ log('Swarms connected');
220
+
221
+ const swarm1Connection = swarm1.connections[0];
222
+ const swarm2Connection = swarm2.connections[0];
223
+ const onData = mockFn<(data: Buffer) => void>().returns(undefined);
224
+ (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
225
+
226
+ const data = Buffer.from('1234');
227
+ (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
228
+ await waitForExpect(() => {
229
+ expect(onData).toHaveBeenCalledWith([data]);
230
+ });
89
231
  await swarm1.destroy();
90
232
  await swarm2.destroy();
91
- });
92
-
93
- return { swarm1, swarm2, peerId1, peerId2 };
94
- };
95
-
96
- test('connects two peers in a swarm', async () => {
97
- const { swarm1, swarm2, peerId2 } = setup();
98
-
99
- expect(swarm1.connections.length).toEqual(0);
100
- expect(swarm2.connections.length).toEqual(0);
101
-
102
- const promise = Promise.all([
103
- promiseTimeout(swarm1.connected.waitForCount(1), 3000, new Error('Swarm1 connect timeout.')),
104
- promiseTimeout(swarm2.connected.waitForCount(1), 3000, new Error('Swarm2 connect timeout.'))
105
- ]);
106
-
107
- swarm1.onPeerCandidatesChanged([peerId2]);
108
-
109
- log('Candidates changed');
110
- await promise;
111
- log('Swarms connected');
112
-
113
- const swarm1Connection = swarm1.connections[0];
114
- const swarm2Connection = swarm2.connections[0];
115
- const onData = mockFn<(data: Buffer) => void>().returns(undefined);
116
- (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
117
-
118
- const data = Buffer.from('1234');
119
- (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
120
- await waitForExpect(() => {
121
- expect(onData).toHaveBeenCalledWith([data]);
122
- });
123
- }).timeout(5_000);
124
-
125
- test('two peers try to originate connections to each other simultaneously', async () => {
126
- const { swarm1, swarm2, peerId1, peerId2 } = setup();
127
-
128
- expect(swarm1.connections.length).toEqual(0);
129
- expect(swarm2.connections.length).toEqual(0);
130
-
131
- swarm1.onPeerCandidatesChanged([peerId2]);
132
- swarm2.onPeerCandidatesChanged([peerId1]);
133
-
134
- await Promise.all([
135
- swarm1.connected.waitForCount(1),
136
- swarm2.connected.waitForCount(1)
137
- ]);
138
- }).timeout(5_000);
139
-
140
- test('second peer discovered after delay', async () => {
141
- const { swarm1, swarm2, peerId1, peerId2 } = setup();
142
-
143
- expect(swarm1.connections.length).toEqual(0);
144
- expect(swarm2.connections.length).toEqual(0);
145
-
146
- swarm1.onPeerCandidatesChanged([peerId2]);
147
- await sleep(15);
148
- swarm2.onPeerCandidatesChanged([peerId1]);
149
-
150
- await Promise.all([
151
- swarm1.connected.waitForCount(1),
152
- swarm1.connected.waitForCount(1)
153
- ]);
154
-
155
- const swarm1Connection = swarm1.connections[0];
156
- const swarm2Connection = swarm2.connections[0];
157
- const onData = mockFn<(data: Buffer) => void>().returns(undefined);
158
- (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
159
-
160
- const data = Buffer.from('1234');
161
- (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
162
- await waitForExpect(() => {
163
- expect(onData).toHaveBeenCalledWith([data]);
164
- });
165
- }).timeout(5_000);
166
-
167
- test('swarming with message router', async () => {
168
- const { swarm1, swarm2, peerId2 } = setup({ router: true });
169
-
170
- const promise = Promise.all([
171
- promiseTimeout(swarm1.connected.waitForCount(1), 3000, new Error('Swarm1 connect timeout.')),
172
- promiseTimeout(swarm2.connected.waitForCount(1), 3000, new Error('Swarm2 connect timeout.'))
173
- ]);
174
-
175
- swarm1.onPeerCandidatesChanged([peerId2]);
176
-
177
- log('Candidates changed');
178
- await promise;
179
- log('Swarms connected');
180
-
181
- const swarm1Connection = swarm1.connections[0];
182
- const swarm2Connection = swarm2.connections[0];
183
- const onData = mockFn<(data: Buffer) => void>().returns(undefined);
184
- (swarm2Connection.transport as WebRTCTransport).peer!.on('data', onData);
185
-
186
- const data = Buffer.from('1234');
187
- (swarm1Connection.transport as WebRTCTransport).peer!.send(data);
188
- await waitForExpect(() => {
189
- expect(onData).toHaveBeenCalledWith([data]);
190
- });
191
- await swarm1.destroy();
192
- await swarm2.destroy();
193
- }).timeout(5_000);
233
+ }).timeout(5_000);
234
+ });
@@ -2,8 +2,8 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
5
  import debug from 'debug';
6
+ import assert from 'node:assert';
7
7
 
8
8
  import { Event } from '@dxos/async';
9
9
  import { discoveryKey } from '@dxos/crypto';
@@ -12,7 +12,8 @@ import { PublicKey } from '@dxos/protocols';
12
12
  import { ComplexMap, ComplexSet } from '@dxos/util';
13
13
 
14
14
  import { ProtocolProvider } from '../network-manager';
15
- import { Answer, Message } from '../proto/gen/dxos/mesh/signal';
15
+ import { SwarmEvent } from '../proto/gen/dxos/mesh/signal';
16
+ import { Answer, SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
16
17
  import { SignalMessaging } from '../signal';
17
18
  import { SwarmController, Topology } from '../topology';
18
19
  import { TransportFactory } from '../transport';
@@ -34,7 +35,6 @@ export class Swarm {
34
35
 
35
36
  private readonly _connections = new ComplexMap<PublicKey, Connection>(x => x.toHex());
36
37
  private readonly _discoveredPeers = new ComplexSet<PublicKey>(x => x.toHex());
37
- private readonly _peerCandidatesUpdated = new Event();
38
38
 
39
39
  get connections () {
40
40
  return Array.from(this._connections.values());
@@ -64,7 +64,6 @@ export class Swarm {
64
64
  private _topology: Topology,
65
65
  private readonly _protocolProvider: ProtocolProvider,
66
66
  private readonly _signalMessaging: SignalMessaging,
67
- private readonly _lookupPeers: (topic: PublicKey) => void,
68
67
  private readonly _transportFactory: TransportFactory,
69
68
  private readonly _label: string | undefined
70
69
  ) {
@@ -87,26 +86,33 @@ export class Swarm {
87
86
  return this._topic;
88
87
  }
89
88
 
90
- onPeerCandidatesChanged (candidates: PublicKey[]) {
91
- log(`New peers for ${this._topic} ${candidates}`);
92
- this._discoveredPeers.clear();
93
- for (const candidate of candidates) {
94
- if (candidate.equals(this._ownPeerId)) {
95
- continue;
89
+ onSwarmEvent (swarmEvent: SwarmEvent) {
90
+ log(`Swarm event ${JSON.stringify(swarmEvent)}`);
91
+ if (swarmEvent.peerAvailable) {
92
+ const peerId = PublicKey.from(swarmEvent.peerAvailable.peer);
93
+ log(`New peer for ${this._topic} ${peerId}`);
94
+ if (!peerId.equals(this._ownPeerId)) {
95
+ this._discoveredPeers.add(peerId);
96
96
  }
97
- this._discoveredPeers.add(candidate);
97
+ } else if (swarmEvent.peerLeft) {
98
+ this._discoveredPeers.delete(PublicKey.from(swarmEvent.peerLeft.peer));
98
99
  }
99
- this._peerCandidatesUpdated.emit();
100
100
  this._topology.update();
101
101
  }
102
102
 
103
- async onOffer (message: Message): Promise<Answer> {
104
- log(`Offer from ${message.id} topic=${this._topic}`);
103
+ async onOffer (message: SignalMessage): Promise<Answer> {
104
+ log(`Offer from ${JSON.stringify(message)}`);
105
105
  // Id of the peer offering us the connection.
106
106
  assert(message.id);
107
107
  const remoteId = message.id;
108
- assert(message.remoteId?.equals(this._ownPeerId));
109
- assert(message.topic?.equals(this._topic));
108
+ if (!message.remoteId?.equals(this._ownPeerId)) {
109
+ log(`Rejecting offer with incorrect peerId: ${message.remoteId}`);
110
+ return { accept: false };
111
+ }
112
+ if (!message.topic?.equals(this._topic)) {
113
+ log(`Rejecting offer with incorrect topic: ${message.topic}`);
114
+ return { accept: false };
115
+ }
110
116
 
111
117
  // Check if we are already trying to connect to that peer.
112
118
  if (this._connections.has(remoteId)) {
@@ -140,7 +146,7 @@ export class Swarm {
140
146
  return { accept };
141
147
  }
142
148
 
143
- async onSignal (message: Message): Promise<void> {
149
+ async onSignal (message: SignalMessage): Promise<void> {
144
150
  log(`Signal ${this._topic} ${JSON.stringify(message)}`);
145
151
  assert(message.remoteId?.equals(this._ownPeerId), `Invalid signal peer id expected=${this.ownPeerId}, actual=${message.remoteId}`);
146
152
  assert(message.topic?.equals(this._topic));
@@ -186,9 +192,6 @@ export class Swarm {
186
192
  this.errors.raise(err);
187
193
  }
188
194
  this._topology.update();
189
- },
190
- lookup: () => {
191
- this._lookupPeers(this._topic);
192
195
  }
193
196
  };
194
197
  }
@@ -201,6 +204,7 @@ export class Swarm {
201
204
 
202
205
  const sessionId = PublicKey.random();
203
206
 
207
+ log(`Initiate connection: topic=${this._topic} peerId=${remoteId} sessionId=${sessionId}`);
204
208
  const connection = this._createConnection(true, remoteId, sessionId);
205
209
  this._signalMessaging.offer({
206
210
  id: this._ownPeerId,
@@ -236,7 +240,7 @@ export class Swarm {
236
240
  }
237
241
 
238
242
  private _createConnection (initiator: boolean, remoteId: PublicKey, sessionId: PublicKey) {
239
- log(`Create connection topic=${this._topic} remoteId=${remoteId} initiator=${initiator}`);
243
+ log(`Create connection topic=${this._topic} ownId=${this._ownPeerId} remoteId=${remoteId} initiator=${initiator}`);
240
244
  assert(!this._connections.has(remoteId), 'Peer already connected.');
241
245
 
242
246
  const connection = new Connection(
@@ -245,7 +249,7 @@ export class Swarm {
245
249
  remoteId,
246
250
  sessionId,
247
251
  initiator,
248
- (msg: Message) => this._signalMessaging.signal(msg),
252
+ (msg: SignalMessage) => this._signalMessaging.signal(msg),
249
253
  this._protocolProvider({ channel: discoveryKey(this._topic), initiator }),
250
254
  this._transportFactory
251
255
  );
@@ -4,9 +4,9 @@
4
4
 
5
5
  // Test/mock Protocol implementation used in network-manager tests.
6
6
 
7
- import assert from 'assert';
8
7
  import debug from 'debug';
9
8
  import { EventEmitter } from 'events';
9
+ import assert from 'node:assert';
10
10
 
11
11
  import { Extension, Protocol } from '@dxos/mesh-protocol';
12
12
  import { PublicKey } from '@dxos/protocols';
@@ -2,7 +2,7 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
5
+ import assert from 'node:assert';
6
6
 
7
7
  import { PublicKey } from '@dxos/protocols';
8
8
 
@@ -11,15 +11,9 @@ import { SwarmController, Topology } from './topology';
11
11
  export class FullyConnectedTopology implements Topology {
12
12
  private _controller?: SwarmController;
13
13
 
14
- private _intervalId?: NodeJS.Timeout;
15
-
16
14
  init (controller: SwarmController): void {
17
15
  assert(!this._controller, 'Already initialized');
18
16
  this._controller = controller;
19
-
20
- this._intervalId = setInterval(() => {
21
- controller.lookup();
22
- }, 10_000);
23
17
  }
24
18
 
25
19
  update (): void {
@@ -35,9 +29,7 @@ export class FullyConnectedTopology implements Topology {
35
29
  }
36
30
 
37
31
  async destroy (): Promise<void> {
38
- if (this._intervalId !== undefined) {
39
- clearInterval(this._intervalId);
40
- }
32
+ // Nothing to do.
41
33
  }
42
34
 
43
35
  toString () {
@@ -2,8 +2,8 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
5
  import debug from 'debug';
6
+ import assert from 'node:assert';
7
7
  import distance from 'xor-distance';
8
8
 
9
9
  import { PublicKey } from '@dxos/protocols';
@@ -36,8 +36,6 @@ export class MMSTTopology implements Topology {
36
36
 
37
37
  private _controller?: SwarmController;
38
38
 
39
- private _lookupIntervalId?: NodeJS.Timeout;
40
-
41
39
  private _sampleCollected = false;
42
40
 
43
41
  constructor ({
@@ -53,10 +51,6 @@ export class MMSTTopology implements Topology {
53
51
  init (controller: SwarmController): void {
54
52
  assert(!this._controller, 'Already initialized');
55
53
  this._controller = controller;
56
-
57
- this._lookupIntervalId = setInterval(() => {
58
- controller.lookup();
59
- }, 10_000);
60
54
  }
61
55
 
62
56
  update (): void {
@@ -79,9 +73,7 @@ export class MMSTTopology implements Topology {
79
73
  }
80
74
 
81
75
  async destroy (): Promise<void> {
82
- if (this._lookupIntervalId !== undefined) {
83
- clearInterval(this._lookupIntervalId);
84
- }
76
+ // Nothing to do.
85
77
  }
86
78
 
87
79
  private _runAlgorithm () {
@@ -2,8 +2,8 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
5
  import debug from 'debug';
6
+ import assert from 'node:assert';
7
7
 
8
8
  import { PublicKey } from '@dxos/protocols';
9
9
 
@@ -13,7 +13,6 @@ const log = debug('dxos:network-manager:topology:star');
13
13
 
14
14
  export class StarTopology implements Topology {
15
15
  private _controller?: SwarmController;
16
- private _intervalId?: NodeJS.Timeout;
17
16
 
18
17
  constructor (
19
18
  private readonly _centralPeer: PublicKey
@@ -26,9 +25,6 @@ export class StarTopology implements Topology {
26
25
  init (controller: SwarmController): void {
27
26
  assert(!this._controller, 'Already initialized.');
28
27
  this._controller = controller;
29
- this._intervalId = setInterval(() => {
30
- controller.lookup();
31
- }, 10_000);
32
28
  }
33
29
 
34
30
  update (): void {
@@ -62,8 +58,6 @@ export class StarTopology implements Topology {
62
58
  }
63
59
 
64
60
  async destroy (): Promise<void> {
65
- if (this._intervalId !== undefined) {
66
- clearInterval(this._intervalId);
67
- }
61
+ // Nothing to do.
68
62
  }
69
63
  }
@@ -19,13 +19,6 @@ export interface SwarmController {
19
19
  * Disconnect from a peer.
20
20
  */
21
21
  disconnect(peer: PublicKey): void;
22
-
23
- /**
24
- * Trigger a lookup of any other peers swarming on this topic.
25
- *
26
- * Updates will be propagated through `update` method.
27
- */
28
- lookup(): void;
29
22
  }
30
23
 
31
24
  export interface SwarmState {
@@ -2,8 +2,8 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
5
  import debug from 'debug';
6
+ import assert from 'node:assert';
7
7
  import { Transform } from 'stream';
8
8
 
9
9
  import { Event } from '@dxos/async';
@@ -11,7 +11,7 @@ import { ErrorStream } from '@dxos/debug';
11
11
  import { PublicKey } from '@dxos/protocols';
12
12
  import { ComplexMap } from '@dxos/util';
13
13
 
14
- import { Message } from '../proto/gen/dxos/mesh/signal';
14
+ import { SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
15
15
  import { Transport, TransportFactory } from './transport';
16
16
 
17
17
  const log = debug('dxos:network-manager:swarm:transport:in-memory-transport');
@@ -79,7 +79,7 @@ export class InMemoryTransport implements Transport {
79
79
  return this._sessionId;
80
80
  }
81
81
 
82
- async signal (msg: Message) {
82
+ async signal (msg: SignalMessage) {
83
83
  // No-op.
84
84
  }
85
85