@libp2p/webrtc 4.1.0 → 4.1.1-ce6da9896
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/index.min.js +6 -6
- package/dist/src/constants.d.ts +7 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +17 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/private-to-private/initiate-connection.d.ts +4 -3
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +15 -5
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +7 -5
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +9 -7
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +3 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +3 -0
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/transport.js +2 -2
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/util.d.ts +1 -0
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +13 -0
- package/dist/src/util.js.map +1 -1
- package/package.json +14 -13
- package/src/constants.ts +16 -0
- package/src/private-to-private/initiate-connection.ts +25 -7
- package/src/private-to-private/transport.ts +27 -10
- package/src/private-to-private/util.ts +6 -1
- package/src/private-to-public/transport.ts +2 -2
- package/src/util.ts +17 -0
- package/dist/typedoc-urls.json +0 -8
@@ -1,15 +1,17 @@
|
|
1
1
|
import { CodeError } from '@libp2p/interface'
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
3
3
|
import { pbStream } from 'it-protobuf-stream'
|
4
|
+
import { CustomProgressEvent } from 'progress-events'
|
4
5
|
import { DataChannelMuxerFactory } from '../muxer.js'
|
5
6
|
import { RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
|
6
7
|
import { Message } from './pb/message.js'
|
7
|
-
import { SIGNALING_PROTO_ID, splitAddr, type WebRTCTransportMetrics } from './transport.js'
|
8
|
+
import { SIGNALING_PROTO_ID, splitAddr, type WebRTCDialEvents, type WebRTCTransportMetrics } from './transport.js'
|
8
9
|
import { readCandidatesUntilConnected } from './util.js'
|
9
10
|
import type { DataChannelOptions } from '../index.js'
|
10
11
|
import type { LoggerOptions, Connection, ComponentLogger } from '@libp2p/interface'
|
11
12
|
import type { ConnectionManager, IncomingStreamData, TransportManager } from '@libp2p/interface-internal'
|
12
13
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
14
|
+
import type { ProgressOptions } from 'progress-events'
|
13
15
|
|
14
16
|
export interface IncomingStreamOpts extends IncomingStreamData {
|
15
17
|
rtcConfiguration?: RTCConfiguration
|
@@ -17,7 +19,7 @@ export interface IncomingStreamOpts extends IncomingStreamData {
|
|
17
19
|
signal: AbortSignal
|
18
20
|
}
|
19
21
|
|
20
|
-
export interface ConnectOptions extends LoggerOptions {
|
22
|
+
export interface ConnectOptions extends LoggerOptions, ProgressOptions<WebRTCDialEvents> {
|
21
23
|
rtcConfiguration?: RTCConfiguration
|
22
24
|
dataChannel?: DataChannelOptions
|
23
25
|
multiaddr: Multiaddr
|
@@ -29,7 +31,7 @@ export interface ConnectOptions extends LoggerOptions {
|
|
29
31
|
logger: ComponentLogger
|
30
32
|
}
|
31
33
|
|
32
|
-
export async function initiateConnection ({ rtcConfiguration, dataChannel, signal, metrics, multiaddr: ma, connectionManager, transportManager, log, logger }: ConnectOptions): Promise<{ remoteAddress: Multiaddr, peerConnection: RTCPeerConnection, muxerFactory: DataChannelMuxerFactory }> {
|
34
|
+
export async function initiateConnection ({ rtcConfiguration, dataChannel, signal, metrics, multiaddr: ma, connectionManager, transportManager, log, logger, onProgress }: ConnectOptions): Promise<{ remoteAddress: Multiaddr, peerConnection: RTCPeerConnection, muxerFactory: DataChannelMuxerFactory }> {
|
33
35
|
const { baseAddr } = splitAddr(ma)
|
34
36
|
|
35
37
|
metrics?.dialerEvents.increment({ open: true })
|
@@ -47,20 +49,27 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
47
49
|
let shouldCloseConnection = false
|
48
50
|
|
49
51
|
if (connections.length === 0) {
|
52
|
+
onProgress?.(new CustomProgressEvent('webrtc:dial-relay'))
|
53
|
+
|
50
54
|
// use the transport manager to open a connection. Initiating a WebRTC
|
51
55
|
// connection takes place in the context of a dial - if we use the
|
52
56
|
// connection manager instead we can end up joining our own dial context
|
53
57
|
connection = await transportManager.dial(baseAddr, {
|
54
|
-
signal
|
58
|
+
signal,
|
59
|
+
onProgress
|
55
60
|
})
|
56
61
|
// this connection is unmanaged by the connection manager so we should
|
57
62
|
// close it when we are done
|
58
63
|
shouldCloseConnection = true
|
59
64
|
} else {
|
65
|
+
onProgress?.(new CustomProgressEvent('webrtc:reuse-relay-connection'))
|
66
|
+
|
60
67
|
connection = connections[0]
|
61
68
|
}
|
62
69
|
|
63
70
|
try {
|
71
|
+
onProgress?.(new CustomProgressEvent('webrtc:open-signaling-stream'))
|
72
|
+
|
64
73
|
const stream = await connection.newStream(SIGNALING_PROTO_ID, {
|
65
74
|
signal,
|
66
75
|
runOnTransientConnection: true
|
@@ -113,6 +122,8 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
113
122
|
|
114
123
|
log.trace('initiator send SDP offer %s', offerSdp.sdp)
|
115
124
|
|
125
|
+
onProgress?.(new CustomProgressEvent('webrtc:send-sdp-offer'))
|
126
|
+
|
116
127
|
// write the offer to the stream
|
117
128
|
await messageStream.write({ type: Message.Type.SDP_OFFER, data: offerSdp.sdp }, {
|
118
129
|
signal
|
@@ -124,6 +135,8 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
124
135
|
throw new CodeError('Failed to set localDescription', 'ERR_SDP_HANDSHAKE_FAILED')
|
125
136
|
})
|
126
137
|
|
138
|
+
onProgress?.(new CustomProgressEvent('webrtc:read-sdp-answer'))
|
139
|
+
|
127
140
|
// read answer
|
128
141
|
const answerMessage = await messageStream.read({
|
129
142
|
signal
|
@@ -143,16 +156,21 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
143
156
|
|
144
157
|
log.trace('initiator read candidates until connected')
|
145
158
|
|
159
|
+
onProgress?.(new CustomProgressEvent('webrtc:read-ice-candidates'))
|
160
|
+
|
146
161
|
await readCandidatesUntilConnected(peerConnection, messageStream, {
|
147
162
|
direction: 'initiator',
|
148
163
|
signal,
|
149
|
-
log
|
164
|
+
log,
|
165
|
+
onProgress
|
150
166
|
})
|
151
167
|
|
152
168
|
log.trace('initiator connected, closing init channel')
|
153
169
|
channel.close()
|
154
170
|
|
155
|
-
|
171
|
+
onProgress?.(new CustomProgressEvent('webrtc:close-signaling-stream'))
|
172
|
+
|
173
|
+
log.trace('closing signaling channel')
|
156
174
|
await stream.close({
|
157
175
|
signal
|
158
176
|
})
|
@@ -165,7 +183,7 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
|
|
165
183
|
muxerFactory
|
166
184
|
}
|
167
185
|
} catch (err: any) {
|
168
|
-
log.error('outgoing
|
186
|
+
log.error('outgoing signaling error', err)
|
169
187
|
|
170
188
|
peerConnection.close()
|
171
189
|
stream.abort(err)
|
@@ -1,17 +1,19 @@
|
|
1
|
-
import { CodeError, serviceCapabilities, serviceDependencies, setMaxListeners } from '@libp2p/interface'
|
2
|
-
import { type CreateListenerOptions, type DialOptions, transportSymbol, type Transport, type Listener, type Upgrader, type ComponentLogger, type Logger, type Connection, type PeerId, type CounterGroup, type Metrics, type Startable } from '@libp2p/interface'
|
1
|
+
import { CodeError, serviceCapabilities, serviceDependencies, setMaxListeners, transportSymbol } from '@libp2p/interface'
|
3
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
4
3
|
import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
|
5
4
|
import { WebRTC } from '@multiformats/multiaddr-matcher'
|
6
5
|
import { codes } from '../error.js'
|
7
6
|
import { WebRTCMultiaddrConnection } from '../maconn.js'
|
8
7
|
import { DataChannelMuxerFactory } from '../muxer.js'
|
8
|
+
import { getRtcConfiguration } from '../util.js'
|
9
9
|
import { RTCPeerConnection } from '../webrtc/index.js'
|
10
10
|
import { initiateConnection } from './initiate-connection.js'
|
11
11
|
import { WebRTCPeerListener } from './listener.js'
|
12
12
|
import { handleIncomingStream } from './signaling-stream-handler.js'
|
13
13
|
import type { DataChannelOptions } from '../index.js'
|
14
|
-
import type {
|
14
|
+
import type { OutboundConnectionUpgradeEvents, CreateListenerOptions, DialOptions, Transport, Listener, Upgrader, ComponentLogger, Logger, Connection, PeerId, CounterGroup, Metrics, Startable } from '@libp2p/interface'
|
15
|
+
import type { IncomingStreamData, Registrar, ConnectionManager, TransportManager, OpenConnectionProgressEvents } from '@libp2p/interface-internal'
|
16
|
+
import type { ProgressEvent } from 'progress-events'
|
15
17
|
|
16
18
|
const WEBRTC_TRANSPORT = '/webrtc'
|
17
19
|
const CIRCUIT_RELAY_TRANSPORT = '/p2p-circuit'
|
@@ -44,7 +46,20 @@ export interface WebRTCTransportMetrics {
|
|
44
46
|
listenerEvents: CounterGroup
|
45
47
|
}
|
46
48
|
|
47
|
-
export
|
49
|
+
export type WebRTCDialEvents =
|
50
|
+
OutboundConnectionUpgradeEvents |
|
51
|
+
OpenConnectionProgressEvents |
|
52
|
+
ProgressEvent<'webrtc:dial-relay'> |
|
53
|
+
ProgressEvent<'webrtc:reuse-relay-connection'> |
|
54
|
+
ProgressEvent<'webrtc:open-signaling-stream'> |
|
55
|
+
ProgressEvent<'webrtc:send-sdp-offer'> |
|
56
|
+
ProgressEvent<'webrtc:read-sdp-answer'> |
|
57
|
+
ProgressEvent<'webrtc:read-ice-candidates'> |
|
58
|
+
ProgressEvent<'webrtc:add-ice-candidate', string> |
|
59
|
+
ProgressEvent<'webrtc:end-of-ice-candidates'> |
|
60
|
+
ProgressEvent<'webrtc:close-signaling-stream'>
|
61
|
+
|
62
|
+
export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
|
48
63
|
private readonly log: Logger
|
49
64
|
private _started = false
|
50
65
|
private readonly metrics?: WebRTCTransportMetrics
|
@@ -130,11 +145,11 @@ export class WebRTCTransport implements Transport, Startable {
|
|
130
145
|
* For a circuit relay, this will be of the form
|
131
146
|
* <relay address>/p2p/<relay-peer>/p2p-circuit/webrtc/p2p/<destination-peer>
|
132
147
|
*/
|
133
|
-
async dial (ma: Multiaddr, options: DialOptions): Promise<Connection> {
|
148
|
+
async dial (ma: Multiaddr, options: DialOptions<WebRTCDialEvents>): Promise<Connection> {
|
134
149
|
this.log.trace('dialing address: %a', ma)
|
135
150
|
|
136
151
|
const { remoteAddress, peerConnection, muxerFactory } = await initiateConnection({
|
137
|
-
rtcConfiguration:
|
152
|
+
rtcConfiguration: await getRtcConfiguration(this.init.rtcConfiguration),
|
138
153
|
dataChannel: this.init.dataChannel,
|
139
154
|
multiaddr: ma,
|
140
155
|
dataChannelOptions: this.init.dataChannel,
|
@@ -142,7 +157,8 @@ export class WebRTCTransport implements Transport, Startable {
|
|
142
157
|
connectionManager: this.components.connectionManager,
|
143
158
|
transportManager: this.components.transportManager,
|
144
159
|
log: this.log,
|
145
|
-
logger: this.components.logger
|
160
|
+
logger: this.components.logger,
|
161
|
+
onProgress: options.onProgress
|
146
162
|
})
|
147
163
|
|
148
164
|
const webRTCConn = new WebRTCMultiaddrConnection(this.components, {
|
@@ -155,7 +171,8 @@ export class WebRTCTransport implements Transport, Startable {
|
|
155
171
|
const connection = await options.upgrader.upgradeOutbound(webRTCConn, {
|
156
172
|
skipProtection: true,
|
157
173
|
skipEncryption: true,
|
158
|
-
muxerFactory
|
174
|
+
muxerFactory,
|
175
|
+
onProgress: options.onProgress
|
159
176
|
})
|
160
177
|
|
161
178
|
// close the connection on shut down
|
@@ -166,7 +183,7 @@ export class WebRTCTransport implements Transport, Startable {
|
|
166
183
|
|
167
184
|
async _onProtocol ({ connection, stream }: IncomingStreamData): Promise<void> {
|
168
185
|
const signal = AbortSignal.timeout(this.init.inboundConnectionTimeout ?? INBOUND_CONNECTION_TIMEOUT)
|
169
|
-
const peerConnection = new RTCPeerConnection(
|
186
|
+
const peerConnection = new RTCPeerConnection(await getRtcConfiguration(this.init.rtcConfiguration))
|
170
187
|
const muxerFactory = new DataChannelMuxerFactory(this.components, {
|
171
188
|
peerConnection,
|
172
189
|
dataChannelOptions: this.init.dataChannel
|
@@ -202,7 +219,7 @@ export class WebRTCTransport implements Transport, Startable {
|
|
202
219
|
// close the connection on shut down
|
203
220
|
this._closeOnShutdown(peerConnection, webRTCConn)
|
204
221
|
} catch (err: any) {
|
205
|
-
this.log.error('incoming
|
222
|
+
this.log.error('incoming signaling error', err)
|
206
223
|
|
207
224
|
peerConnection.close()
|
208
225
|
stream.abort(err)
|
@@ -1,13 +1,16 @@
|
|
1
1
|
import { CodeError } from '@libp2p/interface'
|
2
2
|
import pDefer from 'p-defer'
|
3
|
+
import { CustomProgressEvent } from 'progress-events'
|
3
4
|
import { isFirefox } from '../util.js'
|
4
5
|
import { RTCIceCandidate } from '../webrtc/index.js'
|
5
6
|
import { Message } from './pb/message.js'
|
7
|
+
import type { WebRTCDialEvents } from './transport.js'
|
6
8
|
import type { LoggerOptions, Stream } from '@libp2p/interface'
|
7
9
|
import type { AbortOptions, MessageStream } from 'it-protobuf-stream'
|
8
10
|
import type { DeferredPromise } from 'p-defer'
|
11
|
+
import type { ProgressOptions } from 'progress-events'
|
9
12
|
|
10
|
-
export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions {
|
13
|
+
export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions, ProgressOptions<WebRTCDialEvents> {
|
11
14
|
direction: string
|
12
15
|
}
|
13
16
|
|
@@ -44,6 +47,7 @@ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream
|
|
44
47
|
// candidate means candidate gathering has finished
|
45
48
|
// see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
|
46
49
|
if (candidateInit === '' || candidateInit === null) {
|
50
|
+
options.onProgress?.(new CustomProgressEvent('webrtc:end-of-ice-candidates'))
|
47
51
|
options.log.trace('end-of-candidates received')
|
48
52
|
|
49
53
|
continue
|
@@ -54,6 +58,7 @@ export const readCandidatesUntilConnected = async (pc: RTCPeerConnection, stream
|
|
54
58
|
options.log.trace('%s received new ICE candidate %o', options.direction, candidateInit)
|
55
59
|
|
56
60
|
try {
|
61
|
+
options.onProgress?.(new CustomProgressEvent<string>('webrtc:add-ice-candidate', candidate.candidate))
|
57
62
|
await pc.addIceCandidate(candidate)
|
58
63
|
} catch (err) {
|
59
64
|
options.log.error('%s bad candidate received', options.direction, candidateInit, err)
|
@@ -10,7 +10,7 @@ import { dataChannelError, inappropriateMultiaddr, unimplemented, invalidArgumen
|
|
10
10
|
import { WebRTCMultiaddrConnection } from '../maconn.js'
|
11
11
|
import { DataChannelMuxerFactory } from '../muxer.js'
|
12
12
|
import { createStream } from '../stream.js'
|
13
|
-
import { isFirefox } from '../util.js'
|
13
|
+
import { getRtcConfiguration, isFirefox } from '../util.js'
|
14
14
|
import { RTCPeerConnection } from '../webrtc/index.js'
|
15
15
|
import * as sdp from './sdp.js'
|
16
16
|
import { genUfrag } from './util.js'
|
@@ -139,7 +139,7 @@ export class WebRTCDirectTransport implements Transport {
|
|
139
139
|
} as any)
|
140
140
|
|
141
141
|
const peerConnection = new RTCPeerConnection({
|
142
|
-
...(
|
142
|
+
...(await getRtcConfiguration(this.init.rtcConfiguration)),
|
143
143
|
certificates: [certificate]
|
144
144
|
})
|
145
145
|
|
package/src/util.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
import { detect } from 'detect-browser'
|
2
2
|
import pDefer from 'p-defer'
|
3
3
|
import pTimeout from 'p-timeout'
|
4
|
+
import { DEFAULT_ICE_SERVERS } from './constants.js'
|
4
5
|
import type { LoggerOptions } from '@libp2p/interface'
|
5
6
|
|
6
7
|
const browser = detect()
|
@@ -64,3 +65,19 @@ export interface AbortPromiseOptions {
|
|
64
65
|
signal?: AbortSignal
|
65
66
|
message?: string
|
66
67
|
}
|
68
|
+
|
69
|
+
export async function getRtcConfiguration (config?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>)): Promise<RTCConfiguration> {
|
70
|
+
config = config ?? {}
|
71
|
+
|
72
|
+
if (typeof config === 'function') {
|
73
|
+
config = await config()
|
74
|
+
}
|
75
|
+
|
76
|
+
config.iceServers = config.iceServers ?? DEFAULT_ICE_SERVERS.map(url => ({
|
77
|
+
urls: [
|
78
|
+
url
|
79
|
+
]
|
80
|
+
}))
|
81
|
+
|
82
|
+
return config
|
83
|
+
}
|
package/dist/typedoc-urls.json
DELETED
@@ -1,8 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
3
|
-
".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
4
|
-
"webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
5
|
-
".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
6
|
-
"webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
|
7
|
-
".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
|
8
|
-
}
|