@dxos/network-manager 0.1.21 → 0.1.23
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.
- package/dist/lib/browser/index.mjs +39 -42
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +41 -44
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/node/index.cjs +39 -42
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +40 -43
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/types/src/swarm/swarm.d.ts +0 -1
- package/dist/types/src/swarm/swarm.d.ts.map +1 -1
- package/dist/types/src/testing/test-wire-protocol.d.ts.map +1 -1
- package/dist/types/src/tests/basic-test-suite.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/network-manager.ts +2 -2
- package/src/swarm/swarm.ts +16 -16
- package/src/testing/test-wire-protocol.ts +5 -2
- package/src/tests/basic-test-suite.ts +41 -17
- package/src/tests/webrtc-transport.test.ts +0 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../../../../src/swarm/swarm.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAG/D,OAAO,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAmB,QAAQ,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAQ3D;;;;GAIG;AACH,qBAAa,KAAK;
|
|
1
|
+
{"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../../../../src/swarm/swarm.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AAG/D,OAAO,EAAiB,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAmB,QAAQ,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAQ3D;;;;GAIG;AACH,qBAAa,KAAK;IAwCd,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAxCzB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgB;IAEhD,OAAO,CAAC,IAAI,CAAiB;IAE7B;;OAEG;IAEH,QAAQ,CAAC,UAAU,YAAsB;IAoBzC,QAAQ,CAAC,MAAM,cAAqB;gBAMjB,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,SAAS,EAC9B,SAAS,EAAE,QAAQ,EACV,iBAAiB,EAAE,oBAAoB,EACvC,UAAU,EAAE,SAAS,EACrB,iBAAiB,EAAE,gBAAgB,EACnC,MAAM,EAAE,MAAM,GAAG,SAAS;IAqB7C,IAAI,WAAW,iBAId;IAED,IACI,SAAS,cAEZ;IAED;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,IACI,KAAK,IAAI,KAAK,CAEjB;IAGK,OAAO;IAQP,WAAW,CAAC,QAAQ,EAAE,QAAQ;IAiBpC,YAAY,CAAC,UAAU,EAAE,UAAU;IA8B7B,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB/C,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/C,SAAS;IAOT,QAAQ;IAId,OAAO,CAAC,gBAAgB;YA8CV,YAAY;IAM1B,OAAO,CAAC,mBAAmB;IAuC3B;;OAEG;YACW,mBAAmB;YA0BnB,gBAAgB;CAQ/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-wire-protocol.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-wire-protocol.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"test-wire-protocol.d.ts","sourceRoot":"","sources":["../../../../src/testing/test-wire-protocol.ts"],"names":[],"mappings":"AAIA,OAAO,EAAgB,KAAK,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC,qBAAa,gBAAgB;aAIC,MAAM,EAAE,SAAS;IAH7C,SAAgB,WAAW,uCAA4D;IACvF,SAAgB,SAAS,mBAA0B;gBAEvB,MAAM,EAAE,SAAS;IAE7C,QAAQ,CAAC,OAAO,kDAUb;IAEG,iBAAiB,CAAC,MAAM,EAAE,SAAS;IAYnC,cAAc,CAAC,MAAM,EAAE,SAAS;CAIvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basic-test-suite.d.ts","sourceRoot":"","sources":["../../../../src/tests/basic-test-suite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"basic-test-suite.d.ts","sourceRoot":"","sources":["../../../../src/tests/basic-test-suite.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMzC;;GAEG;AACH,eAAO,MAAM,cAAc,gBAAiB,WAAW,6BA8JtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/network-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "Network Manager",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -25,20 +25,20 @@
|
|
|
25
25
|
"simple-peer": "9.11.0",
|
|
26
26
|
"ws": "^7.4.4",
|
|
27
27
|
"xor-distance": "^2.0.0",
|
|
28
|
-
"@dxos/async": "0.1.
|
|
29
|
-
"@dxos/codec-protobuf": "0.1.
|
|
30
|
-
"@dxos/context": "0.1.
|
|
31
|
-
"@dxos/credentials": "0.1.
|
|
32
|
-
"@dxos/crypto": "0.1.
|
|
33
|
-
"@dxos/debug": "0.1.
|
|
34
|
-
"@dxos/keys": "0.1.
|
|
35
|
-
"@dxos/log": "0.1.
|
|
36
|
-
"@dxos/messaging": "0.1.
|
|
37
|
-
"@dxos/node-std": "0.1.
|
|
38
|
-
"@dxos/protocols": "0.1.
|
|
39
|
-
"@dxos/rpc": "0.1.
|
|
40
|
-
"@dxos/teleport": "0.1.
|
|
41
|
-
"@dxos/util": "0.1.
|
|
28
|
+
"@dxos/async": "0.1.23",
|
|
29
|
+
"@dxos/codec-protobuf": "0.1.23",
|
|
30
|
+
"@dxos/context": "0.1.23",
|
|
31
|
+
"@dxos/credentials": "0.1.23",
|
|
32
|
+
"@dxos/crypto": "0.1.23",
|
|
33
|
+
"@dxos/debug": "0.1.23",
|
|
34
|
+
"@dxos/keys": "0.1.23",
|
|
35
|
+
"@dxos/log": "0.1.23",
|
|
36
|
+
"@dxos/messaging": "0.1.23",
|
|
37
|
+
"@dxos/node-std": "0.1.23",
|
|
38
|
+
"@dxos/protocols": "0.1.23",
|
|
39
|
+
"@dxos/rpc": "0.1.23",
|
|
40
|
+
"@dxos/teleport": "0.1.23",
|
|
41
|
+
"@dxos/util": "0.1.23"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@swc-node/register": "^1.5.4",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"earljs": "~0.1.10",
|
|
49
49
|
"fast-check": "~3.3.0",
|
|
50
50
|
"typescript": "^4.8.4",
|
|
51
|
-
"@dxos/signal": "0.1.
|
|
51
|
+
"@dxos/signal": "0.1.23"
|
|
52
52
|
},
|
|
53
53
|
"publishConfig": {
|
|
54
54
|
"access": "public"
|
package/src/network-manager.ts
CHANGED
|
@@ -213,17 +213,17 @@ export class NetworkManager {
|
|
|
213
213
|
case ConnectionState.OFFLINE: {
|
|
214
214
|
this._connectionState = state;
|
|
215
215
|
// go offline
|
|
216
|
+
await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOffline()));
|
|
216
217
|
await this._messenger.close();
|
|
217
218
|
await this._signalManager.close();
|
|
218
|
-
await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOffline()));
|
|
219
219
|
break;
|
|
220
220
|
}
|
|
221
221
|
case ConnectionState.ONLINE: {
|
|
222
222
|
this._connectionState = state;
|
|
223
223
|
// go online
|
|
224
|
+
await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOnline()));
|
|
224
225
|
this._messenger.open();
|
|
225
226
|
await this._signalManager.open();
|
|
226
|
-
await Promise.all([...this._swarms.values()].map((swarm) => swarm.goOnline()));
|
|
227
227
|
break;
|
|
228
228
|
}
|
|
229
229
|
}
|
package/src/swarm/swarm.ts
CHANGED
|
@@ -33,7 +33,10 @@ const getClassName = (obj: any) => Object.getPrototypeOf(obj).constructor.name;
|
|
|
33
33
|
* Routes signal events and maintains swarm topology.
|
|
34
34
|
*/
|
|
35
35
|
export class Swarm {
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
readonly _peers = new ComplexMap<PublicKey, Peer>(PublicKey.hash);
|
|
37
40
|
|
|
38
41
|
private readonly _swarmMessenger: MessageRouter;
|
|
39
42
|
|
|
@@ -148,11 +151,12 @@ export class Swarm {
|
|
|
148
151
|
onSwarmEvent(swarmEvent: SwarmEvent) {
|
|
149
152
|
log('swarm event', { swarmEvent }); // TODO(burdon): Stringify.
|
|
150
153
|
|
|
154
|
+
if (this._ctx.disposed) {
|
|
155
|
+
log.warn('ignored for offline swarm');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
151
159
|
if (swarmEvent.peerAvailable) {
|
|
152
|
-
if (this._ctx.disposed) {
|
|
153
|
-
log.warn('ignored for offline swarm');
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
160
|
const peerId = PublicKey.from(swarmEvent.peerAvailable.peer);
|
|
157
161
|
log('new peer', { peerId });
|
|
158
162
|
if (!peerId.equals(this._ownPeerId)) {
|
|
@@ -163,7 +167,7 @@ export class Swarm {
|
|
|
163
167
|
const peer = this._peers.get(PublicKey.from(swarmEvent.peerLeft.peer));
|
|
164
168
|
if (peer) {
|
|
165
169
|
peer.advertizing = false;
|
|
166
|
-
if (
|
|
170
|
+
if (peer.connection?.state !== ConnectionState.CONNECTED) {
|
|
167
171
|
// Destroy peer only if there is no p2p-connection established
|
|
168
172
|
void this._destroyPeer(peer.id).catch((err) => log.catch(err));
|
|
169
173
|
}
|
|
@@ -198,6 +202,7 @@ export class Swarm {
|
|
|
198
202
|
return answer;
|
|
199
203
|
}
|
|
200
204
|
|
|
205
|
+
@synchronized
|
|
201
206
|
async onSignal(message: SignalMessage): Promise<void> {
|
|
202
207
|
log('signal', { message });
|
|
203
208
|
if (this._ctx.disposed) {
|
|
@@ -216,23 +221,16 @@ export class Swarm {
|
|
|
216
221
|
}
|
|
217
222
|
|
|
218
223
|
// For debug purposes
|
|
224
|
+
@synchronized
|
|
219
225
|
async goOffline() {
|
|
220
226
|
await this._ctx.dispose();
|
|
221
|
-
[...this._peers.
|
|
222
|
-
peer.advertizing = false;
|
|
223
|
-
});
|
|
224
|
-
await Promise.all([...this._peers.keys()].map((peerId) => this._closeConnection(peerId)));
|
|
227
|
+
await Promise.all([...this._peers.keys()].map((peerId) => this._destroyPeer(peerId)));
|
|
225
228
|
}
|
|
226
229
|
|
|
227
230
|
// For debug purposes
|
|
228
231
|
@synchronized
|
|
229
232
|
async goOnline() {
|
|
230
233
|
this._ctx = new Context();
|
|
231
|
-
|
|
232
|
-
[...this._peers.values()].forEach((peer) => {
|
|
233
|
-
peer.advertizing = true;
|
|
234
|
-
});
|
|
235
|
-
this._topology.update();
|
|
236
234
|
}
|
|
237
235
|
|
|
238
236
|
private _getOrCreatePeer(peerId: PublicKey): Peer {
|
|
@@ -330,13 +328,15 @@ export class Swarm {
|
|
|
330
328
|
* Creates a connection then sends message over signal network.
|
|
331
329
|
*/
|
|
332
330
|
private async _initiateConnection(remoteId: PublicKey) {
|
|
331
|
+
const ctx = this._ctx; // Copy to avoid getting reset while sleeping.
|
|
332
|
+
|
|
333
333
|
// It is likely that the other peer will also try to connect to us at the same time.
|
|
334
334
|
// If our peerId is higher, we will wait for a bit so that other peer has a chance to connect first.
|
|
335
335
|
if (remoteId.toHex() < this._ownPeerId.toHex()) {
|
|
336
336
|
log('initiation delay', { remoteId });
|
|
337
337
|
await sleep(INITIATION_DELAY);
|
|
338
338
|
}
|
|
339
|
-
if (
|
|
339
|
+
if (ctx.disposed) {
|
|
340
340
|
return;
|
|
341
341
|
}
|
|
342
342
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Event } from '@dxos/async';
|
|
5
|
+
import { asyncTimeout, Event } from '@dxos/async';
|
|
6
6
|
import { PublicKey } from '@dxos/keys';
|
|
7
7
|
import { log } from '@dxos/log';
|
|
8
8
|
import { TestExtension } from '@dxos/teleport';
|
|
@@ -33,7 +33,10 @@ export class TestWireProtocol {
|
|
|
33
33
|
return this.connections.get(peerId)!;
|
|
34
34
|
}
|
|
35
35
|
log('waitForConnection', { peerId });
|
|
36
|
-
await
|
|
36
|
+
await asyncTimeout(
|
|
37
|
+
this.connected.waitFor((connectedId) => connectedId.equals(peerId)),
|
|
38
|
+
1_000
|
|
39
|
+
);
|
|
37
40
|
return this.connections.get(peerId)!;
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { expect } from 'chai';
|
|
6
|
+
import waitForExpect from 'wait-for-expect';
|
|
6
7
|
|
|
7
8
|
import { PublicKey } from '@dxos/keys';
|
|
8
9
|
import { log } from '@dxos/log';
|
|
@@ -109,27 +110,50 @@ export const basicTestSuite = (testBuilder: TestBuilder, runTests = true) => {
|
|
|
109
110
|
]);
|
|
110
111
|
});
|
|
111
112
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
// TODO(mykola): Flaky test because of test signal server.
|
|
114
|
+
test
|
|
115
|
+
.skip('going offline and back online', async () => {
|
|
116
|
+
const peer1 = testBuilder.createPeer();
|
|
117
|
+
const peer2 = testBuilder.createPeer();
|
|
118
|
+
await openAndCloseAfterTest([peer1, peer2]);
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
const topic = PublicKey.random();
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
const [swarm1, swarm2] = await joinSwarm([peer1, peer2], topic);
|
|
123
|
+
await exchangeMessages(swarm1, swarm2);
|
|
121
124
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
await peer1.goOnline();
|
|
125
|
+
//
|
|
126
|
+
// Going offline and back online
|
|
127
|
+
//
|
|
128
|
+
const connectionDropped = peer2._networkManager
|
|
129
|
+
.getSwarm(topic)
|
|
130
|
+
?.disconnected.waitFor((peerId) => peerId.equals(peer1.peerId));
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
const peerLeft = peer2._networkManager.signalManager.swarmEvent.waitFor(
|
|
133
|
+
(event) => !!event.swarmEvent.peerLeft && peer1.peerId.equals(event.swarmEvent.peerLeft?.peer)
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
await peer1.goOffline();
|
|
137
|
+
await connectionDropped;
|
|
138
|
+
await peerLeft;
|
|
139
|
+
|
|
140
|
+
// Wait for peer to be removed from the swarm.
|
|
141
|
+
await waitForExpect(() => {
|
|
142
|
+
expect(!!peer2._networkManager.getSwarm(topic)!._peers.get(peer1.peerId)?.advertizing).to.be.false;
|
|
143
|
+
}, 1_000);
|
|
144
|
+
|
|
145
|
+
await peer1.goOnline();
|
|
146
|
+
|
|
147
|
+
await waitForExpect(() => {
|
|
148
|
+
expect(peer1._networkManager.getSwarm(topic)?._peers.get(peer2.peerId)?.advertizing).to.be.true;
|
|
149
|
+
|
|
150
|
+
expect(peer2._networkManager.getSwarm(topic)?._peers.get(peer1.peerId)?.advertizing).to.be.true;
|
|
151
|
+
}, 2_000);
|
|
152
|
+
|
|
153
|
+
await exchangeMessages(swarm1, swarm2);
|
|
154
|
+
await leaveSwarm([peer1, peer2], topic);
|
|
155
|
+
})
|
|
156
|
+
.timeout(2_000);
|
|
133
157
|
|
|
134
158
|
// TODO(mykola): broken.
|
|
135
159
|
test.skip('many peers and connections', async () => {
|
|
@@ -10,10 +10,7 @@ describe('WebRTC transport', () => {
|
|
|
10
10
|
basicTestSuite(testBuilder);
|
|
11
11
|
}).timeout(10_000);
|
|
12
12
|
|
|
13
|
-
/*
|
|
14
|
-
// TODO(burdon): Flaky.
|
|
15
13
|
describe('WebRTC transport proxy', () => {
|
|
16
14
|
const testBuilder = new TestBuilder({ signalHosts: [TEST_SIGNAL_URL], bridge: true });
|
|
17
15
|
basicTestSuite(testBuilder);
|
|
18
16
|
}).timeout(10_000);
|
|
19
|
-
*/
|