@libp2p/webrtc 3.2.6 → 3.2.7-dfbe0cc0

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 +29 -20
  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 +6 -8
  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 +41 -21
  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 +6 -8
  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,10 +137,22 @@ 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) })
131
- }
140
+ this.init.streams.forEach(bufferedStream => {
141
+ bufferedStream.onEnd = () => {
142
+ this.#onStreamEnd(bufferedStream.stream, bufferedStream.channel)
143
+ }
144
+
145
+ this.metrics?.increment({ incoming_stream: true })
146
+ this.init?.onIncomingStream?.(bufferedStream.stream)
147
+ })
148
+ }
149
+
150
+ #onStreamEnd (stream: Stream, channel: RTCDataChannel): void {
151
+ log.trace('stream %s %s %s onEnd', stream.direction, stream.id, stream.protocol)
152
+ drainAndClose(channel, `${stream.direction} ${stream.id} ${stream.protocol}`, this.dataChannelOptions.drainTimeout)
153
+ this.streams = this.streams.filter(s => s.id !== stream.id)
154
+ this.metrics?.increment({ stream_end: true })
155
+ this.init?.onStreamEnd?.(stream)
132
156
  }
133
157
 
134
158
  /**
@@ -170,11 +194,7 @@ export class DataChannelMuxer implements StreamMuxer {
170
194
  channel,
171
195
  direction: 'outbound',
172
196
  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)
197
+ this.#onStreamEnd(stream, channel)
178
198
  },
179
199
  ...this.dataChannelOptions
180
200
  })
@@ -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
 
@@ -121,10 +121,6 @@ export class WebRTCTransport implements Transport, Startable {
121
121
  log.trace('dialing address: %a', ma)
122
122
 
123
123
  const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration)
124
- const muxerFactory = new DataChannelMuxerFactory({
125
- peerConnection,
126
- dataChannelOptions: this.init.dataChannel
127
- })
128
124
 
129
125
  const { remoteAddress } = await initiateConnection({
130
126
  peerConnection,
@@ -145,7 +141,10 @@ export class WebRTCTransport implements Transport, Startable {
145
141
  const connection = await options.upgrader.upgradeOutbound(webRTCConn, {
146
142
  skipProtection: true,
147
143
  skipEncryption: true,
148
- muxerFactory
144
+ muxerFactory: new DataChannelMuxerFactory({
145
+ peerConnection,
146
+ dataChannelOptions: this.init.dataChannel
147
+ })
149
148
  })
150
149
 
151
150
  // close the connection on shut down
@@ -157,7 +156,6 @@ export class WebRTCTransport implements Transport, Startable {
157
156
  async _onProtocol ({ connection, stream }: IncomingStreamData): Promise<void> {
158
157
  const signal = AbortSignal.timeout(this.init.inboundConnectionTimeout ?? INBOUND_CONNECTION_TIMEOUT)
159
158
  const peerConnection = new RTCPeerConnection(this.init.rtcConfiguration)
160
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection, dataChannelOptions: this.init.dataChannel })
161
159
 
162
160
  try {
163
161
  const { remoteAddress } = await handleIncomingStream({
@@ -170,7 +168,7 @@ export class WebRTCTransport implements Transport, Startable {
170
168
  const webRTCConn = new WebRTCMultiaddrConnection({
171
169
  peerConnection,
172
170
  timeline: { open: (new Date()).getTime() },
173
- remoteAddr: multiaddr(remoteAddress).encapsulate(`/p2p/${connection.remotePeer.toString()}`),
171
+ remoteAddr: remoteAddress,
174
172
  metrics: this.metrics?.listenerEvents
175
173
  })
176
174
 
@@ -180,7 +178,7 @@ export class WebRTCTransport implements Transport, Startable {
180
178
  await this.components.upgrader.upgradeInbound(webRTCConn, {
181
179
  skipEncryption: true,
182
180
  skipProtection: true,
183
- muxerFactory
181
+ muxerFactory: new DataChannelMuxerFactory({ peerConnection, dataChannelOptions: this.init.dataChannel })
184
182
  })
185
183
 
186
184
  // close the stream if SDP messages have been exchanged successfully
@@ -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
- }