@libp2p/webrtc 2.0.11 → 3.0.0-e66f4891
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 +7 -2
- package/dist/index.min.js +18 -19
- package/dist/src/error.d.ts +2 -2
- package/dist/src/error.d.ts.map +1 -1
- package/dist/src/error.js +1 -1
- package/dist/src/error.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/maconn.d.ts +5 -4
- package/dist/src/maconn.d.ts.map +1 -1
- package/dist/src/maconn.js +8 -5
- package/dist/src/maconn.js.map +1 -1
- package/dist/src/muxer.d.ts +10 -5
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +6 -2
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/handler.d.ts +4 -3
- package/dist/src/private-to-private/handler.d.ts.map +1 -1
- package/dist/src/private-to-private/handler.js +104 -84
- package/dist/src/private-to-private/handler.js.map +1 -1
- package/dist/src/private-to-private/listener.d.ts +4 -3
- package/dist/src/private-to-private/listener.d.ts.map +1 -1
- package/dist/src/private-to-private/listener.js +1 -1
- package/dist/src/private-to-private/listener.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +6 -5
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +13 -6
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +1 -0
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/options.d.ts +1 -1
- package/dist/src/private-to-public/sdp.js +1 -1
- package/dist/src/private-to-public/transport.d.ts +4 -4
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +99 -92
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/util.d.ts.map +1 -1
- package/dist/src/private-to-public/util.js.map +1 -1
- package/dist/src/stream.d.ts +34 -3
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +24 -14
- package/dist/src/stream.js.map +1 -1
- package/dist/src/webrtc/index.browser.d.ts +15 -0
- package/dist/src/webrtc/index.browser.d.ts.map +1 -0
- package/dist/src/webrtc/index.browser.js +5 -0
- package/dist/src/webrtc/index.browser.js.map +1 -0
- package/dist/src/webrtc/index.d.ts +8 -0
- package/dist/src/webrtc/index.d.ts.map +1 -0
- package/dist/src/webrtc/index.js +11 -0
- package/dist/src/webrtc/index.js.map +1 -0
- package/dist/src/webrtc/rtc-data-channel.d.ts +29 -0
- package/dist/src/webrtc/rtc-data-channel.d.ts.map +1 -0
- package/dist/src/webrtc/rtc-data-channel.js +115 -0
- package/dist/src/webrtc/rtc-data-channel.js.map +1 -0
- package/dist/src/webrtc/rtc-events.d.ts +9 -0
- package/dist/src/webrtc/rtc-events.d.ts.map +1 -0
- package/dist/src/webrtc/rtc-events.js +15 -0
- package/dist/src/webrtc/rtc-events.js.map +1 -0
- package/dist/src/webrtc/rtc-ice-candidate.d.ts +22 -0
- package/dist/src/webrtc/rtc-ice-candidate.d.ts.map +1 -0
- package/dist/src/webrtc/rtc-ice-candidate.js +47 -0
- package/dist/src/webrtc/rtc-ice-candidate.js.map +1 -0
- package/dist/src/webrtc/rtc-peer-connection.d.ts +47 -0
- package/dist/src/webrtc/rtc-peer-connection.d.ts.map +1 -0
- package/dist/src/webrtc/rtc-peer-connection.js +245 -0
- package/dist/src/webrtc/rtc-peer-connection.js.map +1 -0
- package/dist/src/webrtc/rtc-session-description.d.ts +10 -0
- package/dist/src/webrtc/rtc-session-description.d.ts.map +1 -0
- package/dist/src/webrtc/rtc-session-description.js +18 -0
- package/dist/src/webrtc/rtc-session-description.js.map +1 -0
- package/package.json +29 -121
- package/src/error.ts +2 -2
- package/src/index.ts +1 -1
- package/src/maconn.ts +13 -8
- package/src/muxer.ts +11 -5
- package/src/private-to-private/handler.ts +124 -103
- package/src/private-to-private/listener.ts +4 -3
- package/src/private-to-private/transport.ts +20 -12
- package/src/private-to-private/util.ts +1 -0
- package/src/private-to-public/options.ts +1 -1
- package/src/private-to-public/sdp.ts +1 -1
- package/src/private-to-public/transport.ts +113 -107
- package/src/private-to-public/util.ts +0 -1
- package/src/stream.ts +29 -16
- package/src/webrtc/index.browser.ts +4 -0
- package/src/webrtc/index.ts +12 -0
- package/src/webrtc/rtc-data-channel.ts +140 -0
- package/src/webrtc/rtc-events.ts +19 -0
- package/src/webrtc/rtc-ice-candidate.ts +50 -0
- package/src/webrtc/rtc-peer-connection.ts +306 -0
- package/src/webrtc/rtc-session-description.ts +19 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @see https://developer.mozilla.org/docs/Web/API/RTCSessionDescription
|
|
3
|
+
*/
|
|
4
|
+
export class SessionDescription {
|
|
5
|
+
sdp;
|
|
6
|
+
type;
|
|
7
|
+
constructor(init) {
|
|
8
|
+
this.sdp = init.sdp ?? '';
|
|
9
|
+
this.type = init.type;
|
|
10
|
+
}
|
|
11
|
+
toJSON() {
|
|
12
|
+
return {
|
|
13
|
+
sdp: this.sdp,
|
|
14
|
+
type: this.type
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=rtc-session-description.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rtc-session-description.js","sourceRoot":"","sources":["../../../src/webrtc/rtc-session-description.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACpB,GAAG,CAAQ;IACX,IAAI,CAAY;IAEzB,YAAa,IAA+B;QAC1C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,MAAM;QACJ,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAA;IACH,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/webrtc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-e66f4891",
|
|
4
4
|
"description": "A libp2p transport using WebRTC connections",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "Apache-2.0 OR MIT",
|
|
7
|
-
"homepage": "https://github.com/libp2p/js-libp2p-webrtc#readme",
|
|
7
|
+
"homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/transport-webrtc#readme",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/libp2p/js-libp2p
|
|
10
|
+
"url": "git+https://github.com/libp2p/js-libp2p.git"
|
|
11
11
|
},
|
|
12
12
|
"bugs": {
|
|
13
|
-
"url": "https://github.com/libp2p/js-libp2p
|
|
14
|
-
},
|
|
15
|
-
"engines": {
|
|
16
|
-
"node": ">=18.0.0",
|
|
17
|
-
"npm": ">=8.6.0"
|
|
13
|
+
"url": "https://github.com/libp2p/js-libp2p/issues"
|
|
18
14
|
},
|
|
19
15
|
"type": "module",
|
|
20
16
|
"types": "./dist/src/index.d.ts",
|
|
@@ -22,8 +18,7 @@
|
|
|
22
18
|
"src",
|
|
23
19
|
"dist",
|
|
24
20
|
"!dist/test",
|
|
25
|
-
"!**/*.tsbuildinfo"
|
|
26
|
-
"proto_ts"
|
|
21
|
+
"!**/*.tsbuildinfo"
|
|
27
22
|
],
|
|
28
23
|
"exports": {
|
|
29
24
|
".": {
|
|
@@ -37,147 +32,60 @@
|
|
|
37
32
|
"sourceType": "module"
|
|
38
33
|
}
|
|
39
34
|
},
|
|
40
|
-
"release": {
|
|
41
|
-
"branches": [
|
|
42
|
-
"main"
|
|
43
|
-
],
|
|
44
|
-
"plugins": [
|
|
45
|
-
[
|
|
46
|
-
"@semantic-release/commit-analyzer",
|
|
47
|
-
{
|
|
48
|
-
"preset": "conventionalcommits",
|
|
49
|
-
"releaseRules": [
|
|
50
|
-
{
|
|
51
|
-
"breaking": true,
|
|
52
|
-
"release": "major"
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"revert": true,
|
|
56
|
-
"release": "patch"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"type": "feat",
|
|
60
|
-
"release": "minor"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"type": "fix",
|
|
64
|
-
"release": "patch"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"type": "docs",
|
|
68
|
-
"release": "patch"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"type": "test",
|
|
72
|
-
"release": "patch"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"type": "deps",
|
|
76
|
-
"release": "patch"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"scope": "no-release",
|
|
80
|
-
"release": false
|
|
81
|
-
}
|
|
82
|
-
]
|
|
83
|
-
}
|
|
84
|
-
],
|
|
85
|
-
[
|
|
86
|
-
"@semantic-release/release-notes-generator",
|
|
87
|
-
{
|
|
88
|
-
"preset": "conventionalcommits",
|
|
89
|
-
"presetConfig": {
|
|
90
|
-
"types": [
|
|
91
|
-
{
|
|
92
|
-
"type": "feat",
|
|
93
|
-
"section": "Features"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"type": "fix",
|
|
97
|
-
"section": "Bug Fixes"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"type": "chore",
|
|
101
|
-
"section": "Trivial Changes"
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"type": "docs",
|
|
105
|
-
"section": "Documentation"
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"type": "deps",
|
|
109
|
-
"section": "Dependencies"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
"type": "test",
|
|
113
|
-
"section": "Tests"
|
|
114
|
-
}
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
],
|
|
119
|
-
"@semantic-release/changelog",
|
|
120
|
-
"@semantic-release/npm",
|
|
121
|
-
"@semantic-release/github",
|
|
122
|
-
"@semantic-release/git"
|
|
123
|
-
]
|
|
124
|
-
},
|
|
125
35
|
"scripts": {
|
|
126
36
|
"generate": "protons src/private-to-private/pb/message.proto src/pb/message.proto",
|
|
127
37
|
"build": "aegir build",
|
|
128
|
-
"test": "aegir test -t browser",
|
|
38
|
+
"test": "aegir test -t node -t browser -t electron-main",
|
|
39
|
+
"test:node": "aegir test -t node --cov",
|
|
129
40
|
"test:chrome": "aegir test -t browser --cov",
|
|
130
41
|
"test:firefox": "aegir test -t browser -- --browser firefox",
|
|
131
42
|
"lint": "aegir lint",
|
|
132
43
|
"lint:fix": "aegir lint --fix",
|
|
133
44
|
"clean": "aegir clean",
|
|
134
|
-
"dep-check": "aegir dep-check
|
|
135
|
-
"release": "aegir release"
|
|
45
|
+
"dep-check": "aegir dep-check"
|
|
136
46
|
},
|
|
137
47
|
"dependencies": {
|
|
138
48
|
"@chainsafe/libp2p-noise": "^12.0.0",
|
|
139
|
-
"@libp2p/interface
|
|
140
|
-
"@libp2p/interface-
|
|
141
|
-
"@libp2p/
|
|
142
|
-
"@libp2p/
|
|
143
|
-
"@libp2p/interface-stream-muxer": "^4.1.2",
|
|
144
|
-
"@libp2p/interface-transport": "^4.0.3",
|
|
145
|
-
"@libp2p/interfaces": "^3.3.2",
|
|
146
|
-
"@libp2p/logger": "^2.0.7",
|
|
147
|
-
"@libp2p/peer-id": "^2.0.3",
|
|
49
|
+
"@libp2p/interface": "0.1.0-e66f4891",
|
|
50
|
+
"@libp2p/interface-internal": "0.1.0-e66f4891",
|
|
51
|
+
"@libp2p/logger": "3.0.0-e66f4891",
|
|
52
|
+
"@libp2p/peer-id": "3.0.0-e66f4891",
|
|
148
53
|
"@multiformats/mafmt": "^12.1.2",
|
|
149
|
-
"@multiformats/multiaddr": "^12.1.
|
|
54
|
+
"@multiformats/multiaddr": "^12.1.3",
|
|
150
55
|
"abortable-iterator": "^5.0.1",
|
|
151
56
|
"detect-browser": "^5.3.0",
|
|
152
57
|
"it-length-prefixed": "^9.0.1",
|
|
153
|
-
"it-pb-stream": "^4.0.1",
|
|
154
58
|
"it-pipe": "^3.0.1",
|
|
155
|
-
"it-
|
|
59
|
+
"it-protobuf-stream": "^1.0.0",
|
|
60
|
+
"it-pushable": "^3.2.0",
|
|
156
61
|
"it-stream-types": "^2.0.1",
|
|
157
62
|
"it-to-buffer": "^4.0.2",
|
|
158
|
-
"multiformats": "^
|
|
63
|
+
"multiformats": "^12.0.1",
|
|
159
64
|
"multihashes": "^4.0.3",
|
|
65
|
+
"node-datachannel": "^0.4.3",
|
|
160
66
|
"p-defer": "^4.0.0",
|
|
161
67
|
"p-event": "^6.0.0",
|
|
162
68
|
"protons-runtime": "^5.0.0",
|
|
163
69
|
"uint8arraylist": "^2.4.3",
|
|
164
|
-
"uint8arrays": "^4.0.
|
|
70
|
+
"uint8arrays": "^4.0.4"
|
|
165
71
|
},
|
|
166
72
|
"devDependencies": {
|
|
167
|
-
"@chainsafe/libp2p-yamux": "^4.0.
|
|
168
|
-
"@libp2p/interface-
|
|
169
|
-
"@libp2p/
|
|
170
|
-
"@libp2p/
|
|
171
|
-
"@
|
|
172
|
-
"
|
|
173
|
-
"aegir": "^39.0.7",
|
|
73
|
+
"@chainsafe/libp2p-yamux": "^4.0.0",
|
|
74
|
+
"@libp2p/interface-compliance-tests": "4.0.0-e66f4891",
|
|
75
|
+
"@libp2p/peer-id-factory": "3.0.0-e66f4891",
|
|
76
|
+
"@libp2p/websockets": "7.0.0-e66f4891",
|
|
77
|
+
"@types/sinon": "^10.0.15",
|
|
78
|
+
"aegir": "^40.0.1",
|
|
174
79
|
"delay": "^6.0.0",
|
|
175
80
|
"it-length": "^3.0.2",
|
|
176
81
|
"it-map": "^3.0.3",
|
|
177
82
|
"it-pair": "^2.0.6",
|
|
178
|
-
"libp2p": "
|
|
83
|
+
"libp2p": "0.46.0-e66f4891",
|
|
179
84
|
"protons": "^7.0.2",
|
|
180
|
-
"sinon": "^15.
|
|
85
|
+
"sinon": "^15.1.2",
|
|
181
86
|
"sinon-ts": "^1.0.0"
|
|
87
|
+
},
|
|
88
|
+
"browser": {
|
|
89
|
+
"./dist/src/webrtc/index.js": "./dist/src/webrtc/index.browser.js"
|
|
182
90
|
}
|
|
183
91
|
}
|
package/src/error.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CodeError } from '@libp2p/
|
|
2
|
-
import type { Direction } from '@libp2p/interface
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
2
|
+
import type { Direction } from '@libp2p/interface/connection'
|
|
3
3
|
|
|
4
4
|
export enum codes {
|
|
5
5
|
ERR_ALREADY_ABORTED = 'ERR_ALREADY_ABORTED',
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WebRTCTransport } from './private-to-private/transport.js'
|
|
2
2
|
import { WebRTCDirectTransport, type WebRTCTransportDirectInit, type WebRTCDirectTransportComponents } from './private-to-public/transport.js'
|
|
3
3
|
import type { WebRTCTransportComponents, WebRTCTransportInit } from './private-to-private/transport.js'
|
|
4
|
-
import type { Transport } from '@libp2p/interface
|
|
4
|
+
import type { Transport } from '@libp2p/interface/transport'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @param {WebRTCTransportDirectInit} init - WebRTC direct transport configuration
|
package/src/maconn.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { logger } from '@libp2p/logger'
|
|
2
2
|
import { nopSink, nopSource } from './util.js'
|
|
3
|
-
import type { MultiaddrConnection, MultiaddrConnectionTimeline } from '@libp2p/interface
|
|
4
|
-
import type { CounterGroup } from '@libp2p/interface
|
|
5
|
-
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
3
|
+
import type { MultiaddrConnection, MultiaddrConnectionTimeline } from '@libp2p/interface/connection'
|
|
4
|
+
import type { CounterGroup } from '@libp2p/interface/metrics'
|
|
5
|
+
import type { AbortOptions, Multiaddr } from '@multiformats/multiaddr'
|
|
6
6
|
import type { Source, Sink } from 'it-stream-types'
|
|
7
7
|
|
|
8
8
|
const log = logger('libp2p:webrtc:connection')
|
|
@@ -72,14 +72,19 @@ export class WebRTCMultiaddrConnection implements MultiaddrConnection {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
async close (
|
|
76
|
-
if (err !== undefined) {
|
|
77
|
-
log.error('error closing connection', err)
|
|
78
|
-
}
|
|
75
|
+
async close (options?: AbortOptions): Promise<void> {
|
|
79
76
|
log.trace('closing connection')
|
|
80
77
|
|
|
81
|
-
this.timeline.close = Date.now()
|
|
82
78
|
this.peerConnection.close()
|
|
79
|
+
this.timeline.close = Date.now()
|
|
83
80
|
this.metrics?.increment({ close: true })
|
|
84
81
|
}
|
|
82
|
+
|
|
83
|
+
abort (err: Error): void {
|
|
84
|
+
log.error('closing connection due to error', err)
|
|
85
|
+
|
|
86
|
+
this.peerConnection.close()
|
|
87
|
+
this.timeline.close = Date.now()
|
|
88
|
+
this.metrics?.increment({ abort: true })
|
|
89
|
+
}
|
|
85
90
|
}
|
package/src/muxer.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createStream } from './stream.js'
|
|
2
2
|
import { nopSink, nopSource } from './util.js'
|
|
3
3
|
import type { DataChannelOpts } from './stream.js'
|
|
4
|
-
import type { Stream } from '@libp2p/interface
|
|
5
|
-
import type { CounterGroup } from '@libp2p/interface
|
|
6
|
-
import type { StreamMuxer, StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interface
|
|
4
|
+
import type { Stream } from '@libp2p/interface/connection'
|
|
5
|
+
import type { CounterGroup } from '@libp2p/interface/metrics'
|
|
6
|
+
import type { StreamMuxer, StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interface/stream-muxer'
|
|
7
|
+
import type { AbortOptions } from '@multiformats/multiaddr'
|
|
7
8
|
import type { Source, Sink } from 'it-stream-types'
|
|
8
9
|
import type { Uint8ArrayList } from 'uint8arraylist'
|
|
9
10
|
|
|
@@ -93,9 +94,14 @@ export class DataChannelMuxer implements StreamMuxer {
|
|
|
93
94
|
private readonly metrics?: CounterGroup
|
|
94
95
|
|
|
95
96
|
/**
|
|
96
|
-
*
|
|
97
|
+
* Gracefully close all tracked streams and stop the muxer
|
|
97
98
|
*/
|
|
98
|
-
close: (
|
|
99
|
+
close: (options?: AbortOptions) => Promise<void> = async () => { }
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Abort all tracked streams and stop the muxer
|
|
103
|
+
*/
|
|
104
|
+
abort: (err: Error) => void = () => { }
|
|
99
105
|
|
|
100
106
|
/**
|
|
101
107
|
* The stream source, a no-op as the transport natively supports multiplexing
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { CodeError } from '@libp2p/interface/errors'
|
|
1
2
|
import { logger } from '@libp2p/logger'
|
|
2
3
|
import { abortableDuplex } from 'abortable-iterator'
|
|
3
|
-
import { pbStream } from 'it-
|
|
4
|
+
import { pbStream } from 'it-protobuf-stream'
|
|
4
5
|
import pDefer, { type DeferredPromise } from 'p-defer'
|
|
5
6
|
import { DataChannelMuxerFactory } from '../muxer.js'
|
|
7
|
+
import { RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
|
|
6
8
|
import { Message } from './pb/message.js'
|
|
7
9
|
import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
|
|
8
10
|
import type { DataChannelOpts } from '../stream.js'
|
|
9
|
-
import type { Stream } from '@libp2p/interface
|
|
10
|
-
import type {
|
|
11
|
-
import type {
|
|
11
|
+
import type { Stream } from '@libp2p/interface/connection'
|
|
12
|
+
import type { StreamMuxerFactory } from '@libp2p/interface/stream-muxer'
|
|
13
|
+
import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
|
|
12
14
|
|
|
13
15
|
const DEFAULT_TIMEOUT = 30 * 1000
|
|
14
16
|
|
|
@@ -20,66 +22,75 @@ export async function handleIncomingStream ({ rtcConfiguration, dataChannelOptio
|
|
|
20
22
|
const signal = AbortSignal.timeout(DEFAULT_TIMEOUT)
|
|
21
23
|
const stream = pbStream(abortableDuplex(rawStream, signal)).pb(Message)
|
|
22
24
|
const pc = new RTCPeerConnection(rtcConfiguration)
|
|
23
|
-
const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
|
|
24
|
-
const connectedPromise: DeferredPromise<void> = pDefer()
|
|
25
|
-
const answerSentPromise: DeferredPromise<void> = pDefer()
|
|
26
|
-
|
|
27
|
-
signal.onabort = () => { connectedPromise.reject() }
|
|
28
|
-
// candidate callbacks
|
|
29
|
-
pc.onicecandidate = ({ candidate }) => {
|
|
30
|
-
answerSentPromise.promise.then(
|
|
31
|
-
() => {
|
|
32
|
-
stream.write({
|
|
33
|
-
type: Message.Type.ICE_CANDIDATE,
|
|
34
|
-
data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
|
|
35
|
-
})
|
|
36
|
-
},
|
|
37
|
-
(err) => {
|
|
38
|
-
log.error('cannot set candidate since sending answer failed', err)
|
|
39
|
-
}
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
25
|
|
|
43
|
-
|
|
26
|
+
try {
|
|
27
|
+
const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
|
|
28
|
+
const connectedPromise: DeferredPromise<void> = pDefer()
|
|
29
|
+
const answerSentPromise: DeferredPromise<void> = pDefer()
|
|
30
|
+
|
|
31
|
+
signal.onabort = () => {
|
|
32
|
+
connectedPromise.reject(new CodeError('Timed out while trying to connect', 'ERR_TIMEOUT'))
|
|
33
|
+
}
|
|
34
|
+
// candidate callbacks
|
|
35
|
+
pc.onicecandidate = ({ candidate }) => {
|
|
36
|
+
answerSentPromise.promise.then(
|
|
37
|
+
async () => {
|
|
38
|
+
await stream.write({
|
|
39
|
+
type: Message.Type.ICE_CANDIDATE,
|
|
40
|
+
data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
|
|
41
|
+
})
|
|
42
|
+
},
|
|
43
|
+
(err) => {
|
|
44
|
+
log.error('cannot set candidate since sending answer failed', err)
|
|
45
|
+
connectedPromise.reject(err)
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
resolveOnConnected(pc, connectedPromise)
|
|
51
|
+
|
|
52
|
+
// read an SDP offer
|
|
53
|
+
const pbOffer = await stream.read()
|
|
54
|
+
if (pbOffer.type !== Message.Type.SDP_OFFER) {
|
|
55
|
+
throw new Error(`expected message type SDP_OFFER, received: ${pbOffer.type ?? 'undefined'} `)
|
|
56
|
+
}
|
|
57
|
+
const offer = new RTCSessionDescription({
|
|
58
|
+
type: 'offer',
|
|
59
|
+
sdp: pbOffer.data
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
await pc.setRemoteDescription(offer).catch(err => {
|
|
63
|
+
log.error('could not execute setRemoteDescription', err)
|
|
64
|
+
throw new Error('Failed to set remoteDescription')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// create and write an SDP answer
|
|
68
|
+
const answer = await pc.createAnswer().catch(err => {
|
|
69
|
+
log.error('could not execute createAnswer', err)
|
|
70
|
+
answerSentPromise.reject(err)
|
|
71
|
+
throw new Error('Failed to create answer')
|
|
72
|
+
})
|
|
73
|
+
// write the answer to the remote
|
|
74
|
+
await stream.write({ type: Message.Type.SDP_ANSWER, data: answer.sdp })
|
|
75
|
+
|
|
76
|
+
await pc.setLocalDescription(answer).catch(err => {
|
|
77
|
+
log.error('could not execute setLocalDescription', err)
|
|
78
|
+
answerSentPromise.reject(err)
|
|
79
|
+
throw new Error('Failed to set localDescription')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
answerSentPromise.resolve()
|
|
44
83
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
84
|
+
// wait until candidates are connected
|
|
85
|
+
await readCandidatesUntilConnected(connectedPromise, pc, stream)
|
|
86
|
+
|
|
87
|
+
const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
|
|
88
|
+
|
|
89
|
+
return { pc, muxerFactory, remoteAddress }
|
|
90
|
+
} catch (err) {
|
|
91
|
+
pc.close()
|
|
92
|
+
throw err
|
|
49
93
|
}
|
|
50
|
-
const offer = new RTCSessionDescription({
|
|
51
|
-
type: 'offer',
|
|
52
|
-
sdp: pbOffer.data
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
await pc.setRemoteDescription(offer).catch(err => {
|
|
56
|
-
log.error('could not execute setRemoteDescription', err)
|
|
57
|
-
throw new Error('Failed to set remoteDescription')
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
// create and write an SDP answer
|
|
61
|
-
const answer = await pc.createAnswer().catch(err => {
|
|
62
|
-
log.error('could not execute createAnswer', err)
|
|
63
|
-
answerSentPromise.reject(err)
|
|
64
|
-
throw new Error('Failed to create answer')
|
|
65
|
-
})
|
|
66
|
-
// write the answer to the remote
|
|
67
|
-
stream.write({ type: Message.Type.SDP_ANSWER, data: answer.sdp })
|
|
68
|
-
|
|
69
|
-
await pc.setLocalDescription(answer).catch(err => {
|
|
70
|
-
log.error('could not execute setLocalDescription', err)
|
|
71
|
-
answerSentPromise.reject(err)
|
|
72
|
-
throw new Error('Failed to set localDescription')
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
answerSentPromise.resolve()
|
|
76
|
-
|
|
77
|
-
// wait until candidates are connected
|
|
78
|
-
await readCandidatesUntilConnected(connectedPromise, pc, stream)
|
|
79
|
-
|
|
80
|
-
const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
|
|
81
|
-
|
|
82
|
-
return { pc, muxerFactory, remoteAddress }
|
|
83
94
|
}
|
|
84
95
|
|
|
85
96
|
export interface ConnectOptions {
|
|
@@ -93,53 +104,63 @@ export async function initiateConnection ({ rtcConfiguration, dataChannelOptions
|
|
|
93
104
|
const stream = pbStream(abortableDuplex(rawStream, signal)).pb(Message)
|
|
94
105
|
// setup peer connection
|
|
95
106
|
const pc = new RTCPeerConnection(rtcConfiguration)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
|
|
110
|
+
|
|
111
|
+
const connectedPromise: DeferredPromise<void> = pDefer()
|
|
112
|
+
resolveOnConnected(pc, connectedPromise)
|
|
113
|
+
|
|
114
|
+
// reject the connectedPromise if the signal aborts
|
|
115
|
+
signal.onabort = connectedPromise.reject
|
|
116
|
+
// we create the channel so that the peerconnection has a component for which
|
|
117
|
+
// to collect candidates. The label is not relevant to connection initiation
|
|
118
|
+
// but can be useful for debugging
|
|
119
|
+
const channel = pc.createDataChannel('init')
|
|
120
|
+
// setup callback to write ICE candidates to the remote
|
|
121
|
+
// peer
|
|
122
|
+
pc.onicecandidate = ({ candidate }) => {
|
|
123
|
+
void stream.write({
|
|
124
|
+
type: Message.Type.ICE_CANDIDATE,
|
|
125
|
+
data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
|
|
126
|
+
})
|
|
127
|
+
.catch(err => {
|
|
128
|
+
log.error('error sending ICE candidate', err)
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// create an offer
|
|
133
|
+
const offerSdp = await pc.createOffer()
|
|
134
|
+
// write the offer to the stream
|
|
135
|
+
await stream.write({ type: Message.Type.SDP_OFFER, data: offerSdp.sdp })
|
|
136
|
+
// set offer as local description
|
|
137
|
+
await pc.setLocalDescription(offerSdp).catch(err => {
|
|
138
|
+
log.error('could not execute setLocalDescription', err)
|
|
139
|
+
throw new Error('Failed to set localDescription')
|
|
113
140
|
})
|
|
114
|
-
}
|
|
115
|
-
// create an offer
|
|
116
|
-
const offerSdp = await pc.createOffer()
|
|
117
|
-
// write the offer to the stream
|
|
118
|
-
stream.write({ type: Message.Type.SDP_OFFER, data: offerSdp.sdp })
|
|
119
|
-
// set offer as local description
|
|
120
|
-
await pc.setLocalDescription(offerSdp).catch(err => {
|
|
121
|
-
log.error('could not execute setLocalDescription', err)
|
|
122
|
-
throw new Error('Failed to set localDescription')
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
// read answer
|
|
126
|
-
const answerMessage = await stream.read()
|
|
127
|
-
if (answerMessage.type !== Message.Type.SDP_ANSWER) {
|
|
128
|
-
throw new Error('remote should send an SDP answer')
|
|
129
|
-
}
|
|
130
141
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
142
|
+
// read answer
|
|
143
|
+
const answerMessage = await stream.read()
|
|
144
|
+
if (answerMessage.type !== Message.Type.SDP_ANSWER) {
|
|
145
|
+
throw new Error('remote should send an SDP answer')
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const answerSdp = new RTCSessionDescription({ type: 'answer', sdp: answerMessage.data })
|
|
149
|
+
await pc.setRemoteDescription(answerSdp).catch(err => {
|
|
150
|
+
log.error('could not execute setRemoteDescription', err)
|
|
151
|
+
throw new Error('Failed to set remoteDescription')
|
|
152
|
+
})
|
|
136
153
|
|
|
137
|
-
|
|
138
|
-
|
|
154
|
+
await readCandidatesUntilConnected(connectedPromise, pc, stream)
|
|
155
|
+
channel.close()
|
|
139
156
|
|
|
140
|
-
|
|
157
|
+
const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
|
|
141
158
|
|
|
142
|
-
|
|
159
|
+
return { pc, muxerFactory, remoteAddress }
|
|
160
|
+
} catch (err) {
|
|
161
|
+
pc.close()
|
|
162
|
+
throw err
|
|
163
|
+
}
|
|
143
164
|
}
|
|
144
165
|
|
|
145
166
|
function parseRemoteAddress (sdp: string): string {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { EventEmitter } from '@libp2p/
|
|
1
|
+
import { EventEmitter } from '@libp2p/interface/events'
|
|
2
2
|
import { Circuit } from '@multiformats/mafmt'
|
|
3
|
-
import type { PeerId } from '@libp2p/interface
|
|
4
|
-
import type { ListenerEvents, Listener
|
|
3
|
+
import type { PeerId } from '@libp2p/interface/peer-id'
|
|
4
|
+
import type { ListenerEvents, Listener } from '@libp2p/interface/transport'
|
|
5
|
+
import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
|
|
5
6
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
6
7
|
|
|
7
8
|
export interface ListenerOptions {
|