@libp2p/webrtc 5.2.24 → 6.0.0-55b7e5fea
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/README.md +10 -20
- package/dist/index.min.js +28 -29
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +4 -23
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -23
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +20 -22
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -22
- package/dist/src/index.js.map +1 -1
- package/dist/src/muxer.d.ts +14 -46
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +30 -138
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts +2 -3
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +37 -5
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts +4 -4
- package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.js +19 -7
- package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +2 -9
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +30 -15
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +3 -2
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +26 -14
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +21 -15
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/dist/src/private-to-public/transport.d.ts +0 -8
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +3 -2
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/connect.js +17 -14
- package/dist/src/private-to-public/utils/connect.js.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +4 -4
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +13 -2
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/sdp.js +25 -13
- package/dist/src/private-to-public/utils/sdp.js.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
- package/dist/src/rtcpeerconnection-to-conn.d.ts +12 -0
- package/dist/src/rtcpeerconnection-to-conn.d.ts.map +1 -0
- package/dist/src/rtcpeerconnection-to-conn.js +46 -0
- package/dist/src/rtcpeerconnection-to-conn.js.map +1 -0
- package/dist/src/stream.d.ts +14 -26
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +134 -204
- package/dist/src/stream.js.map +1 -1
- package/dist/src/util.d.ts +3 -1
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +19 -0
- package/dist/src/util.js.map +1 -1
- package/dist/src/webrtc/index.d.ts +1 -1
- package/dist/src/webrtc/index.d.ts.map +1 -1
- package/dist/src/webrtc/index.js +1 -1
- package/dist/src/webrtc/index.js.map +1 -1
- package/package.json +28 -31
- package/src/constants.ts +5 -28
- package/src/index.ts +21 -22
- package/src/muxer.ts +39 -169
- package/src/private-to-private/initiate-connection.ts +46 -8
- package/src/private-to-private/signaling-stream-handler.ts +23 -10
- package/src/private-to-private/transport.ts +33 -25
- package/src/private-to-private/util.ts +33 -16
- package/src/private-to-public/listener.ts +22 -15
- package/src/private-to-public/transport.ts +3 -12
- package/src/private-to-public/utils/connect.ts +18 -15
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +16 -4
- package/src/private-to-public/utils/sdp.ts +29 -13
- package/src/private-to-public/utils/stun-listener.ts +1 -1
- package/src/rtcpeerconnection-to-conn.ts +66 -0
- package/src/stream.ts +153 -237
- package/src/util.ts +22 -1
- package/src/webrtc/index.ts +1 -1
- package/dist/src/maconn.d.ts +0 -58
- package/dist/src/maconn.d.ts.map +0 -1
- package/dist/src/maconn.js +0 -56
- package/dist/src/maconn.js.map +0 -1
- package/dist/typedoc-urls.json +0 -14
- package/src/maconn.ts +0 -101
package/dist/src/util.js
CHANGED
@@ -6,6 +6,25 @@ const browser = detect();
|
|
6
6
|
export const isFirefox = ((browser != null) && browser.name === 'firefox');
|
7
7
|
export const nopSource = async function* nop() { };
|
8
8
|
export const nopSink = async (_) => { };
|
9
|
+
// Duplex that does nothing. Needed to fulfill the interface
|
10
|
+
export function inertDuplex() {
|
11
|
+
return {
|
12
|
+
source: {
|
13
|
+
[Symbol.asyncIterator]() {
|
14
|
+
return {
|
15
|
+
async next() {
|
16
|
+
// This will never resolve
|
17
|
+
return new Promise(() => { });
|
18
|
+
}
|
19
|
+
};
|
20
|
+
}
|
21
|
+
},
|
22
|
+
sink: async (source) => {
|
23
|
+
// This will never resolve
|
24
|
+
return new Promise(() => { });
|
25
|
+
}
|
26
|
+
};
|
27
|
+
}
|
9
28
|
export function drainAndClose(channel, direction, drainTimeout = DATA_CHANNEL_DRAIN_TIMEOUT, options) {
|
10
29
|
if (channel.readyState !== 'open') {
|
11
30
|
return;
|
package/dist/src/util.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,MAAM,MAAM,SAAS,CAAA;AAC5B,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACvC,OAAO,MAAM,MAAM,SAAS,CAAA;AAC5B,OAAO,QAAQ,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAK9G,MAAM,OAAO,GAAG,MAAM,EAAE,CAAA;AACxB,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAA;AAE1E,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,SAAU,CAAC,CAAC,GAAG,KAA+C,CAAC,CAAA;AAE7F,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAAE,CAAM,EAAiB,EAAE,GAAE,CAAC,CAAA;AAE1D,4DAA4D;AAC5D,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,MAAM,EAAE;YACN,CAAC,MAAM,CAAC,aAAa,CAAC;gBACpB,OAAO;oBACL,KAAK,CAAC,IAAI;wBACR,0BAA0B;wBAC1B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;oBAC/B,CAAC;iBACF,CAAA;YACH,CAAC;SACF;QACD,IAAI,EAAE,KAAK,EAAE,MAAmB,EAAE,EAAE;YAClC,0BAA0B;YAC1B,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;QAC/B,CAAC;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAE,OAAuB,EAAE,SAAiB,EAAE,eAAuB,0BAA0B,EAAE,OAAsB;IAClJ,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QAClC,OAAM;IACR,CAAC;IAED,KAAK,OAAO,CAAC,OAAO,EAAE;SACnB,IAAI,CAAC,KAAK,IAAI,EAAE;QACf,yCAAyC;QACzC,IAAI,OAAO,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,yCAAyC,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;YACzF,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAA;YACzB,IAAI,OAAO,GAAG,KAAK,CAAA;YAEnB,OAAO,CAAC,0BAA0B,GAAG,CAAC,CAAA;YAEtC,MAAM,aAAa,GAAG,GAAS,EAAE;gBAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,SAAS,CAAC,CAAA;oBAC9D,QAAQ,CAAC,OAAO,EAAE,CAAA;gBACpB,CAAC;YACH,CAAC,CAAA;YAED,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE;gBAC/C,IAAI,EAAE,IAAI;aACX,CAAC,CAAA;YAEF,OAAO,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,GAAG,EAAE;gBACjD,OAAO,GAAG,IAAI,CAAA;gBACd,OAAO,CAAC,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAA;gBACnD,QAAQ,CAAC,OAAO,EAAE,CAAA;YACpB,CAAC,CAAC,CAAA;YAEF,MAAM,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE;gBAC/B,YAAY,EAAE,YAAY;aAC3B,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,CAAC;SACD,IAAI,CAAC,KAAK,IAAI,EAAE;QACf,0CAA0C;QAC1C,IAAI,OAAO,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,EAAE,CAAA;QACjB,CAAC;IACH,CAAC,CAAC;SACD,KAAK,CAAC,GAAG,CAAC,EAAE;QACX,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;AACN,CAAC;AAOD,MAAM,UAAU,gBAAgB,CAAE,GAAQ;IACxC,OAAO,OAAO,GAAG,CAAC,KAAK,KAAK,UAAU,CAAA;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAE,MAAgF;IACzH,MAAM,GAAG,MAAM,IAAI,EAAE,CAAA;IAErB,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,MAAM,GAAG,MAAM,MAAM,EAAE,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,IAAI,EAAE;YACJ,GAAG;SACJ;KACF,CAAC,CAAC,CAAA;IAEH,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAE,EAAU,EAAE;IACnD,OAAO,YAAY,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;AAChI,CAAC,CAAA"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from '
|
1
|
+
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from 'node-datachannel/polyfill';
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA"}
|
package/dist/src/webrtc/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from '
|
1
|
+
export { RTCSessionDescription, RTCIceCandidate, RTCPeerConnection } from 'node-datachannel/polyfill';
|
2
2
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/webrtc/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@libp2p/webrtc",
|
3
|
-
"version": "
|
3
|
+
"version": "6.0.0-55b7e5fea",
|
4
4
|
"description": "A libp2p transport using WebRTC connections",
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
6
6
|
"homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/transport-webrtc#readme",
|
@@ -45,52 +45,49 @@
|
|
45
45
|
},
|
46
46
|
"dependencies": {
|
47
47
|
"@chainsafe/is-ip": "^2.1.0",
|
48
|
-
"@
|
49
|
-
"@
|
50
|
-
"@libp2p/
|
51
|
-
"@libp2p/
|
52
|
-
"@libp2p/
|
53
|
-
"@libp2p/
|
54
|
-
"@libp2p/
|
55
|
-
"@
|
56
|
-
"@multiformats/multiaddr": "^
|
57
|
-
"@multiformats/multiaddr-matcher": "^2.0.0",
|
48
|
+
"@libp2p/crypto": "5.1.9-55b7e5fea",
|
49
|
+
"@libp2p/interface": "3.0.0-55b7e5fea",
|
50
|
+
"@libp2p/interface-internal": "3.0.0-55b7e5fea",
|
51
|
+
"@libp2p/keychain": "6.0.0-55b7e5fea",
|
52
|
+
"@libp2p/noise": "1.0.0-55b7e5fea",
|
53
|
+
"@libp2p/peer-id": "6.0.0-55b7e5fea",
|
54
|
+
"@libp2p/utils": "7.0.0-55b7e5fea",
|
55
|
+
"@multiformats/multiaddr": "^13.0.1",
|
56
|
+
"@multiformats/multiaddr-matcher": "^3.0.1",
|
58
57
|
"@peculiar/webcrypto": "^1.5.0",
|
59
|
-
"@peculiar/x509": "^1.
|
60
|
-
"any-signal": "^4.1.1",
|
58
|
+
"@peculiar/x509": "^1.13.0",
|
61
59
|
"detect-browser": "^5.3.0",
|
62
60
|
"get-port": "^7.1.0",
|
63
|
-
"interface-datastore": "^8.3.
|
61
|
+
"interface-datastore": "^8.3.2",
|
64
62
|
"it-length-prefixed": "^10.0.1",
|
65
|
-
"it-protobuf-stream": "^2.0.
|
63
|
+
"it-protobuf-stream": "^2.0.3",
|
66
64
|
"it-pushable": "^3.2.3",
|
67
65
|
"it-stream-types": "^2.0.2",
|
68
66
|
"main-event": "^1.0.1",
|
69
|
-
"multiformats": "^13.
|
67
|
+
"multiformats": "^13.4.0",
|
68
|
+
"node-datachannel": "^0.29.0",
|
70
69
|
"p-defer": "^4.0.1",
|
71
|
-
"p-
|
72
|
-
"p-
|
70
|
+
"p-event": "^7.0.0",
|
71
|
+
"p-timeout": "^7.0.0",
|
72
|
+
"p-wait-for": "^6.0.0",
|
73
73
|
"progress-events": "^1.0.1",
|
74
|
-
"protons-runtime": "^5.
|
75
|
-
"race-
|
76
|
-
"
|
77
|
-
"react-native-webrtc": "^124.0.5",
|
74
|
+
"protons-runtime": "^5.6.0",
|
75
|
+
"race-signal": "^2.0.0",
|
76
|
+
"react-native-webrtc": "^124.0.6",
|
78
77
|
"uint8-varint": "^2.0.4",
|
79
78
|
"uint8arraylist": "^2.4.8",
|
80
79
|
"uint8arrays": "^5.1.0"
|
81
80
|
},
|
82
81
|
"devDependencies": {
|
83
|
-
"@libp2p/
|
84
|
-
"@libp2p/logger": "^5.2.0",
|
82
|
+
"@libp2p/logger": "6.0.0-55b7e5fea",
|
85
83
|
"@types/sinon": "^17.0.4",
|
86
|
-
"aegir": "^47.0.
|
87
|
-
"
|
84
|
+
"aegir": "^47.0.22",
|
85
|
+
"any-signal": "^4.1.1",
|
86
|
+
"datastore-core": "^10.0.4",
|
88
87
|
"delay": "^6.0.0",
|
89
|
-
"
|
90
|
-
"
|
91
|
-
"
|
92
|
-
"protons": "^7.6.1",
|
93
|
-
"sinon": "^20.0.0",
|
88
|
+
"p-retry": "^7.0.0",
|
89
|
+
"protons": "^7.7.0",
|
90
|
+
"sinon": "^21.0.0",
|
94
91
|
"sinon-ts": "^2.0.0",
|
95
92
|
"wherearewe": "^2.0.1"
|
96
93
|
},
|
package/src/constants.ts
CHANGED
@@ -26,26 +26,11 @@ export const UFRAG_ALPHABET = Array.from('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKL
|
|
26
26
|
*/
|
27
27
|
export const UFRAG_PREFIX = 'libp2p+webrtc+v1/'
|
28
28
|
|
29
|
-
/**
|
30
|
-
* The multicodec code for webrtc-direct tuples
|
31
|
-
*/
|
32
|
-
export const CODEC_WEBRTC_DIRECT = 0x0118
|
33
|
-
|
34
|
-
/**
|
35
|
-
* The multicodec code for certhash tuples
|
36
|
-
*/
|
37
|
-
export const CODEC_CERTHASH = 0x01d2
|
38
|
-
|
39
29
|
/**
|
40
30
|
* How much can be buffered to the DataChannel at once
|
41
31
|
*/
|
42
32
|
export const MAX_BUFFERED_AMOUNT = 2 * 1024 * 1024
|
43
33
|
|
44
|
-
/**
|
45
|
-
* How long time we wait for the 'bufferedamountlow' event to be emitted
|
46
|
-
*/
|
47
|
-
export const BUFFERED_AMOUNT_LOW_TIMEOUT = 30 * 1000
|
48
|
-
|
49
34
|
/**
|
50
35
|
* Max message size that can be sent to the DataChannel. In browsers this is
|
51
36
|
* 256KiB but go-libp2p and rust-libp2p only support 16KiB at the time of
|
@@ -82,25 +67,17 @@ function calculateProtobufOverhead (maxMessageSize = MAX_MESSAGE_SIZE): number {
|
|
82
67
|
*/
|
83
68
|
export const PROTOBUF_OVERHEAD = calculateProtobufOverhead()
|
84
69
|
|
85
|
-
/**
|
86
|
-
* When closing streams we send a FIN then wait for the remote to
|
87
|
-
* reply with a FIN_ACK. If that does not happen within this timeout
|
88
|
-
* we close the stream anyway.
|
89
|
-
*/
|
90
|
-
export const FIN_ACK_TIMEOUT = 5_000
|
91
|
-
|
92
|
-
/**
|
93
|
-
* When sending data messages, if the channel is not in the "open" state, wait
|
94
|
-
* this long for the "open" event to fire.
|
95
|
-
*/
|
96
|
-
export const OPEN_TIMEOUT = 5_000
|
97
|
-
|
98
70
|
/**
|
99
71
|
* When closing a stream, we wait for `bufferedAmount` to become 0 before
|
100
72
|
* closing the underlying RTCDataChannel - this controls how long we wait in ms
|
101
73
|
*/
|
102
74
|
export const DATA_CHANNEL_DRAIN_TIMEOUT = 30_000
|
103
75
|
|
76
|
+
/**
|
77
|
+
* Wait for the remote to acknowledge our FIN for this long
|
78
|
+
*/
|
79
|
+
export const DEFAULT_FIN_ACK_TIMEOUT = 10_000
|
80
|
+
|
104
81
|
/**
|
105
82
|
* Set as the 'negotiated' muxer protocol name
|
106
83
|
*/
|
package/src/index.ts
CHANGED
@@ -26,8 +26,8 @@
|
|
26
26
|
* WebRTC requires use of a relay to connect two nodes. The listener first discovers a relay server and makes a reservation, then the dialer can connect via the relayed address.
|
27
27
|
*
|
28
28
|
* ```TypeScript
|
29
|
-
* import { noise } from '@
|
30
|
-
* import { yamux } from '@
|
29
|
+
* import { noise } from '@libp2p/noise'
|
30
|
+
* import { yamux } from '@libp2p/yamux'
|
31
31
|
* import { echo } from '@libp2p/echo'
|
32
32
|
* import { circuitRelayTransport, circuitRelayServer } from '@libp2p/circuit-relay-v2'
|
33
33
|
* import { identify } from '@libp2p/identify'
|
@@ -35,7 +35,6 @@
|
|
35
35
|
* import { webSockets } from '@libp2p/websockets'
|
36
36
|
* import { WebRTC } from '@multiformats/multiaddr-matcher'
|
37
37
|
* import delay from 'delay'
|
38
|
-
* import { pipe } from 'it-pipe'
|
39
38
|
* import { createLibp2p } from 'libp2p'
|
40
39
|
* import type { Multiaddr } from '@multiformats/multiaddr'
|
41
40
|
*
|
@@ -134,15 +133,11 @@
|
|
134
133
|
* await relay.stop()
|
135
134
|
*
|
136
135
|
* // send/receive some data from the remote peer via a direct connection
|
137
|
-
*
|
138
|
-
*
|
139
|
-
*
|
140
|
-
*
|
141
|
-
*
|
142
|
-
* console.info(new TextDecoder().decode(buf.subarray()))
|
143
|
-
* }
|
144
|
-
* }
|
145
|
-
* )
|
136
|
+
* stream.send(new TextEncoder().encode('hello world'))
|
137
|
+
*
|
138
|
+
* stream.addEventListener('message', (evt) => {
|
139
|
+
* console.info(new TextDecoder().decode(evt.data.subarray()))
|
140
|
+
* })
|
146
141
|
* ```
|
147
142
|
*
|
148
143
|
* @example WebRTC Direct
|
@@ -167,7 +162,6 @@
|
|
167
162
|
* ```TypeScript
|
168
163
|
* import { createLibp2p } from 'libp2p'
|
169
164
|
* import { multiaddr } from '@multiformats/multiaddr'
|
170
|
-
* import { pipe } from 'it-pipe'
|
171
165
|
* import { fromString, toString } from 'uint8arrays'
|
172
166
|
* import { webRTCDirect } from '@libp2p/webrtc'
|
173
167
|
*
|
@@ -196,15 +190,11 @@
|
|
196
190
|
* signal: AbortSignal.timeout(10_000)
|
197
191
|
* })
|
198
192
|
*
|
199
|
-
*
|
200
|
-
*
|
201
|
-
*
|
202
|
-
*
|
203
|
-
*
|
204
|
-
* console.info(toString(buf.subarray()))
|
205
|
-
* }
|
206
|
-
* }
|
207
|
-
* )
|
193
|
+
* stream.send(new TextEncoder().encode('hello world'))
|
194
|
+
*
|
195
|
+
* stream.addEventListener('message', (evt) => {
|
196
|
+
* console.info(new TextDecoder().decode(evt.data.subarray()))
|
197
|
+
* })
|
208
198
|
* ```
|
209
199
|
*
|
210
200
|
* ## WebRTC Direct certificate hashes
|
@@ -318,6 +308,15 @@ export interface DataChannelOptions {
|
|
318
308
|
* @default 5_000
|
319
309
|
*/
|
320
310
|
openTimeout?: number
|
311
|
+
|
312
|
+
/**
|
313
|
+
* Due to bugs in WebRTC implementations it's necessary for the remote end of
|
314
|
+
* the connection to acknowledge the FIN message we send during stream
|
315
|
+
* closing. A stream will wait for this many ms.
|
316
|
+
*
|
317
|
+
* @default 10_000
|
318
|
+
*/
|
319
|
+
finAckTimeout?: number
|
321
320
|
}
|
322
321
|
|
323
322
|
/**
|
package/src/muxer.ts
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
+
import { AbstractStreamMuxer } from '@libp2p/utils'
|
1
2
|
import { MUXER_PROTOCOL } from './constants.js'
|
2
|
-
import { createStream } from './stream.js'
|
3
|
-
import { drainAndClose, nopSink, nopSource } from './util.js'
|
3
|
+
import { createStream, WebRTCStream } from './stream.js'
|
4
4
|
import type { DataChannelOptions } from './index.js'
|
5
|
-
import type { ComponentLogger,
|
6
|
-
import type { AbortOptions } from '@multiformats/multiaddr'
|
7
|
-
import type { Source, Sink } from 'it-stream-types'
|
8
|
-
import type { Uint8ArrayList } from 'uint8arraylist'
|
5
|
+
import type { ComponentLogger, CounterGroup, StreamMuxer, StreamMuxerFactory, CreateStreamOptions, MultiaddrConnection } from '@libp2p/interface'
|
9
6
|
|
10
7
|
export interface DataChannelMuxerFactoryInit {
|
11
8
|
/**
|
@@ -23,6 +20,9 @@ export interface DataChannelMuxerFactoryInit {
|
|
23
20
|
*/
|
24
21
|
metrics?: CounterGroup
|
25
22
|
|
23
|
+
/**
|
24
|
+
* Options used to create data channels
|
25
|
+
*/
|
26
26
|
dataChannelOptions?: DataChannelOptions
|
27
27
|
}
|
28
28
|
|
@@ -30,12 +30,6 @@ export interface DataChannelMuxerFactoryComponents {
|
|
30
30
|
logger: ComponentLogger
|
31
31
|
}
|
32
32
|
|
33
|
-
interface BufferedStream {
|
34
|
-
stream: Stream
|
35
|
-
channel: RTCDataChannel
|
36
|
-
onEnd(err?: Error): void
|
37
|
-
}
|
38
|
-
|
39
33
|
export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
40
34
|
public readonly protocol: string
|
41
35
|
|
@@ -43,69 +37,28 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
43
37
|
* WebRTC Peer Connection
|
44
38
|
*/
|
45
39
|
private readonly peerConnection: RTCPeerConnection
|
46
|
-
private bufferedStreams: BufferedStream[] = []
|
47
40
|
private readonly metrics?: CounterGroup
|
48
41
|
private readonly dataChannelOptions?: DataChannelOptions
|
49
|
-
private readonly components: DataChannelMuxerFactoryComponents
|
50
|
-
private readonly log: Logger
|
51
42
|
|
52
|
-
constructor (
|
53
|
-
this.components = components
|
43
|
+
constructor (init: DataChannelMuxerFactoryInit) {
|
54
44
|
this.peerConnection = init.peerConnection
|
55
45
|
this.metrics = init.metrics
|
56
46
|
this.protocol = init.protocol ?? MUXER_PROTOCOL
|
57
47
|
this.dataChannelOptions = init.dataChannelOptions ?? {}
|
58
|
-
this.log = components.logger.forComponent('libp2p:webrtc:muxerfactory')
|
59
|
-
|
60
|
-
// store any data channels opened before upgrade has been completed
|
61
|
-
this.peerConnection.ondatachannel = ({ channel }) => {
|
62
|
-
this.log.trace('incoming early datachannel with channel id %d and label "%s"', channel.id)
|
63
|
-
|
64
|
-
// 'init' channel is only used during connection establishment
|
65
|
-
if (channel.label === 'init') {
|
66
|
-
this.log.trace('closing early init channel')
|
67
|
-
channel.close()
|
68
|
-
|
69
|
-
return
|
70
|
-
}
|
71
|
-
|
72
|
-
// @ts-expect-error fields are set below
|
73
|
-
const bufferedStream: BufferedStream = {}
|
74
|
-
|
75
|
-
const stream = createStream({
|
76
|
-
channel,
|
77
|
-
direction: 'inbound',
|
78
|
-
onEnd: (err) => {
|
79
|
-
bufferedStream.onEnd(err)
|
80
|
-
},
|
81
|
-
log: this.log,
|
82
|
-
...this.dataChannelOptions
|
83
|
-
})
|
84
|
-
|
85
|
-
bufferedStream.stream = stream
|
86
|
-
bufferedStream.channel = channel
|
87
|
-
bufferedStream.onEnd = () => {
|
88
|
-
this.bufferedStreams = this.bufferedStreams.filter(s => s.stream.id !== stream.id)
|
89
|
-
}
|
90
|
-
|
91
|
-
this.bufferedStreams.push(bufferedStream)
|
92
|
-
}
|
93
48
|
}
|
94
49
|
|
95
|
-
createStreamMuxer (
|
96
|
-
return new DataChannelMuxer(
|
97
|
-
...init,
|
50
|
+
createStreamMuxer (maConn: MultiaddrConnection): StreamMuxer {
|
51
|
+
return new DataChannelMuxer(maConn, {
|
98
52
|
peerConnection: this.peerConnection,
|
99
53
|
dataChannelOptions: this.dataChannelOptions,
|
100
54
|
metrics: this.metrics,
|
101
|
-
streams: this.bufferedStreams,
|
102
55
|
protocol: this.protocol
|
103
56
|
})
|
104
57
|
}
|
105
58
|
}
|
106
59
|
|
107
|
-
export interface DataChannelMuxerInit extends DataChannelMuxerFactoryInit
|
108
|
-
|
60
|
+
export interface DataChannelMuxerInit extends DataChannelMuxerFactoryInit {
|
61
|
+
protocol: string
|
109
62
|
}
|
110
63
|
|
111
64
|
export interface DataChannelMuxerComponents {
|
@@ -115,26 +68,18 @@ export interface DataChannelMuxerComponents {
|
|
115
68
|
/**
|
116
69
|
* A libp2p data channel stream muxer
|
117
70
|
*/
|
118
|
-
export class DataChannelMuxer implements StreamMuxer {
|
119
|
-
/**
|
120
|
-
* Array of streams in the data channel
|
121
|
-
*/
|
122
|
-
public streams: Stream[]
|
123
|
-
public protocol: string
|
124
|
-
|
125
|
-
private readonly log: Logger
|
71
|
+
export class DataChannelMuxer extends AbstractStreamMuxer<WebRTCStream> implements StreamMuxer<WebRTCStream> {
|
126
72
|
private readonly peerConnection: RTCPeerConnection
|
127
73
|
private readonly dataChannelOptions: DataChannelOptions
|
128
|
-
private readonly metrics?: CounterGroup
|
129
|
-
private readonly logger: ComponentLogger
|
130
74
|
|
131
|
-
constructor (
|
132
|
-
|
133
|
-
|
134
|
-
|
75
|
+
constructor (maConn: MultiaddrConnection, init: DataChannelMuxerInit) {
|
76
|
+
super(maConn, {
|
77
|
+
...init,
|
78
|
+
name: 'muxer'
|
79
|
+
})
|
80
|
+
|
135
81
|
this.peerConnection = init.peerConnection
|
136
82
|
this.protocol = init.protocol ?? MUXER_PROTOCOL
|
137
|
-
this.metrics = init.metrics
|
138
83
|
this.dataChannelOptions = init.dataChannelOptions ?? {}
|
139
84
|
|
140
85
|
/**
|
@@ -144,125 +89,50 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
144
89
|
* {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event}
|
145
90
|
*/
|
146
91
|
this.peerConnection.ondatachannel = ({ channel }) => {
|
147
|
-
this.log.trace('incoming datachannel with channel id %d', channel.id)
|
92
|
+
this.log.trace('incoming %s datachannel with channel id %d, protocol %s and status %s', channel.protocol, channel.id, channel.protocol, channel.readyState)
|
148
93
|
|
149
|
-
// 'init' channel is only used during connection establishment
|
94
|
+
// 'init' channel is only used during connection establishment, it is
|
95
|
+
// closed by the initiator
|
150
96
|
if (channel.label === 'init') {
|
151
|
-
this.log.trace('closing init channel')
|
97
|
+
this.log.trace('closing init channel %d', channel.id)
|
152
98
|
channel.close()
|
153
99
|
|
154
100
|
return
|
155
101
|
}
|
156
102
|
|
157
|
-
// lib-datachannel throws if `.getId` is called on a closed channel so
|
158
|
-
// memoize it
|
159
|
-
const id = channel.id
|
160
|
-
|
161
103
|
const stream = createStream({
|
104
|
+
...this.streamOptions,
|
105
|
+
...this.dataChannelOptions,
|
162
106
|
channel,
|
163
107
|
direction: 'inbound',
|
164
|
-
onEnd: () => {
|
165
|
-
this.#onStreamEnd(stream, channel)
|
166
|
-
this.log('incoming channel %s ended', id)
|
167
|
-
},
|
168
|
-
log: this.log,
|
169
|
-
...this.dataChannelOptions
|
170
|
-
})
|
171
|
-
|
172
|
-
this.streams.push(stream)
|
173
|
-
this.metrics?.increment({ incoming_stream: true })
|
174
|
-
init?.onIncomingStream?.(stream)
|
175
|
-
}
|
176
|
-
|
177
|
-
// the DataChannelMuxer constructor is called during set up of the
|
178
|
-
// connection by the upgrader.
|
179
|
-
//
|
180
|
-
// If we invoke `init.onIncomingStream` immediately, the connection object
|
181
|
-
// will not be set up yet so add a tiny delay before letting the
|
182
|
-
// connection know about early streams
|
183
|
-
if (this.init.streams.length > 0) {
|
184
|
-
queueMicrotask(() => {
|
185
|
-
this.init.streams.forEach(bufferedStream => {
|
186
|
-
bufferedStream.onEnd = () => {
|
187
|
-
this.log('incoming early channel %s ended with state %s', bufferedStream.channel.id, bufferedStream.channel.readyState)
|
188
|
-
this.#onStreamEnd(bufferedStream.stream, bufferedStream.channel)
|
189
|
-
}
|
190
|
-
|
191
|
-
this.metrics?.increment({ incoming_stream: true })
|
192
|
-
this.init?.onIncomingStream?.(bufferedStream.stream)
|
193
|
-
})
|
194
|
-
})
|
195
|
-
}
|
196
|
-
}
|
197
|
-
|
198
|
-
#onStreamEnd (stream: Stream, channel: RTCDataChannel): void {
|
199
|
-
this.log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
|
200
|
-
drainAndClose(
|
201
|
-
channel,
|
202
|
-
`${stream.direction} ${stream.id} ${stream.protocol}`,
|
203
|
-
this.dataChannelOptions.drainTimeout, {
|
204
108
|
log: this.log
|
205
|
-
}
|
206
|
-
)
|
207
|
-
this.streams = this.streams.filter(s => s.id !== stream.id)
|
208
|
-
this.metrics?.increment({ stream_end: true })
|
209
|
-
this.init?.onStreamEnd?.(stream)
|
210
|
-
}
|
211
|
-
|
212
|
-
/**
|
213
|
-
* Gracefully close all tracked streams and stop the muxer
|
214
|
-
*/
|
215
|
-
async close (options?: AbortOptions): Promise<void> {
|
216
|
-
try {
|
217
|
-
await Promise.all(
|
218
|
-
this.streams.map(async stream => stream.close(options))
|
219
|
-
)
|
220
|
-
} catch (err: any) {
|
221
|
-
this.abort(err)
|
222
|
-
}
|
223
|
-
}
|
109
|
+
})
|
224
110
|
|
225
|
-
|
226
|
-
* Abort all tracked streams and stop the muxer
|
227
|
-
*/
|
228
|
-
abort (err: Error): void {
|
229
|
-
for (const stream of this.streams) {
|
230
|
-
stream.abort(err)
|
111
|
+
this.onRemoteStream(stream)
|
231
112
|
}
|
232
113
|
}
|
233
114
|
|
234
|
-
|
235
|
-
* The stream source, a no-op as the transport natively supports multiplexing
|
236
|
-
*/
|
237
|
-
source: AsyncGenerator<Uint8Array, any, unknown> = nopSource()
|
238
|
-
|
239
|
-
/**
|
240
|
-
* The stream destination, a no-op as the transport natively supports multiplexing
|
241
|
-
*/
|
242
|
-
sink: Sink<Source<Uint8Array | Uint8ArrayList>, Promise<void>> = nopSink
|
243
|
-
|
244
|
-
newStream (): Stream {
|
115
|
+
async onCreateStream (options?: CreateStreamOptions): Promise<WebRTCStream> {
|
245
116
|
// The spec says the label MUST be an empty string: https://github.com/libp2p/specs/blob/master/webrtc/README.md#rtcdatachannel-label
|
246
|
-
const channel = this.peerConnection.createDataChannel(''
|
247
|
-
|
248
|
-
|
249
|
-
|
117
|
+
const channel = this.peerConnection.createDataChannel('', {
|
118
|
+
// TODO: pre-negotiate stream protocol
|
119
|
+
// protocol: options?.protocol
|
120
|
+
})
|
250
121
|
|
251
|
-
this.log
|
122
|
+
this.log('open channel %d for protocol %s', channel.id, options?.protocol)
|
252
123
|
|
253
124
|
const stream = createStream({
|
125
|
+
...options,
|
126
|
+
...this.dataChannelOptions,
|
254
127
|
channel,
|
255
128
|
direction: 'outbound',
|
256
|
-
|
257
|
-
this.#onStreamEnd(stream, channel)
|
258
|
-
this.log('outgoing channel %s ended', id)
|
259
|
-
},
|
260
|
-
log: this.log,
|
261
|
-
...this.dataChannelOptions
|
129
|
+
log: this.log
|
262
130
|
})
|
263
|
-
this.streams.push(stream)
|
264
|
-
this.metrics?.increment({ outgoing_stream: true })
|
265
131
|
|
266
132
|
return stream
|
267
133
|
}
|
134
|
+
|
135
|
+
onData (): void {
|
136
|
+
|
137
|
+
}
|
268
138
|
}
|