@libp2p/webrtc 3.2.10 → 3.2.11-0b4a2ee79

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 (58) hide show
  1. package/README.md +1 -1
  2. package/dist/index.min.js +12 -12
  3. package/dist/src/index.d.ts +5 -0
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/maconn.d.ts +6 -1
  7. package/dist/src/maconn.d.ts.map +1 -1
  8. package/dist/src/maconn.js +6 -6
  9. package/dist/src/maconn.js.map +1 -1
  10. package/dist/src/muxer.d.ts +13 -2
  11. package/dist/src/muxer.d.ts.map +1 -1
  12. package/dist/src/muxer.js +36 -7
  13. package/dist/src/muxer.js.map +1 -1
  14. package/dist/src/private-to-private/initiate-connection.d.ts +3 -2
  15. package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
  16. package/dist/src/private-to-private/initiate-connection.js +3 -4
  17. package/dist/src/private-to-private/initiate-connection.js.map +1 -1
  18. package/dist/src/private-to-private/signaling-stream-handler.d.ts +3 -1
  19. package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
  20. package/dist/src/private-to-private/signaling-stream-handler.js +3 -4
  21. package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
  22. package/dist/src/private-to-private/transport.d.ts +3 -0
  23. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  24. package/dist/src/private-to-private/transport.js +13 -11
  25. package/dist/src/private-to-private/transport.js.map +1 -1
  26. package/dist/src/private-to-private/util.d.ts +2 -1
  27. package/dist/src/private-to-private/util.d.ts.map +1 -1
  28. package/dist/src/private-to-private/util.js +25 -40
  29. package/dist/src/private-to-private/util.js.map +1 -1
  30. package/dist/src/private-to-public/sdp.d.ts +2 -1
  31. package/dist/src/private-to-public/sdp.d.ts.map +1 -1
  32. package/dist/src/private-to-public/sdp.js +3 -6
  33. package/dist/src/private-to-public/sdp.js.map +1 -1
  34. package/dist/src/private-to-public/transport.d.ts +3 -0
  35. package/dist/src/private-to-public/transport.d.ts.map +1 -1
  36. package/dist/src/private-to-public/transport.js +21 -10
  37. package/dist/src/private-to-public/transport.js.map +1 -1
  38. package/dist/src/stream.d.ts +10 -3
  39. package/dist/src/stream.d.ts.map +1 -1
  40. package/dist/src/stream.js +18 -32
  41. package/dist/src/stream.js.map +1 -1
  42. package/dist/src/util.d.ts +2 -1
  43. package/dist/src/util.d.ts.map +1 -1
  44. package/dist/src/util.js +4 -6
  45. package/dist/src/util.js.map +1 -1
  46. package/package.json +21 -20
  47. package/src/index.ts +6 -0
  48. package/src/maconn.ts +12 -7
  49. package/src/muxer.ts +57 -8
  50. package/src/private-to-private/initiate-connection.ts +5 -6
  51. package/src/private-to-private/signaling-stream-handler.ts +5 -5
  52. package/src/private-to-private/transport.ts +15 -12
  53. package/src/private-to-private/util.ts +29 -44
  54. package/src/private-to-public/sdp.ts +4 -8
  55. package/src/private-to-public/transport.ts +23 -11
  56. package/src/stream.ts +26 -37
  57. package/src/util.ts +5 -7
  58. package/dist/typedoc-urls.json +0 -8
@@ -1,19 +1,15 @@
1
1
  import { CodeError } from '@libp2p/interface/errors'
2
- import { logger } from '@libp2p/logger'
3
- import { abortableSource } from 'abortable-iterator'
2
+ import { closeSource } from '@libp2p/utils/close-source'
4
3
  import { anySignal } from 'any-signal'
5
- import * as lp from 'it-length-prefixed'
6
- import { AbortError, raceSignal } from 'race-signal'
7
4
  import { isFirefox } from '../util.js'
8
5
  import { RTCIceCandidate } from '../webrtc/index.js'
9
6
  import { Message } from './pb/message.js'
7
+ import type { LoggerOptions } from '@libp2p/interface'
10
8
  import type { Stream } from '@libp2p/interface/connection'
11
9
  import type { AbortOptions, MessageStream } from 'it-protobuf-stream'
12
10
  import type { DeferredPromise } from 'p-defer'
13
11
 
14
- const log = logger('libp2p:webrtc:peer:util')
15
-
16
- export interface ReadCandidatesOptions extends AbortOptions {
12
+ export interface ReadCandidatesOptions extends AbortOptions, LoggerOptions {
17
13
  direction: string
18
14
  }
19
15
 
@@ -31,71 +27,60 @@ export const readCandidatesUntilConnected = async (connectedPromise: DeferredPro
31
27
  options.signal
32
28
  ])
33
29
 
34
- const source = abortableSource(stream.unwrap().unwrap().source, signal, {
35
- returnOnAbort: true
36
- })
30
+ const abortListener = (): void => {
31
+ closeSource(stream.unwrap().unwrap().source, options.log)
32
+ }
33
+
34
+ signal.addEventListener('abort', abortListener)
37
35
 
38
36
  try {
39
37
  // read candidates until we are connected or we reach the end of the stream
40
- for await (const buf of lp.decode(source)) {
41
- const message = Message.decode(buf)
38
+ while (true) {
39
+ const message = await Promise.race([
40
+ connectedPromise.promise,
41
+ stream.read()
42
+ ])
43
+
44
+ // stream ended or we became connected
45
+ if (message == null) {
46
+ break
47
+ }
42
48
 
43
49
  if (message.type !== Message.Type.ICE_CANDIDATE) {
44
50
  throw new CodeError('ICE candidate message expected', 'ERR_NOT_ICE_CANDIDATE')
45
51
  }
46
52
 
47
- let candidateInit = JSON.parse(message.data ?? 'null')
53
+ const candidateInit = JSON.parse(message.data ?? 'null')
48
54
 
49
- if (candidateInit === '') {
50
- log.trace('end-of-candidates for this generation received')
51
- candidateInit = {
52
- candidate: '',
53
- sdpMid: '0',
54
- sdpMLineIndex: 0
55
- }
56
- }
55
+ // an empty string means this generation of candidates is complete, a null
56
+ // candidate means candidate gathering has finished
57
+ // see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
58
+ if (candidateInit === '' || candidateInit === null) {
59
+ options.log.trace('end-of-candidates received')
57
60
 
58
- if (candidateInit === null) {
59
- log.trace('end-of-candidates received')
60
- candidateInit = {
61
- candidate: null,
62
- sdpMid: '0',
63
- sdpMLineIndex: 0
64
- }
61
+ continue
65
62
  }
66
63
 
67
- // a null candidate means end-of-candidates
68
- // see - https://www.w3.org/TR/webrtc/#rtcpeerconnectioniceevent
69
64
  const candidate = new RTCIceCandidate(candidateInit)
70
65
 
71
- log.trace('%s received new ICE candidate', options.direction, candidate)
66
+ options.log.trace('%s received new ICE candidate', options.direction, candidate)
72
67
 
73
68
  try {
74
69
  await pc.addIceCandidate(candidate)
75
70
  } catch (err) {
76
- log.error('%s bad candidate received', options.direction, err)
71
+ options.log.error('%s bad candidate received', options.direction, candidateInit, err)
77
72
  }
78
73
  }
79
74
  } catch (err) {
80
- log.error('%s error parsing ICE candidate', options.direction, err)
75
+ options.log.error('%s error parsing ICE candidate', options.direction, err)
81
76
  } finally {
77
+ signal.removeEventListener('abort', abortListener)
82
78
  signal.clear()
83
79
  }
84
-
85
- if (options.signal?.aborted === true) {
86
- throw new AbortError('Aborted while reading ICE candidates', 'ERR_ICE_CANDIDATES_READ_ABORTED')
87
- }
88
-
89
- // read all available ICE candidates, wait for connection state change
90
- await raceSignal(connectedPromise.promise, options.signal, {
91
- errorMessage: 'Aborted before connected',
92
- errorCode: 'ERR_ABORTED_BEFORE_CONNECTED'
93
- })
94
80
  }
95
81
 
96
82
  export function resolveOnConnected (pc: RTCPeerConnection, promise: DeferredPromise<void>): void {
97
83
  pc[isFirefox ? 'oniceconnectionstatechange' : 'onconnectionstatechange'] = (_) => {
98
- log.trace('receiver peerConnectionState state change: %s', pc.connectionState)
99
84
  switch (isFirefox ? pc.iceConnectionState : pc.connectionState) {
100
85
  case 'connected':
101
86
  promise.resolve()
@@ -1,24 +1,22 @@
1
- import { logger } from '@libp2p/logger'
2
1
  import { bases } from 'multiformats/basics'
3
2
  import * as multihashes from 'multihashes'
4
3
  import { inappropriateMultiaddr, invalidArgument, invalidFingerprint, unsupportedHashAlgorithm } from '../error.js'
5
4
  import { CERTHASH_CODE } from './transport.js'
5
+ import type { LoggerOptions } from '@libp2p/interface'
6
6
  import type { Multiaddr } from '@multiformats/multiaddr'
7
7
  import type { HashCode, HashName } from 'multihashes'
8
8
 
9
- const log = logger('libp2p:webrtc:sdp')
10
-
11
9
  /**
12
10
  * Get base2 | identity decoders
13
11
  */
14
12
  // @ts-expect-error - Not easy to combine these types.
15
13
  export const mbdecoder: any = Object.values(bases).map(b => b.decoder).reduce((d, b) => d.or(b))
16
14
 
17
- export function getLocalFingerprint (pc: RTCPeerConnection): string | undefined {
15
+ export function getLocalFingerprint (pc: RTCPeerConnection, options: LoggerOptions): string | undefined {
18
16
  // try to fetch fingerprint from local certificate
19
17
  const localCert = pc.getConfiguration().certificates?.at(0)
20
18
  if (localCert == null || localCert.getFingerprints == null) {
21
- log.trace('fetching fingerprint from local SDP')
19
+ options.log.trace('fetching fingerprint from local SDP')
22
20
  const localDescription = pc.localDescription
23
21
  if (localDescription == null) {
24
22
  return undefined
@@ -26,7 +24,7 @@ export function getLocalFingerprint (pc: RTCPeerConnection): string | undefined
26
24
  return getFingerprintFromSdp(localDescription.sdp)
27
25
  }
28
26
 
29
- log.trace('fetching fingerprint from local certificate')
27
+ options.log.trace('fetching fingerprint from local certificate')
30
28
 
31
29
  if (localCert.getFingerprints().length === 0) {
32
30
  return undefined
@@ -55,8 +53,6 @@ function ipv (ma: Multiaddr): string {
55
53
  }
56
54
  }
57
55
 
58
- log('Warning: multiaddr does not appear to contain IP4 or IP6, defaulting to IP6', ma)
59
-
60
56
  return 'IP6'
61
57
  }
62
58
 
@@ -1,6 +1,5 @@
1
1
  import { noise as Noise } from '@chainsafe/libp2p-noise'
2
2
  import { type CreateListenerOptions, symbol, type Transport, type Listener } from '@libp2p/interface/transport'
3
- import { logger } from '@libp2p/logger'
4
3
  import * as p from '@libp2p/peer-id'
5
4
  import { protocols } from '@multiformats/multiaddr'
6
5
  import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
@@ -17,13 +16,12 @@ import * as sdp from './sdp.js'
17
16
  import { genUfrag } from './util.js'
18
17
  import type { WebRTCDialOptions } from './options.js'
19
18
  import type { DataChannelOptions } from '../index.js'
19
+ import type { ComponentLogger, Logger } from '@libp2p/interface'
20
20
  import type { Connection } from '@libp2p/interface/connection'
21
21
  import type { CounterGroup, Metrics } from '@libp2p/interface/metrics'
22
22
  import type { PeerId } from '@libp2p/interface/peer-id'
23
23
  import type { Multiaddr } from '@multiformats/multiaddr'
24
24
 
25
- const log = logger('libp2p:webrtc:transport')
26
-
27
25
  /**
28
26
  * The time to wait, in milliseconds, for the data channel handshake to complete
29
27
  */
@@ -49,6 +47,7 @@ export const CERTHASH_CODE: number = protocols('certhash').code
49
47
  export interface WebRTCDirectTransportComponents {
50
48
  peerId: PeerId
51
49
  metrics?: Metrics
50
+ logger: ComponentLogger
52
51
  }
53
52
 
54
53
  export interface WebRTCMetrics {
@@ -60,10 +59,12 @@ export interface WebRTCTransportDirectInit {
60
59
  }
61
60
 
62
61
  export class WebRTCDirectTransport implements Transport {
62
+ private readonly log: Logger
63
63
  private readonly metrics?: WebRTCMetrics
64
64
  private readonly components: WebRTCDirectTransportComponents
65
65
  private readonly init: WebRTCTransportDirectInit
66
66
  constructor (components: WebRTCDirectTransportComponents, init: WebRTCTransportDirectInit = {}) {
67
+ this.log = components.logger.forComponent('libp2p:webrtc-direct')
67
68
  this.components = components
68
69
  this.init = init
69
70
  if (components.metrics != null) {
@@ -81,7 +82,7 @@ export class WebRTCDirectTransport implements Transport {
81
82
  */
82
83
  async dial (ma: Multiaddr, options: WebRTCDialOptions): Promise<Connection> {
83
84
  const rawConn = await this._connect(ma, options)
84
- log('dialing address: %a', ma)
85
+ this.log('dialing address: %a', ma)
85
86
  return rawConn
86
87
  }
87
88
 
@@ -144,7 +145,7 @@ export class WebRTCDirectTransport implements Transport {
144
145
  const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 })
145
146
  const handshakeTimeout = setTimeout(() => {
146
147
  const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`
147
- log.error(error)
148
+ this.log.error(error)
148
149
  this.metrics?.dialerEvents.increment({ open_error: true })
149
150
  reject(dataChannelError('data', error))
150
151
  }, HANDSHAKE_TIMEOUT_MS)
@@ -159,7 +160,7 @@ export class WebRTCDirectTransport implements Transport {
159
160
  clearTimeout(handshakeTimeout)
160
161
  const errorTarget = event.target?.toString() ?? 'not specified'
161
162
  const error = `Error opening a data channel for handshaking: ${errorTarget}`
162
- log.error(error)
163
+ this.log.error(error)
163
164
  // NOTE: We use unknown error here but this could potentially be considered a reset by some standards.
164
165
  this.metrics?.dialerEvents.increment({ unknown_error: true })
165
166
  reject(dataChannelError('data', error))
@@ -194,7 +195,12 @@ export class WebRTCDirectTransport implements Transport {
194
195
  // we pass in undefined for these parameters.
195
196
  const noise = Noise({ prologueBytes: fingerprintsPrologue })()
196
197
 
197
- const wrappedChannel = createStream({ channel: handshakeDataChannel, direction: 'inbound', ...(this.init.dataChannel ?? {}) })
198
+ const wrappedChannel = createStream({
199
+ channel: handshakeDataChannel,
200
+ direction: 'inbound',
201
+ logger: this.components.logger,
202
+ ...(this.init.dataChannel ?? {})
203
+ })
198
204
  const wrappedDuplex = {
199
205
  ...wrappedChannel,
200
206
  sink: wrappedChannel.sink.bind(wrappedChannel),
@@ -209,7 +215,7 @@ export class WebRTCDirectTransport implements Transport {
209
215
 
210
216
  // Creating the connection before completion of the noise
211
217
  // handshake ensures that the stream opening callback is set up
212
- const maConn = new WebRTCMultiaddrConnection({
218
+ const maConn = new WebRTCMultiaddrConnection(this.components, {
213
219
  peerConnection,
214
220
  remoteAddr: ma,
215
221
  timeline: {
@@ -226,7 +232,7 @@ export class WebRTCDirectTransport implements Transport {
226
232
  case 'disconnected':
227
233
  case 'closed':
228
234
  maConn.close().catch((err) => {
229
- log.error('error closing connection', err)
235
+ this.log.error('error closing connection', err)
230
236
  }).finally(() => {
231
237
  // Remove the event listener once the connection is closed
232
238
  controller.abort()
@@ -240,7 +246,11 @@ export class WebRTCDirectTransport implements Transport {
240
246
  // Track opened peer connection
241
247
  this.metrics?.dialerEvents.increment({ peer_connection: true })
242
248
 
243
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection, metrics: this.metrics?.dialerEvents, dataChannelOptions: this.init.dataChannel })
249
+ const muxerFactory = new DataChannelMuxerFactory(this.components, {
250
+ peerConnection,
251
+ metrics: this.metrics?.dialerEvents,
252
+ dataChannelOptions: this.init.dataChannel
253
+ })
244
254
 
245
255
  // For outbound connections, the remote is expected to start the noise handshake.
246
256
  // Therefore, we need to secure an inbound noise connection from the remote.
@@ -262,7 +272,9 @@ export class WebRTCDirectTransport implements Transport {
262
272
  throw invalidArgument('no local certificate')
263
273
  }
264
274
 
265
- const localFingerprint = sdp.getLocalFingerprint(pc)
275
+ const localFingerprint = sdp.getLocalFingerprint(pc, {
276
+ log: this.log
277
+ })
266
278
  if (localFingerprint == null) {
267
279
  throw invalidArgument('no local fingerprint found')
268
280
  }
package/src/stream.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { CodeError } from '@libp2p/interface/errors'
2
- import { AbstractStream, type AbstractStreamInit } from '@libp2p/interface/stream-muxer/stream'
3
- import { logger } from '@libp2p/logger'
2
+ import { AbstractStream, type AbstractStreamInit } from '@libp2p/utils/abstract-stream'
4
3
  import * as lengthPrefixed from 'it-length-prefixed'
5
4
  import { type Pushable, pushable } from 'it-pushable'
6
5
  import pDefer from 'p-defer'
@@ -10,7 +9,7 @@ import { raceSignal } from 'race-signal'
10
9
  import { Uint8ArrayList } from 'uint8arraylist'
11
10
  import { Message } from './pb/message.js'
12
11
  import type { DataChannelOptions } from './index.js'
13
- import type { AbortOptions } from '@libp2p/interface'
12
+ import type { AbortOptions, ComponentLogger } from '@libp2p/interface'
14
13
  import type { Direction } from '@libp2p/interface/connection'
15
14
  import type { DeferredPromise } from 'p-defer'
16
15
 
@@ -22,6 +21,8 @@ export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions
22
21
  * {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel}
23
22
  */
24
23
  channel: RTCDataChannel
24
+
25
+ logger: ComponentLogger
25
26
  }
26
27
 
27
28
  /**
@@ -56,6 +57,12 @@ export const MAX_MESSAGE_SIZE = 16 * 1024
56
57
  */
57
58
  export const FIN_ACK_TIMEOUT = 5000
58
59
 
60
+ /**
61
+ * When sending data messages, if the channel is not in the "open" state, wait
62
+ * this long for the "open" event to fire.
63
+ */
64
+ export const OPEN_TIMEOUT = 5000
65
+
59
66
  export class WebRTCStream extends AbstractStream {
60
67
  /**
61
68
  * The data channel used to send and receive data
@@ -68,8 +75,6 @@ export class WebRTCStream extends AbstractStream {
68
75
  */
69
76
  private readonly incomingData: Pushable<Uint8Array>
70
77
 
71
- private messageQueue?: Uint8ArrayList
72
-
73
78
  private readonly maxBufferedAmount: number
74
79
 
75
80
  private readonly bufferedAmountLowEventTimeout: number
@@ -84,6 +89,7 @@ export class WebRTCStream extends AbstractStream {
84
89
  */
85
90
  private readonly receiveFinAck: DeferredPromise<void>
86
91
  private readonly finAckTimeout: number
92
+ private readonly openTimeout: number
87
93
 
88
94
  constructor (init: WebRTCStreamInit) {
89
95
  // override onEnd to send/receive FIN_ACK before closing the stream
@@ -121,17 +127,18 @@ export class WebRTCStream extends AbstractStream {
121
127
 
122
128
  this.channel = init.channel
123
129
  this.channel.binaryType = 'arraybuffer'
124
- this.incomingData = pushable()
125
- this.messageQueue = new Uint8ArrayList()
130
+ this.incomingData = pushable<Uint8Array>()
126
131
  this.bufferedAmountLowEventTimeout = init.bufferedAmountLowEventTimeout ?? BUFFERED_AMOUNT_LOW_TIMEOUT
127
132
  this.maxBufferedAmount = init.maxBufferedAmount ?? MAX_BUFFERED_AMOUNT
128
133
  this.maxMessageSize = (init.maxMessageSize ?? MAX_MESSAGE_SIZE) - PROTOBUF_OVERHEAD - VARINT_LENGTH
129
134
  this.receiveFinAck = pDefer()
130
135
  this.finAckTimeout = init.closeTimeout ?? FIN_ACK_TIMEOUT
136
+ this.openTimeout = init.openTimeout ?? OPEN_TIMEOUT
131
137
 
132
138
  // set up initial state
133
139
  switch (this.channel.readyState) {
134
140
  case 'open':
141
+ this.timeline.open = new Date().getTime()
135
142
  break
136
143
 
137
144
  case 'closed':
@@ -152,19 +159,6 @@ export class WebRTCStream extends AbstractStream {
152
159
  // handle RTCDataChannel events
153
160
  this.channel.onopen = (_evt) => {
154
161
  this.timeline.open = new Date().getTime()
155
-
156
- if (this.messageQueue != null && this.messageQueue.byteLength > 0) {
157
- this.log.trace('dataChannel opened, sending queued messages', this.messageQueue.byteLength, this.channel.readyState)
158
-
159
- // send any queued messages
160
- this._sendMessage(this.messageQueue)
161
- .catch(err => {
162
- this.log.error('error sending queued messages', err)
163
- this.abort(err)
164
- })
165
- }
166
-
167
- this.messageQueue = undefined
168
162
  }
169
163
 
170
164
  this.channel.onclose = (_evt) => {
@@ -217,6 +211,7 @@ export class WebRTCStream extends AbstractStream {
217
211
  async _sendMessage (data: Uint8ArrayList, checkBuffer: boolean = true): Promise<void> {
218
212
  if (checkBuffer && this.channel.bufferedAmount > this.maxBufferedAmount) {
219
213
  try {
214
+ this.log('channel buffer is %d, wait for "bufferedamountlow" event', this.channel.bufferedAmount)
220
215
  await pEvent(this.channel, 'bufferedamountlow', { timeout: this.bufferedAmountLowEventTimeout })
221
216
  } catch (err: any) {
222
217
  if (err instanceof TimeoutError) {
@@ -231,22 +226,14 @@ export class WebRTCStream extends AbstractStream {
231
226
  throw new CodeError(`Invalid datachannel state - ${this.channel.readyState}`, 'ERR_INVALID_STATE')
232
227
  }
233
228
 
234
- if (this.channel.readyState === 'open') {
235
- // send message without copying data
236
- for (const buf of data) {
237
- this.channel.send(buf)
238
- }
239
- } else if (this.channel.readyState === 'connecting') {
240
- // queue message for when we are open
241
- if (this.messageQueue == null) {
242
- this.messageQueue = new Uint8ArrayList()
243
- }
244
-
245
- this.messageQueue.append(data)
246
- } else {
247
- this.log.error('unknown datachannel state %s', this.channel.readyState)
248
- throw new CodeError('Unknown datachannel state', 'ERR_INVALID_STATE')
229
+ if (this.channel.readyState !== 'open') {
230
+ this.log('channel state is "%s" and not "open", waiting for "open" event before sending data', this.channel.readyState)
231
+ await pEvent(this.channel, 'open', { timeout: this.openTimeout })
232
+ this.log('channel state is now "%s", sending data', this.channel.readyState)
249
233
  }
234
+
235
+ // send message without copying data
236
+ this.channel.send(data.subarray())
250
237
  }
251
238
 
252
239
  async sendData (data: Uint8ArrayList): Promise<void> {
@@ -341,7 +328,7 @@ export class WebRTCStream extends AbstractStream {
341
328
  // flags can be sent while we or the remote are closing the datachannel so
342
329
  // if the channel isn't open, don't try to send it but return false to let
343
330
  // the caller know and act if they need to
344
- this.log.trace('not sending flag %s because channel is not open', flag.toString())
331
+ this.log.trace('not sending flag %s because channel is "%s" and not "open"', this.channel.readyState, flag.toString())
345
332
  return false
346
333
  }
347
334
 
@@ -379,6 +366,8 @@ export interface WebRTCStreamOptions extends DataChannelOptions {
379
366
  * A callback invoked when the channel ends
380
367
  */
381
368
  onEnd?(err?: Error | undefined): void
369
+
370
+ logger: ComponentLogger
382
371
  }
383
372
 
384
373
  export function createStream (options: WebRTCStreamOptions): WebRTCStream {
@@ -386,7 +375,7 @@ export function createStream (options: WebRTCStreamOptions): WebRTCStream {
386
375
 
387
376
  return new WebRTCStream({
388
377
  id: direction === 'inbound' ? (`i${channel.id}`) : `r${channel.id}`,
389
- log: logger(`libp2p:webrtc:stream:${direction}:${channel.id}`),
378
+ log: options.logger.forComponent(`libp2p:webrtc:stream:${direction}:${channel.id}`),
390
379
  ...options
391
380
  })
392
381
  }
package/src/util.ts CHANGED
@@ -1,9 +1,7 @@
1
- import { logger } from '@libp2p/logger'
2
1
  import { detect } from 'detect-browser'
3
2
  import pDefer from 'p-defer'
4
3
  import pTimeout from 'p-timeout'
5
-
6
- const log = logger('libp2p:webrtc:utils')
4
+ import type { LoggerOptions } from '@libp2p/interface'
7
5
 
8
6
  const browser = detect()
9
7
  export const isFirefox = ((browser != null) && browser.name === 'firefox')
@@ -14,7 +12,7 @@ export const nopSink = async (_: any): Promise<void> => {}
14
12
 
15
13
  export const DATA_CHANNEL_DRAIN_TIMEOUT = 30 * 1000
16
14
 
17
- export function drainAndClose (channel: RTCDataChannel, direction: string, drainTimeout: number = DATA_CHANNEL_DRAIN_TIMEOUT): void {
15
+ export function drainAndClose (channel: RTCDataChannel, direction: string, drainTimeout: number = DATA_CHANNEL_DRAIN_TIMEOUT, options: LoggerOptions): void {
18
16
  if (channel.readyState !== 'open') {
19
17
  return
20
18
  }
@@ -23,7 +21,7 @@ export function drainAndClose (channel: RTCDataChannel, direction: string, drain
23
21
  .then(async () => {
24
22
  // wait for bufferedAmount to become zero
25
23
  if (channel.bufferedAmount > 0) {
26
- log('%s drain channel with %d buffered bytes', direction, channel.bufferedAmount)
24
+ options.log('%s drain channel with %d buffered bytes', direction, channel.bufferedAmount)
27
25
  const deferred = pDefer()
28
26
  let drained = false
29
27
 
@@ -31,7 +29,7 @@ export function drainAndClose (channel: RTCDataChannel, direction: string, drain
31
29
 
32
30
  const closeListener = (): void => {
33
31
  if (!drained) {
34
- log('%s drain channel closed before drain', direction)
32
+ options.log('%s drain channel closed before drain', direction)
35
33
  deferred.resolve()
36
34
  }
37
35
  }
@@ -58,7 +56,7 @@ export function drainAndClose (channel: RTCDataChannel, direction: string, drain
58
56
  }
59
57
  })
60
58
  .catch(err => {
61
- log.error('error closing outbound stream', err)
59
+ options.log.error('error closing outbound stream', err)
62
60
  })
63
61
  }
64
62
 
@@ -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
- }