@dxos/network-manager 0.6.12-main.5cc132e → 0.6.12-main.78ddbdf
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/chunk-GW3YM55A.mjs +14 -0
- package/dist/lib/browser/chunk-GW3YM55A.mjs.map +7 -0
- package/dist/lib/browser/{chunk-NMDGRINN.mjs → chunk-YOKKEU6T.mjs} +1216 -1037
- package/dist/lib/browser/chunk-YOKKEU6T.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +10 -19
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing/index.mjs +18 -27
- package/dist/lib/browser/testing/index.mjs.map +3 -3
- package/dist/lib/browser/transport/tcp/index.mjs +39 -0
- package/dist/lib/browser/transport/tcp/index.mjs.map +7 -0
- package/dist/lib/node/{chunk-4K3JQNY3.cjs → chunk-7ZWQLO5T.cjs} +1229 -1177
- package/dist/lib/node/chunk-7ZWQLO5T.cjs.map +7 -0
- package/dist/lib/node/index.cjs +27 -37
- package/dist/lib/node/index.cjs.map +2 -2
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing/index.cjs +20 -29
- package/dist/lib/node/testing/index.cjs.map +3 -3
- package/dist/lib/node/transport/tcp/index.cjs +191 -0
- package/dist/lib/node/transport/tcp/index.cjs.map +7 -0
- package/dist/lib/node-esm/{chunk-X2RY5LSM.mjs → chunk-4VO725JT.mjs} +1249 -1185
- package/dist/lib/node-esm/chunk-4VO725JT.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +10 -19
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/testing/index.mjs +16 -26
- package/dist/lib/node-esm/testing/index.mjs.map +3 -3
- package/dist/lib/node-esm/transport/tcp/index.mjs +159 -0
- package/dist/lib/node-esm/transport/tcp/index.mjs.map +7 -0
- package/dist/types/src/swarm/connection.d.ts.map +1 -1
- package/dist/types/src/swarm/swarm.d.ts +1 -1
- package/dist/types/src/testing/test-builder.d.ts +2 -2
- package/dist/types/src/testing/test-builder.d.ts.map +1 -1
- package/dist/types/src/transport/index.d.ts +1 -5
- package/dist/types/src/transport/index.d.ts.map +1 -1
- package/dist/types/src/transport/memory-transport.d.ts +2 -2
- package/dist/types/src/transport/memory-transport.d.ts.map +1 -1
- package/dist/types/src/transport/tcp/index.d.ts +2 -0
- package/dist/types/src/transport/tcp/index.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp-transport.browser.d.ts → tcp/tcp-transport.browser.d.ts} +3 -3
- package/dist/types/src/transport/tcp/tcp-transport.browser.d.ts.map +1 -0
- package/dist/types/src/transport/{tcp-transport.d.ts → tcp/tcp-transport.d.ts} +3 -3
- package/dist/types/src/transport/tcp/tcp-transport.d.ts.map +1 -0
- package/dist/types/src/transport/transport.d.ts +7 -6
- package/dist/types/src/transport/transport.d.ts.map +1 -1
- package/dist/types/src/transport/webrtc/index.d.ts +4 -0
- package/dist/types/src/transport/webrtc/index.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts +14 -0
- package/dist/types/src/transport/webrtc/rtc-connection-factory.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts +68 -0
- package/dist/types/src/transport/webrtc/rtc-peer-connection.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts +33 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport-channel.test.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts +4 -0
- package/dist/types/src/transport/webrtc/rtc-transport-factory.d.ts.map +1 -0
- package/dist/types/src/transport/{simplepeer-transport-proxy.d.ts → webrtc/rtc-transport-proxy.d.ts} +10 -12
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport-proxy.test.d.ts.map +1 -0
- package/dist/types/src/transport/{simplepeer-transport-service.d.ts → webrtc/rtc-transport-service.d.ts} +9 -7
- package/dist/types/src/transport/webrtc/rtc-transport-service.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts +4 -0
- package/dist/types/src/transport/webrtc/rtc-transport-stats.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts +2 -0
- package/dist/types/src/transport/webrtc/rtc-transport.test.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/test-utils.d.ts +5 -0
- package/dist/types/src/transport/webrtc/test-utils.d.ts.map +1 -0
- package/dist/types/src/transport/webrtc/utils.d.ts +3 -0
- package/dist/types/src/transport/webrtc/utils.d.ts.map +1 -0
- package/package.json +44 -20
- package/src/signal/swarm-messenger.node.test.ts +1 -1
- package/src/swarm/connection.test.ts +61 -37
- package/src/swarm/connection.ts +5 -5
- package/src/swarm/swarm.test.ts +2 -3
- package/src/swarm/swarm.ts +1 -1
- package/src/testing/test-builder.ts +12 -28
- package/src/transport/index.ts +1 -5
- package/src/transport/memory-transport.ts +2 -0
- package/src/transport/tcp/index.ts +5 -0
- package/src/transport/{tcp-transport.browser.ts → tcp/tcp-transport.browser.ts} +7 -3
- package/src/transport/{tcp-transport.ts → tcp/tcp-transport.ts} +3 -1
- package/src/transport/transport.ts +8 -7
- package/src/transport/webrtc/index.ts +7 -0
- package/src/transport/webrtc/rtc-connection-factory.ts +82 -0
- package/src/transport/webrtc/rtc-peer-connection.ts +472 -0
- package/src/transport/webrtc/rtc-transport-channel.test.ts +176 -0
- package/src/transport/webrtc/rtc-transport-channel.ts +195 -0
- package/src/transport/webrtc/rtc-transport-factory.ts +28 -0
- package/src/transport/webrtc/rtc-transport-proxy.test.ts +413 -0
- package/src/transport/webrtc/rtc-transport-proxy.ts +264 -0
- package/src/transport/webrtc/rtc-transport-service.ts +192 -0
- package/src/transport/webrtc/rtc-transport-stats.ts +67 -0
- package/src/transport/webrtc/rtc-transport.test.ts +198 -0
- package/src/transport/webrtc/test-utils.ts +22 -0
- package/src/transport/webrtc/utils.ts +36 -0
- package/dist/lib/browser/chunk-NMDGRINN.mjs.map +0 -7
- package/dist/lib/node/chunk-4K3JQNY3.cjs.map +0 -7
- package/dist/lib/node-esm/chunk-X2RY5LSM.mjs.map +0 -7
- package/dist/types/src/transport/libdatachannel-transport.d.ts +0 -42
- package/dist/types/src/transport/libdatachannel-transport.d.ts.map +0 -1
- package/dist/types/src/transport/libdatachannel-transport.node.test.d.ts +0 -2
- package/dist/types/src/transport/libdatachannel-transport.node.test.d.ts.map +0 -1
- package/dist/types/src/transport/memory-transport.test.d.ts +0 -2
- package/dist/types/src/transport/memory-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-simple-peer.node.test.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-simple-peer.node.test.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-proxy.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-proxy.node.test.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-transport-proxy.node.test.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport-service.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport.d.ts +0 -36
- package/dist/types/src/transport/simplepeer-transport.d.ts.map +0 -1
- package/dist/types/src/transport/simplepeer-transport.test.d.ts +0 -2
- package/dist/types/src/transport/simplepeer-transport.test.d.ts.map +0 -1
- package/dist/types/src/transport/tcp-transport.browser.d.ts.map +0 -1
- package/dist/types/src/transport/tcp-transport.d.ts.map +0 -1
- package/dist/types/src/transport/webrtc.d.ts +0 -6
- package/dist/types/src/transport/webrtc.d.ts.map +0 -1
- package/src/transport/libdatachannel-transport.node.test.ts +0 -91
- package/src/transport/libdatachannel-transport.ts +0 -372
- package/src/transport/memory-transport.test.ts +0 -75
- package/src/transport/simplepeer-simple-peer.node.test.ts +0 -22
- package/src/transport/simplepeer-transport-proxy.node.test.ts +0 -180
- package/src/transport/simplepeer-transport-proxy.ts +0 -246
- package/src/transport/simplepeer-transport-service.ts +0 -160
- package/src/transport/simplepeer-transport.test.ts +0 -57
- package/src/transport/simplepeer-transport.ts +0 -250
- package/src/transport/webrtc.ts +0 -15
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TransportStats } from '../transport';
|
|
2
|
+
export declare const describeSelectedRemoteCandidate: (connection?: RTCPeerConnection) => Promise<string>;
|
|
3
|
+
export declare const createRtcTransportStats: (connection: RTCPeerConnection | undefined, topic: string) => Promise<TransportStats>;
|
|
4
|
+
//# sourceMappingURL=rtc-transport-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtc-transport-stats.d.ts","sourceRoot":"","sources":["../../../../../src/transport/webrtc/rtc-transport-stats.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,eAAO,MAAM,+BAA+B,gBAAuB,iBAAiB,KAAG,OAAO,CAAC,MAAM,CAYpG,CAAC;AAEF,eAAO,MAAM,uBAAuB,eACtB,iBAAiB,GAAG,SAAS,SAClC,MAAM,KACZ,OAAO,CAAC,cAAc,CAmBxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtc-transport.test.d.ts","sourceRoot":"","sources":["../../../../../src/transport/webrtc/rtc-transport.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../../../../src/transport/webrtc/test-utils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,eAAO,MAAM,mBAAmB,YAAa,SAAS;;CAWrD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/transport/webrtc/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB,aAAc,MAAM,YAAY,MAAM,WAAgD,CAAC;AAEvH,eAAO,MAAM,WAAW,SAAU,MAAM,QAAQ,MAAM,YAOrD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/network-manager",
|
|
3
|
-
"version": "0.6.12-main.
|
|
3
|
+
"version": "0.6.12-main.78ddbdf",
|
|
4
4
|
"description": "Network Manager",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
"browser": "./module-stub.js",
|
|
17
17
|
"workerd": "./module-stub.js",
|
|
18
18
|
"default": "node-datachannel/*"
|
|
19
|
+
},
|
|
20
|
+
"#tcp-transport": {
|
|
21
|
+
"browser": "./dist/lib/browser/transport/tcp/index.mjs",
|
|
22
|
+
"node": "./dist/lib/node/transport/tcp/index.cjs",
|
|
23
|
+
"import": "./dist/lib/browser/transport/tcp/index.mjs",
|
|
24
|
+
"require": "./dist/lib/node/transport/tcp/index.cjs",
|
|
25
|
+
"types": "./dist/types/src/transport/tcp/index.d.ts"
|
|
19
26
|
}
|
|
20
27
|
},
|
|
21
28
|
"exports": {
|
|
@@ -34,16 +41,27 @@
|
|
|
34
41
|
"default": "./dist/lib/node-esm/testing/index.mjs"
|
|
35
42
|
},
|
|
36
43
|
"types": "./dist/types/src/testing/index.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./tcp": {
|
|
46
|
+
"browser": "./dist/lib/browser/transport/tcp/index.mjs",
|
|
47
|
+
"node": {
|
|
48
|
+
"require": "./dist/lib/node/transport/tcp/index.cjs",
|
|
49
|
+
"default": "./dist/lib/node-esm/transport/tcp/index.mjs"
|
|
50
|
+
},
|
|
51
|
+
"types": "./dist/types/src/transport/tcp/index.d.ts"
|
|
37
52
|
}
|
|
38
53
|
},
|
|
39
54
|
"browser": {
|
|
40
|
-
"./src/transport/tcp-transport.ts": "./src/transport/tcp-transport.browser.ts"
|
|
55
|
+
"./src/transport/tcp/tcp-transport.ts": "./src/transport/tcp/tcp-transport.browser.ts"
|
|
41
56
|
},
|
|
42
57
|
"types": "dist/types/src/index.d.ts",
|
|
43
58
|
"typesVersions": {
|
|
44
59
|
"*": {
|
|
45
60
|
"testing": [
|
|
46
61
|
"dist/types/src/testing/index.d.ts"
|
|
62
|
+
],
|
|
63
|
+
"tcp": [
|
|
64
|
+
"dist/types/src/transport/tcp/index.d.ts"
|
|
47
65
|
]
|
|
48
66
|
}
|
|
49
67
|
},
|
|
@@ -54,29 +72,35 @@
|
|
|
54
72
|
"src"
|
|
55
73
|
],
|
|
56
74
|
"dependencies": {
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
75
|
+
"isomorphic-ws": "^5.0.0",
|
|
76
|
+
"nanomessage-rpc": "^3.0.0",
|
|
77
|
+
"node-datachannel": "^0.9.2",
|
|
78
|
+
"p-defer": "^3.0.0",
|
|
60
79
|
"stream": "^0.0.3",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"@dxos/
|
|
65
|
-
"@dxos/
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/
|
|
68
|
-
"@dxos/
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/
|
|
71
|
-
"@dxos/
|
|
72
|
-
"@dxos/
|
|
73
|
-
"@dxos/
|
|
80
|
+
"tiny-invariant": "^1.3.1",
|
|
81
|
+
"ws": "^8.14.2",
|
|
82
|
+
"xor-distance": "^2.0.0",
|
|
83
|
+
"@dxos/async": "0.6.12-main.78ddbdf",
|
|
84
|
+
"@dxos/codec-protobuf": "0.6.12-main.78ddbdf",
|
|
85
|
+
"@dxos/context": "0.6.12-main.78ddbdf",
|
|
86
|
+
"@dxos/invariant": "0.6.12-main.78ddbdf",
|
|
87
|
+
"@dxos/debug": "0.6.12-main.78ddbdf",
|
|
88
|
+
"@dxos/keys": "0.6.12-main.78ddbdf",
|
|
89
|
+
"@dxos/messaging": "0.6.12-main.78ddbdf",
|
|
90
|
+
"@dxos/log": "0.6.12-main.78ddbdf",
|
|
91
|
+
"@dxos/node-std": "0.6.12-main.78ddbdf",
|
|
92
|
+
"@dxos/rpc": "0.6.12-main.78ddbdf",
|
|
93
|
+
"@dxos/protocols": "0.6.12-main.78ddbdf",
|
|
94
|
+
"@dxos/teleport": "0.6.12-main.78ddbdf",
|
|
95
|
+
"@dxos/tracing": "0.6.12-main.78ddbdf",
|
|
96
|
+
"@dxos/util": "0.6.12-main.78ddbdf"
|
|
74
97
|
},
|
|
75
98
|
"devDependencies": {
|
|
76
|
-
"@
|
|
99
|
+
"@swc-node/register": "1.9.1",
|
|
100
|
+
"@types/ws": "^7.4.0",
|
|
77
101
|
"fast-check": "^3.19.0",
|
|
78
102
|
"fetch-mock": "^11.0.0",
|
|
79
|
-
"@dxos/signal": "0.6.12-main.
|
|
103
|
+
"@dxos/signal": "0.6.12-main.78ddbdf"
|
|
80
104
|
},
|
|
81
105
|
"publishConfig": {
|
|
82
106
|
"access": "public"
|
|
@@ -13,7 +13,7 @@ import { runTestSignalServer } from '@dxos/signal';
|
|
|
13
13
|
import { type OfferMessage, type SignalMessage } from './signal-messenger';
|
|
14
14
|
import { SwarmMessenger } from './swarm-messenger';
|
|
15
15
|
|
|
16
|
-
describe('SwarmMessenger', () => {
|
|
16
|
+
describe('SwarmMessenger', { timeout: 7000 }, () => {
|
|
17
17
|
let topic: PublicKey;
|
|
18
18
|
|
|
19
19
|
let broker1: Awaited<ReturnType<typeof runTestSignalServer>>;
|
|
@@ -9,72 +9,96 @@ import { PublicKey } from '@dxos/keys';
|
|
|
9
9
|
|
|
10
10
|
import { Connection } from './connection';
|
|
11
11
|
import { TestWireProtocol } from '../testing/test-wire-protocol';
|
|
12
|
-
import {
|
|
12
|
+
import { createRtcTransportFactory } from '../transport';
|
|
13
|
+
import { chooseInitiatorPeer } from '../transport/webrtc/utils';
|
|
13
14
|
|
|
14
15
|
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
|
+
|
|
15
24
|
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 }) => {
|
|
16
33
|
const [topic, sessionId] = PublicKey.randomSequence();
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const
|
|
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(
|
|
21
39
|
topic,
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
slowPeer,
|
|
41
|
+
fastPeer,
|
|
24
42
|
sessionId,
|
|
25
43
|
true,
|
|
26
44
|
{
|
|
27
|
-
offer: async (msg) => {
|
|
28
|
-
return { accept: true };
|
|
29
|
-
},
|
|
45
|
+
offer: async (msg) => ({ accept: true }),
|
|
30
46
|
signal: async (msg) => {
|
|
31
|
-
await
|
|
47
|
+
await fastConnection.signal(msg);
|
|
32
48
|
},
|
|
33
49
|
},
|
|
34
|
-
|
|
50
|
+
slowPeerProtocol.factory({
|
|
35
51
|
initiator: true,
|
|
36
|
-
localPeerId: PublicKey.from(
|
|
37
|
-
remotePeerId: PublicKey.from(
|
|
52
|
+
localPeerId: PublicKey.from(slowPeer.peerKey),
|
|
53
|
+
remotePeerId: PublicKey.from(fastPeer.peerKey),
|
|
38
54
|
topic,
|
|
39
55
|
}),
|
|
40
|
-
|
|
41
|
-
process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
|
|
56
|
+
createRtcTransportFactory(),
|
|
42
57
|
);
|
|
43
58
|
|
|
44
|
-
const
|
|
45
|
-
const
|
|
59
|
+
const fastPeerProtocol = new TestWireProtocol(PublicKey.from(fastPeer.peerKey));
|
|
60
|
+
const fastConnection = new Connection(
|
|
46
61
|
topic,
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
fastPeer,
|
|
63
|
+
slowPeer,
|
|
49
64
|
sessionId,
|
|
50
65
|
false,
|
|
51
66
|
{
|
|
52
|
-
offer: async (msg) => {
|
|
53
|
-
return { accept: true };
|
|
54
|
-
},
|
|
67
|
+
offer: async (msg) => ({ accept: true }),
|
|
55
68
|
signal: async (msg) => {
|
|
56
|
-
await
|
|
69
|
+
await slowConnection.signal(msg);
|
|
57
70
|
},
|
|
58
71
|
},
|
|
59
|
-
|
|
72
|
+
fastPeerProtocol.factory({
|
|
60
73
|
initiator: false,
|
|
61
|
-
localPeerId: PublicKey.from(
|
|
62
|
-
remotePeerId: PublicKey.from(
|
|
74
|
+
localPeerId: PublicKey.from(fastPeer.peerKey),
|
|
75
|
+
remotePeerId: PublicKey.from(slowPeer.peerKey),
|
|
63
76
|
topic,
|
|
64
77
|
}),
|
|
65
|
-
|
|
66
|
-
process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
|
|
78
|
+
createRtcTransportFactory(),
|
|
67
79
|
);
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
await
|
|
71
|
-
await sleep(
|
|
81
|
+
fastConnection.initiate();
|
|
82
|
+
await fastConnection.openConnection();
|
|
83
|
+
await sleep(200);
|
|
84
|
+
|
|
85
|
+
slowConnection.initiate();
|
|
86
|
+
await slowConnection.openConnection();
|
|
72
87
|
|
|
73
|
-
connection1.initiate();
|
|
74
|
-
await connection1.openConnection();
|
|
75
88
|
await Promise.all([
|
|
76
|
-
|
|
77
|
-
|
|
89
|
+
slowPeerProtocol.testConnection(PublicKey.from(fastPeer.peerKey), 'test message 1'),
|
|
90
|
+
fastPeerProtocol.testConnection(PublicKey.from(slowPeer.peerKey), 'test message 2'),
|
|
78
91
|
]);
|
|
79
|
-
}
|
|
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
|
+
};
|
|
80
104
|
});
|
package/src/swarm/connection.ts
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
ConnectionResetError,
|
|
16
16
|
ConnectivityError,
|
|
17
17
|
TimeoutError,
|
|
18
|
-
UnknownProtocolError,
|
|
19
18
|
trace,
|
|
20
19
|
} from '@dxos/protocols';
|
|
21
20
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
@@ -202,14 +201,15 @@ export class Connection {
|
|
|
202
201
|
|
|
203
202
|
invariant(!this._transport);
|
|
204
203
|
this._transport = this._transportFactory.createTransport({
|
|
204
|
+
ownPeerKey: this.localInfo.peerKey,
|
|
205
|
+
remotePeerKey: this.remoteInfo.peerKey,
|
|
206
|
+
topic: this.topic.toHex(),
|
|
205
207
|
initiator: this.initiator,
|
|
206
208
|
stream: this._protocol.stream,
|
|
207
209
|
sendSignal: async (signal) => this._sendSignal(signal),
|
|
208
210
|
sessionId: this.sessionId,
|
|
209
211
|
});
|
|
210
212
|
|
|
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,8 +238,6 @@ 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 });
|
|
243
241
|
}
|
|
244
242
|
|
|
245
243
|
if (this._state !== ConnectionState.CLOSED && this._state !== ConnectionState.CLOSING) {
|
|
@@ -248,6 +246,8 @@ export class Connection {
|
|
|
248
246
|
}
|
|
249
247
|
});
|
|
250
248
|
|
|
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?
|
package/src/swarm/swarm.test.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { ConnectionLimiter } from './connection-limiter';
|
|
|
20
20
|
import { Swarm } from './swarm';
|
|
21
21
|
import { TestWireProtocol } from '../testing/test-wire-protocol';
|
|
22
22
|
import { FullyConnectedTopology } from '../topology';
|
|
23
|
-
import {
|
|
23
|
+
import { createRtcTransportFactory } from '../transport';
|
|
24
24
|
|
|
25
25
|
type TestPeer = {
|
|
26
26
|
swarm: Swarm;
|
|
@@ -53,8 +53,7 @@ describe('Swarm', () => {
|
|
|
53
53
|
new FullyConnectedTopology(),
|
|
54
54
|
protocol.factory,
|
|
55
55
|
new Messenger({ signalManager }),
|
|
56
|
-
|
|
57
|
-
process.env.MOCHA_ENV === 'nodejs' ? createLibDataChannelTransportFactory() : createSimplePeerTransportFactory(),
|
|
56
|
+
createRtcTransportFactory(),
|
|
58
57
|
undefined,
|
|
59
58
|
connectionLimiter,
|
|
60
59
|
initiationDelay,
|
package/src/swarm/swarm.ts
CHANGED
|
@@ -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
|
|
32
|
+
* Manages a set of peers subscribed on the same topic.
|
|
33
33
|
* Routes signal events and maintains swarm topology.
|
|
34
34
|
*/
|
|
35
35
|
export class Swarm {
|
|
@@ -16,19 +16,12 @@ 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';
|
|
19
20
|
import { type TestTeleportExtensionFactory, TestWireProtocol } from './test-wire-protocol';
|
|
20
21
|
import { SwarmNetworkManager } from '../network-manager';
|
|
21
22
|
import { FullyConnectedTopology } from '../topology';
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
createSimplePeerTransportFactory,
|
|
25
|
-
MemoryTransportFactory,
|
|
26
|
-
SimplePeerTransportProxyFactory,
|
|
27
|
-
SimplePeerTransportService,
|
|
28
|
-
type TransportFactory,
|
|
29
|
-
TransportKind,
|
|
30
|
-
} from '../transport';
|
|
31
|
-
import { TcpTransportFactory } from '../transport/tcp-transport';
|
|
23
|
+
import { MemoryTransportFactory, type TransportFactory, TransportKind } from '../transport';
|
|
24
|
+
import { createRtcTransportFactory, RtcTransportProxyFactory, RtcTransportService } from '../transport';
|
|
32
25
|
|
|
33
26
|
// Signal server will be started by the setup script.
|
|
34
27
|
const port = process.env.SIGNAL_PORT ?? 4000;
|
|
@@ -85,18 +78,12 @@ export class TestPeer {
|
|
|
85
78
|
constructor(
|
|
86
79
|
private readonly testBuilder: TestBuilder,
|
|
87
80
|
public readonly peerId: PublicKey,
|
|
88
|
-
public readonly transport
|
|
81
|
+
public readonly transport: TransportKind = testBuilder.options.signalHosts
|
|
82
|
+
? TransportKind.WEB_RTC
|
|
83
|
+
: TransportKind.MEMORY,
|
|
89
84
|
) {
|
|
90
85
|
this._signalManager = this.testBuilder.createSignalManager();
|
|
91
|
-
|
|
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);
|
|
86
|
+
this._networkManager = this.createNetworkManager(this.transport);
|
|
100
87
|
}
|
|
101
88
|
|
|
102
89
|
// TODO(burdon): Move to TestBuilder.
|
|
@@ -110,13 +97,10 @@ export class TestPeer {
|
|
|
110
97
|
case TransportKind.TCP:
|
|
111
98
|
transportFactory = TcpTransportFactory;
|
|
112
99
|
break;
|
|
113
|
-
case TransportKind.
|
|
114
|
-
transportFactory =
|
|
115
|
-
break;
|
|
116
|
-
case TransportKind.LIBDATACHANNEL:
|
|
117
|
-
transportFactory = createLibDataChannelTransportFactory();
|
|
100
|
+
case TransportKind.WEB_RTC:
|
|
101
|
+
transportFactory = createRtcTransportFactory();
|
|
118
102
|
break;
|
|
119
|
-
case TransportKind.
|
|
103
|
+
case TransportKind.WEB_RTC_PROXY:
|
|
120
104
|
{
|
|
121
105
|
// Simulates bridge to shared worker.
|
|
122
106
|
const [proxyPort, servicePort] = createLinkedPorts();
|
|
@@ -137,14 +121,14 @@ export class TestPeer {
|
|
|
137
121
|
exposed: {
|
|
138
122
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService'),
|
|
139
123
|
},
|
|
140
|
-
handlers: { BridgeService: new
|
|
124
|
+
handlers: { BridgeService: new RtcTransportService() },
|
|
141
125
|
noHandshake: true,
|
|
142
126
|
encodingOptions: {
|
|
143
127
|
preserveAny: true,
|
|
144
128
|
},
|
|
145
129
|
});
|
|
146
130
|
|
|
147
|
-
transportFactory = new
|
|
131
|
+
transportFactory = new RtcTransportProxyFactory().setBridgeService(this._proxy.rpc.BridgeService);
|
|
148
132
|
}
|
|
149
133
|
break;
|
|
150
134
|
default:
|
package/src/transport/index.ts
CHANGED
|
@@ -4,8 +4,4 @@
|
|
|
4
4
|
|
|
5
5
|
export * from './memory-transport';
|
|
6
6
|
export * from './transport';
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './simplepeer-transport-service';
|
|
9
|
-
export * from './simplepeer-transport-proxy';
|
|
10
|
-
export * from './libdatachannel-transport';
|
|
11
|
-
export * from './tcp-transport';
|
|
7
|
+
export * from './webrtc';
|
|
@@ -123,6 +123,7 @@ export class MemoryTransport implements Transport {
|
|
|
123
123
|
this.errors.raise(err);
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
|
+
return this;
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
async close() {
|
|
@@ -155,6 +156,7 @@ export class MemoryTransport implements Transport {
|
|
|
155
156
|
|
|
156
157
|
this.closed.emit();
|
|
157
158
|
log('closed');
|
|
159
|
+
return this;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
async onSignal({ payload }: Signal) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { ErrorStream } from '@dxos/debug';
|
|
7
7
|
|
|
8
|
-
import { type Transport, type TransportFactory, type TransportStats } from '
|
|
8
|
+
import { type Transport, type TransportFactory, type TransportStats } from '../transport';
|
|
9
9
|
|
|
10
10
|
export const TcpTransportFactory: TransportFactory = {
|
|
11
11
|
createTransport: () => new TcpTransport(),
|
|
@@ -23,9 +23,13 @@ export class TcpTransport implements Transport {
|
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
async open() {
|
|
26
|
+
async open() {
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
27
29
|
|
|
28
|
-
async close() {
|
|
30
|
+
async close() {
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
29
33
|
|
|
30
34
|
async onSignal() {
|
|
31
35
|
throw new Error('Method not implemented.');
|
|
@@ -9,7 +9,7 @@ import { ErrorStream } from '@dxos/debug';
|
|
|
9
9
|
import { log } from '@dxos/log';
|
|
10
10
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
11
11
|
|
|
12
|
-
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from '
|
|
12
|
+
import { type Transport, type TransportFactory, type TransportOptions, type TransportStats } from '../transport';
|
|
13
13
|
|
|
14
14
|
export const TcpTransportFactory: TransportFactory = {
|
|
15
15
|
createTransport: (options) => new TcpTransport(options),
|
|
@@ -72,6 +72,7 @@ export class TcpTransport implements Transport {
|
|
|
72
72
|
this._server.listen(0);
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
|
+
return this;
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
async close() {
|
|
@@ -79,6 +80,7 @@ export class TcpTransport implements Transport {
|
|
|
79
80
|
this._socket?.destroy();
|
|
80
81
|
this._server?.close();
|
|
81
82
|
this._closed = true;
|
|
83
|
+
return this;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
async onSignal({ payload }: Signal) {
|
|
@@ -8,9 +8,8 @@ import { type PublicKey } from '@dxos/keys';
|
|
|
8
8
|
import { type Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
9
9
|
|
|
10
10
|
export enum TransportKind {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
LIBDATACHANNEL = 'LIBDATACHANNEL',
|
|
11
|
+
WEB_RTC = 'WEB-RTC',
|
|
12
|
+
WEB_RTC_PROXY = 'WEB-RTC_PROXY',
|
|
14
13
|
MEMORY = 'MEMORY',
|
|
15
14
|
TCP = 'TCP',
|
|
16
15
|
}
|
|
@@ -25,10 +24,8 @@ export interface Transport {
|
|
|
25
24
|
connected: Event;
|
|
26
25
|
errors: ErrorStream;
|
|
27
26
|
|
|
28
|
-
open(): Promise<
|
|
29
|
-
close(): Promise<
|
|
30
|
-
|
|
31
|
-
get isOpen(): boolean;
|
|
27
|
+
open(): Promise<this>;
|
|
28
|
+
close(): Promise<this>;
|
|
32
29
|
|
|
33
30
|
/**
|
|
34
31
|
* Handle message from signaling.
|
|
@@ -50,6 +47,10 @@ export interface Transport {
|
|
|
50
47
|
* Common options for all transports.
|
|
51
48
|
*/
|
|
52
49
|
export type TransportOptions = {
|
|
50
|
+
ownPeerKey: string;
|
|
51
|
+
remotePeerKey: string;
|
|
52
|
+
|
|
53
|
+
topic: string;
|
|
53
54
|
/**
|
|
54
55
|
* Did local node initiate this connection.
|
|
55
56
|
*/
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { Mutex } from '@dxos/async';
|
|
6
|
+
|
|
7
|
+
export type ConnectionInfo = {
|
|
8
|
+
initiator: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export interface RtcConnectionFactory {
|
|
12
|
+
initialize(): Promise<void>;
|
|
13
|
+
onConnectionDestroyed(): Promise<void>;
|
|
14
|
+
createConnection(config: RTCConfiguration): Promise<RTCPeerConnection>;
|
|
15
|
+
initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Use built-in browser RTCPeerConnection.
|
|
20
|
+
*/
|
|
21
|
+
class BrowserRtcConnectionFactory implements RtcConnectionFactory {
|
|
22
|
+
async initialize() {}
|
|
23
|
+
async onConnectionDestroyed() {}
|
|
24
|
+
|
|
25
|
+
async createConnection(config: RTCConfiguration) {
|
|
26
|
+
return new RTCPeerConnection(config);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void> {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Use `node-datachannel` polyfill.
|
|
34
|
+
* https://github.com/paullouisageneau/libdatachannel
|
|
35
|
+
*/
|
|
36
|
+
class NodeRtcConnectionFactory implements RtcConnectionFactory {
|
|
37
|
+
private static _createdConnections = 0;
|
|
38
|
+
private static _cleanupMutex = new Mutex();
|
|
39
|
+
|
|
40
|
+
// This should be inside the function to avoid triggering `eval` in the global scope.
|
|
41
|
+
// eslint-disable-next-line no-new-func
|
|
42
|
+
|
|
43
|
+
// TODO(burdon): Do imports here?
|
|
44
|
+
async initialize() {}
|
|
45
|
+
async onConnectionDestroyed() {
|
|
46
|
+
return NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
47
|
+
if (--NodeRtcConnectionFactory._createdConnections === 0) {
|
|
48
|
+
(await import('#node-datachannel')).cleanup();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async createConnection(config: RTCConfiguration) {
|
|
54
|
+
return NodeRtcConnectionFactory._cleanupMutex.executeSynchronized(async () => {
|
|
55
|
+
const { RTCPeerConnection } = await import('#node-datachannel/polyfill');
|
|
56
|
+
NodeRtcConnectionFactory._createdConnections++;
|
|
57
|
+
return new RTCPeerConnection(config);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async initConnection(connection: RTCPeerConnection, info: ConnectionInfo): Promise<void> {
|
|
62
|
+
// Initiator peer is responsible for data-channel creation. This triggers the callback in browsers.
|
|
63
|
+
// In node-datachannel/polyfill createOffer() / setLocalDescription(offer) are no-ops, the process
|
|
64
|
+
// is handled by c++ implementation when a data-channel gets created.
|
|
65
|
+
// By calling the method here we'll start waiting for an offer promise that'll resolve on data-channel creation
|
|
66
|
+
// at which point we'll need to send an SDP to a remote peer.
|
|
67
|
+
// https://github.com/murat-dogan/node-datachannel/blob/master/polyfill/RTCPeerConnection.js#L452C1-L459C6
|
|
68
|
+
//
|
|
69
|
+
if (info.initiator) {
|
|
70
|
+
connection.onnegotiationneeded?.(null as any);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Create platform-specific connection factory.
|
|
77
|
+
*/
|
|
78
|
+
export const getRtcConnectionFactory = (): RtcConnectionFactory => {
|
|
79
|
+
return typeof (globalThis as any).RTCPeerConnection === 'undefined'
|
|
80
|
+
? new NodeRtcConnectionFactory()
|
|
81
|
+
: new BrowserRtcConnectionFactory();
|
|
82
|
+
};
|