@libp2p/webrtc 3.2.6 → 3.2.7-d25d9510

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.
Files changed (31) hide show
  1. package/dist/index.min.js +10 -11
  2. package/dist/src/muxer.d.ts +9 -2
  3. package/dist/src/muxer.d.ts.map +1 -1
  4. package/dist/src/muxer.js +38 -19
  5. package/dist/src/muxer.js.map +1 -1
  6. package/dist/src/private-to-private/initiate-connection.d.ts +1 -1
  7. package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
  8. package/dist/src/private-to-private/initiate-connection.js +4 -6
  9. package/dist/src/private-to-private/initiate-connection.js.map +1 -1
  10. package/dist/src/private-to-private/signaling-stream-handler.d.ts +2 -1
  11. package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
  12. package/dist/src/private-to-private/signaling-stream-handler.js +3 -2
  13. package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
  14. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  15. package/dist/src/private-to-private/transport.js +5 -2
  16. package/dist/src/private-to-private/transport.js.map +1 -1
  17. package/dist/src/private-to-private/util.d.ts +0 -1
  18. package/dist/src/private-to-private/util.d.ts.map +1 -1
  19. package/dist/src/private-to-private/util.js +0 -10
  20. package/dist/src/private-to-private/util.js.map +1 -1
  21. package/dist/src/stream.d.ts.map +1 -1
  22. package/dist/src/stream.js +0 -1
  23. package/dist/src/stream.js.map +1 -1
  24. package/package.json +9 -9
  25. package/src/muxer.ts +50 -20
  26. package/src/private-to-private/initiate-connection.ts +5 -7
  27. package/src/private-to-private/signaling-stream-handler.ts +4 -3
  28. package/src/private-to-private/transport.ts +5 -2
  29. package/src/private-to-private/util.ts +0 -13
  30. package/src/stream.ts +0 -1
  31. package/dist/typedoc-urls.json +0 -8
package/src/muxer.ts CHANGED
@@ -32,6 +32,12 @@ export interface DataChannelMuxerFactoryInit {
32
32
  dataChannelOptions?: DataChannelOptions
33
33
  }
34
34
 
35
+ interface BufferedStream {
36
+ stream: Stream
37
+ channel: RTCDataChannel
38
+ onEnd(err?: Error): void
39
+ }
40
+
35
41
  export class DataChannelMuxerFactory implements StreamMuxerFactory {
36
42
  public readonly protocol: string
37
43
 
@@ -39,7 +45,7 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
39
45
  * WebRTC Peer Connection
40
46
  */
41
47
  private readonly peerConnection: RTCPeerConnection
42
- private streamBuffer: Stream[] = []
48
+ private bufferedStreams: BufferedStream[] = []
43
49
  private readonly metrics?: CounterGroup
44
50
  private readonly dataChannelOptions?: DataChannelOptions
45
51
 
@@ -51,15 +57,25 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
51
57
 
52
58
  // store any datachannels opened before upgrade has been completed
53
59
  this.peerConnection.ondatachannel = ({ channel }) => {
60
+ // @ts-expect-error fields are set below
61
+ const bufferedStream: BufferedStream = {}
62
+
54
63
  const stream = createStream({
55
64
  channel,
56
65
  direction: 'inbound',
57
- onEnd: () => {
58
- this.streamBuffer = this.streamBuffer.filter(s => s.id !== stream.id)
66
+ onEnd: (err) => {
67
+ bufferedStream.onEnd(err)
59
68
  },
60
69
  ...this.dataChannelOptions
61
70
  })
62
- this.streamBuffer.push(stream)
71
+
72
+ bufferedStream.stream = stream
73
+ bufferedStream.channel = channel
74
+ bufferedStream.onEnd = () => {
75
+ this.bufferedStreams = this.bufferedStreams.filter(s => s.stream.id !== stream.id)
76
+ }
77
+
78
+ this.bufferedStreams.push(bufferedStream)
63
79
  }
64
80
  }
65
81
 
@@ -69,14 +85,14 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
69
85
  peerConnection: this.peerConnection,
70
86
  dataChannelOptions: this.dataChannelOptions,
71
87
  metrics: this.metrics,
72
- streams: this.streamBuffer,
88
+ streams: this.bufferedStreams,
73
89
  protocol: this.protocol
74
90
  })
75
91
  }
76
92
  }
77
93
 
78
94
  export interface DataChannelMuxerInit extends DataChannelMuxerFactoryInit, StreamMuxerInit {
79
- streams: Stream[]
95
+ streams: BufferedStream[]
80
96
  }
81
97
 
82
98
  /**
@@ -94,7 +110,7 @@ export class DataChannelMuxer implements StreamMuxer {
94
110
  private readonly metrics?: CounterGroup
95
111
 
96
112
  constructor (readonly init: DataChannelMuxerInit) {
97
- this.streams = init.streams
113
+ this.streams = init.streams.map(s => s.stream)
98
114
  this.peerConnection = init.peerConnection
99
115
  this.protocol = init.protocol ?? PROTOCOL
100
116
  this.metrics = init.metrics
@@ -111,11 +127,7 @@ export class DataChannelMuxer implements StreamMuxer {
111
127
  channel,
112
128
  direction: 'inbound',
113
129
  onEnd: () => {
114
- log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
115
- drainAndClose(channel, `inbound ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
116
- this.streams = this.streams.filter(s => s.id !== stream.id)
117
- this.metrics?.increment({ stream_end: true })
118
- init?.onStreamEnd?.(stream)
130
+ this.#onStreamEnd(stream, channel)
119
131
  },
120
132
  ...this.dataChannelOptions
121
133
  })
@@ -125,12 +137,34 @@ export class DataChannelMuxer implements StreamMuxer {
125
137
  init?.onIncomingStream?.(stream)
126
138
  }
127
139
 
128
- const onIncomingStream = init?.onIncomingStream
129
- if (onIncomingStream != null) {
130
- this.streams.forEach(s => { onIncomingStream(s) })
140
+ // the DataChannelMuxer constructor is called during set up of the
141
+ // connection by the upgrader.
142
+ //
143
+ // If we invoke `init.onIncomingStream` immediately, the connection object
144
+ // will not be set up yet so add a tiny delay before letting the
145
+ // connection know about early streams
146
+ if (this.init.streams.length > 0) {
147
+ queueMicrotask(() => {
148
+ this.init.streams.forEach(bufferedStream => {
149
+ bufferedStream.onEnd = () => {
150
+ this.#onStreamEnd(bufferedStream.stream, bufferedStream.channel)
151
+ }
152
+
153
+ this.metrics?.increment({ incoming_stream: true })
154
+ this.init?.onIncomingStream?.(bufferedStream.stream)
155
+ })
156
+ })
131
157
  }
132
158
  }
133
159
 
160
+ #onStreamEnd (stream: Stream, channel: RTCDataChannel): void {
161
+ log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
162
+ drainAndClose(channel, `${stream.direction} ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
163
+ this.streams = this.streams.filter(s => s.id !== stream.id)
164
+ this.metrics?.increment({ stream_end: true })
165
+ this.init?.onStreamEnd?.(stream)
166
+ }
167
+
134
168
  /**
135
169
  * Gracefully close all tracked streams and stop the muxer
136
170
  */
@@ -170,11 +204,7 @@ export class DataChannelMuxer implements StreamMuxer {
170
204
  channel,
171
205
  direction: 'outbound',
172
206
  onEnd: () => {
173
- log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
174
- drainAndClose(channel, `outbound ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
175
- this.streams = this.streams.filter(s => s.id !== stream.id)
176
- this.metrics?.increment({ stream_end: true })
177
- this.init?.onStreamEnd?.(stream)
207
+ this.#onStreamEnd(stream, channel)
178
208
  },
179
209
  ...this.dataChannelOptions
180
210
  })
@@ -1,18 +1,18 @@
1
1
  import { CodeError } from '@libp2p/interface/errors'
2
2
  import { logger } from '@libp2p/logger'
3
3
  import { peerIdFromString } from '@libp2p/peer-id'
4
- import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
5
4
  import { pbStream } from 'it-protobuf-stream'
6
5
  import pDefer, { type DeferredPromise } from 'p-defer'
7
6
  import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
8
7
  import { Message } from './pb/message.js'
9
8
  import { SIGNALING_PROTO_ID, splitAddr, type WebRTCTransportMetrics } from './transport.js'
10
- import { parseRemoteAddress, readCandidatesUntilConnected, resolveOnConnected } from './util.js'
9
+ import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
11
10
  import type { DataChannelOptions } from '../index.js'
12
11
  import type { Connection } from '@libp2p/interface/connection'
13
12
  import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
14
13
  import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
15
14
  import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
15
+ import type { Multiaddr } from '@multiformats/multiaddr'
16
16
 
17
17
  const log = logger('libp2p:webrtc:initiate-connection')
18
18
 
@@ -33,7 +33,7 @@ export interface ConnectOptions {
33
33
  }
34
34
 
35
35
  export async function initiateConnection ({ peerConnection, signal, metrics, multiaddr: ma, connectionManager, transportManager }: ConnectOptions): Promise<{ remoteAddress: Multiaddr }> {
36
- const { baseAddr, peerId } = splitAddr(ma)
36
+ const { baseAddr } = splitAddr(ma)
37
37
 
38
38
  metrics?.dialerEvents.increment({ open: true })
39
39
 
@@ -158,12 +158,10 @@ export async function initiateConnection ({ peerConnection, signal, metrics, mul
158
158
  signal
159
159
  })
160
160
 
161
- const remoteAddress = parseRemoteAddress(peerConnection.currentRemoteDescription?.sdp ?? '')
162
-
163
- log.trace('initiator connected to remote address %s', remoteAddress)
161
+ log.trace('initiator connected to remote address %s', ma)
164
162
 
165
163
  return {
166
- remoteAddress: multiaddr(remoteAddress).encapsulate(`/p2p/${peerId.toString()}`)
164
+ remoteAddress: ma
167
165
  }
168
166
  } catch (err: any) {
169
167
  peerConnection.close()
@@ -1,10 +1,11 @@
1
1
  import { CodeError } from '@libp2p/interface/errors'
2
2
  import { logger } from '@libp2p/logger'
3
+ import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
3
4
  import { pbStream } from 'it-protobuf-stream'
4
5
  import pDefer, { type DeferredPromise } from 'p-defer'
5
6
  import { type RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
6
7
  import { Message } from './pb/message.js'
7
- import { parseRemoteAddress, readCandidatesUntilConnected, resolveOnConnected } from './util.js'
8
+ import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
8
9
  import type { IncomingStreamData } from '@libp2p/interface-internal/registrar'
9
10
 
10
11
  const log = logger('libp2p:webrtc:signaling-stream-handler')
@@ -14,7 +15,7 @@ export interface IncomingStreamOpts extends IncomingStreamData {
14
15
  signal: AbortSignal
15
16
  }
16
17
 
17
- export async function handleIncomingStream ({ peerConnection, stream, signal, connection }: IncomingStreamOpts): Promise<{ remoteAddress: string }> {
18
+ export async function handleIncomingStream ({ peerConnection, stream, signal, connection }: IncomingStreamOpts): Promise<{ remoteAddress: Multiaddr }> {
18
19
  log.trace('new inbound signaling stream')
19
20
 
20
21
  const messageStream = pbStream(stream).pb(Message)
@@ -121,7 +122,7 @@ export async function handleIncomingStream ({ peerConnection, stream, signal, co
121
122
  }
122
123
  }
123
124
 
124
- const remoteAddress = parseRemoteAddress(peerConnection.currentRemoteDescription?.sdp ?? '')
125
+ const remoteAddress = multiaddr(`/webrtc/p2p/${connection.remoteAddr.getPeerId()}`)
125
126
 
126
127
  log.trace('recipient connected to remote address %s', remoteAddress)
127
128
 
@@ -157,7 +157,10 @@ export class WebRTCTransport implements Transport, Startable {
157
157
  async _onProtocol ({ connection, stream }: IncomingStreamData): Promise<void> {
158
158
  const signal = AbortSignal.timeout(this.init.inboundConnectionTimeout ?? INBOUND_CONNECTION_TIMEOUT)
159
159
  const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration)
160
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection, dataChannelOptions: this.init.dataChannel })
160
+ const muxerFactory = new DataChannelMuxerFactory({
161
+ peerConnection,
162
+ dataChannelOptions: this.init.dataChannel
163
+ })
161
164
 
162
165
  try {
163
166
  const { remoteAddress } = await handleIncomingStream({
@@ -170,7 +173,7 @@ export class WebRTCTransport implements Transport, Startable {
170
173
  const webRTCConn = new WebRTCMultiaddrConnection({
171
174
  peerConnection,
172
175
  timeline: { open: (new Date()).getTime() },
173
- remoteAddr: multiaddr(remoteAddress).encapsulate(`/p2p/${connection.remotePeer.toString()}`),
176
+ remoteAddr: remoteAddress,
174
177
  metrics: this.metrics?.listenerEvents
175
178
  })
176
179
 
@@ -110,16 +110,3 @@ export function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredProm
110
110
  }
111
111
  }
112
112
  }
113
-
114
- export function parseRemoteAddress (sdp: string): string {
115
- // 'a=candidate:1746876089 1 udp 2113937151 0614fbad-b...ocal 54882 typ host generation 0 network-cost 999'
116
- const candidateLine = sdp.split('\r\n').filter(line => line.startsWith('a=candidate')).pop()
117
- const candidateParts = candidateLine?.split(' ')
118
-
119
- if (candidateLine == null || candidateParts == null || candidateParts.length < 5) {
120
- log('could not parse remote address from', candidateLine)
121
- return '/webrtc'
122
- }
123
-
124
- return `/dnsaddr/${candidateParts[4]}/${candidateParts[2].toLowerCase()}/${candidateParts[5]}/webrtc`
125
- }
package/src/stream.ts CHANGED
@@ -84,7 +84,6 @@ export class WebRTCStream extends AbstractStream {
84
84
  */
85
85
  private readonly receiveFinAck: DeferredPromise<void>
86
86
  private readonly finAckTimeout: number
87
- // private sentFinAck: boolean
88
87
 
89
88
  constructor (init: WebRTCStreamInit) {
90
89
  // override onEnd to send/receive FIN_ACK before closing the stream
@@ -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
- }