@libp2p/utils 7.4.1 → 7.4.2-974e63f20

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.
@@ -67,6 +67,18 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
67
67
 
68
68
  #readableEnded = false
69
69
 
70
+ /**
71
+ * The error the stream was aborted or reset with, thrown by async iterators
72
+ * after they have yielded all received data
73
+ */
74
+ #closeError?: Error
75
+
76
+ /**
77
+ * Ends active async iterators. Unlike 'end' these run each time the readable
78
+ * end is done, eg. again after data is pushed back following 'end'
79
+ */
80
+ readonly #iteratorEnds = new Set<() => void>()
81
+
70
82
  private onDrainPromise?: PromiseWithResolvers<void>
71
83
 
72
84
  constructor (init: MessageStreamInit) {
@@ -145,36 +157,51 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
145
157
  }
146
158
 
147
159
  async * [Symbol.asyncIterator] (): AsyncGenerator<Uint8Array | Uint8ArrayList> {
148
- if (this.readStatus !== 'readable' && this.readStatus !== 'paused') {
149
- return
150
- }
151
-
152
160
  const output = pushable<Uint8Array | Uint8ArrayList>()
161
+ let error: Error | undefined
153
162
 
154
163
  const streamAsyncIterableOnMessageListener = (evt: StreamMessageEvent): void => {
155
164
  output.push(evt.data)
156
165
  }
157
166
  this.addEventListener('message', streamAsyncIterableOnMessageListener)
158
167
 
159
- const streamAsyncIterableOnCloseListener = (evt: StreamCloseEvent): void => {
160
- output.end(evt.error)
161
- }
162
- this.addEventListener('close', streamAsyncIterableOnCloseListener)
168
+ const streamAsyncIterableEnd = (): void => {
169
+ this.#iteratorEnds.delete(streamAsyncIterableEnd)
170
+ // data pushed back later must stay buffered for the next reader
171
+ this.removeEventListener('message', streamAsyncIterableOnMessageListener)
163
172
 
164
- const streamAsyncIterableOnRemoteCloseWriteListener = (): void => {
173
+ // ending the pushable with an error discards data not yet yielded, so
174
+ // throw the error after the output drains instead
175
+ error = this.#closeError
165
176
  output.end()
166
177
  }
167
- this.addEventListener('remoteCloseWrite', streamAsyncIterableOnRemoteCloseWriteListener)
178
+ this.#iteratorEnds.add(streamAsyncIterableEnd)
179
+
180
+ // there may already be nothing left to read
181
+ if (this.readableDone()) {
182
+ streamAsyncIterableEnd()
183
+ }
168
184
 
169
185
  try {
170
186
  yield * output
187
+
188
+ if (error != null) {
189
+ throw error
190
+ }
171
191
  } finally {
172
192
  this.removeEventListener('message', streamAsyncIterableOnMessageListener)
173
- this.removeEventListener('close', streamAsyncIterableOnCloseListener)
174
- this.removeEventListener('remoteCloseWrite', streamAsyncIterableOnRemoteCloseWriteListener)
193
+ this.#iteratorEnds.delete(streamAsyncIterableEnd)
175
194
  }
176
195
  }
177
196
 
197
+ /**
198
+ * Returns true if nothing is buffered and nothing more will arrive, because
199
+ * the remote writable end is closed or our readable end is closing or closed
200
+ */
201
+ private readableDone (): boolean {
202
+ return this.readBuffer.byteLength === 0 && (this.remoteWriteStatus === 'closed' || this.readStatus === 'closing' || this.readStatus === 'closed')
203
+ }
204
+
178
205
  isReadable (): boolean {
179
206
  return this.status === 'open'
180
207
  }
@@ -196,12 +223,22 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
196
223
  */
197
224
  abort (err: Error): void {
198
225
  if (this.status === 'aborted' || this.status === 'reset' || this.status === 'closed') {
226
+ // a paused reader can still hold unread data after the stream closes,
227
+ // discard it so iterators waiting on it end
228
+ if (this.readBuffer.byteLength > 0) {
229
+ this.#closeError ??= err
230
+ this.readBuffer.consume(this.readBuffer.byteLength)
231
+ this.readStatus = 'closed'
232
+ this.maybeDispatchEnd()
233
+ }
234
+
199
235
  return
200
236
  }
201
237
 
202
238
  this.log.error('abort with error - %e', err)
203
239
 
204
240
  this.status = 'aborted'
241
+ this.#closeError = err
205
242
 
206
243
  // throw away unread data
207
244
  if (this.readBuffer.byteLength > 0) {
@@ -346,12 +383,20 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
346
383
  }
347
384
 
348
385
  /**
349
- * Receive a reset message - close immediately for reading and writing (remote
350
- * error)
386
+ * Receive a reset message (remote error) - close immediately for writing,
387
+ * buffered data can still be read. Ignored once the stream has closed
351
388
  */
352
389
  onRemoteReset (): void {
390
+ // only emit one 'close' event and keep the first close error
391
+ if (this.status === 'aborted' || this.status === 'reset' || this.status === 'closed') {
392
+ return
393
+ }
394
+
353
395
  this.log('remote reset')
354
396
 
397
+ const err = new StreamResetError()
398
+ this.#closeError = err
399
+
355
400
  this.status = 'reset'
356
401
  this.writeStatus = 'closed'
357
402
  this.remoteWriteStatus = 'closed'
@@ -363,7 +408,7 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
363
408
  this.maybeDispatchEnd()
364
409
  }
365
410
 
366
- this.dispatchEvent(new StreamResetEvent(new StreamResetError()))
411
+ this.dispatchEvent(new StreamResetEvent(err))
367
412
  }
368
413
 
369
414
  /**
@@ -539,15 +584,17 @@ export abstract class AbstractMessageStream<Timeline extends MessageStreamTimeli
539
584
  }
540
585
 
541
586
  /**
542
- * Emit 'end' if nothing is buffered and no more data will be delivered.
543
- * Emits at most once
587
+ * If nothing is buffered and no more data will be delivered, end any active
588
+ * async iterators and emit 'end'. 'end' is emitted at most once
544
589
  */
545
590
  protected maybeDispatchEnd (): void {
546
- if (this.#readableEnded || this.readBuffer.byteLength > 0) {
591
+ if (!this.readableDone()) {
547
592
  return
548
593
  }
549
594
 
550
- if (this.remoteWriteStatus !== 'closed' && this.readStatus !== 'closed') {
595
+ this.#iteratorEnds.forEach(end => { end() })
596
+
597
+ if (this.#readableEnded) {
551
598
  return
552
599
  }
553
600
 
@@ -81,11 +81,21 @@ export abstract class AbstractStream extends AbstractMessageStream implements St
81
81
 
82
82
  this.readStatus = 'closing'
83
83
 
84
- await this.sendCloseRead(options)
85
-
86
- this.readStatus = 'closed'
84
+ // no more data can be read, so end iterators and emit 'end' without waiting
85
+ // for the remote to be told
87
86
  this.maybeDispatchEnd()
88
87
 
88
+ try {
89
+ await this.sendCloseRead(options)
90
+ } catch (err) {
91
+ this.log.error('failed to close readable end - %e', err)
92
+ throw err
93
+ } finally {
94
+ // unread data has been discarded so the readable end is closed even if
95
+ // the remote could not be told
96
+ this.readStatus = 'closed'
97
+ }
98
+
89
99
  this.log('closed readable end gracefully')
90
100
  }
91
101
 
@@ -126,6 +126,11 @@ export function byteStream <T extends MessageStream> (stream: T, opts?: ByteStre
126
126
  }
127
127
 
128
128
  const byteStreamOnMessageListener = (evt: StreamMessageEvent): void => {
129
+ // the underlying stream owns incoming data once we have been unwrapped
130
+ if (unwrapped) {
131
+ return
132
+ }
133
+
129
134
  if (overflow != null) {
130
135
  // the stream is being aborted after a previous overflow, ignore any
131
136
  // more data
@@ -265,6 +270,7 @@ export function byteStream <T extends MessageStream> (stream: T, opts?: ByteStre
265
270
  if (readBuffer.byteLength > 0) {
266
271
  stream.log('stream unwrapped with %d unread bytes', readBuffer.byteLength)
267
272
  stream.unshift(readBuffer)
273
+ readBuffer.consume(readBuffer.byteLength)
268
274
  }
269
275
 
270
276
  return stream
@@ -1,130 +0,0 @@
1
- {
2
- "AbstractMessageStream": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.AbstractMessageStream.html",
3
- "AbstractMultiaddrConnection": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.AbstractMultiaddrConnection.html",
4
- "AbstractStream": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.AbstractStream.html",
5
- "AbstractStreamMuxer": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.AbstractStreamMuxer.html",
6
- "AdaptiveTimeout": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.AdaptiveTimeout.html",
7
- "BloomFilter": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.BloomFilter.html",
8
- "CuckooFilter": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.CuckooFilter.html",
9
- "InvalidDataLengthError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.InvalidDataLengthError.html",
10
- "InvalidDataLengthLengthError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.InvalidDataLengthLengthError.html",
11
- "InvalidMessageLengthError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.InvalidMessageLengthError.html",
12
- "LengthPrefixedDecoder": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.LengthPrefixedDecoder.html",
13
- "MaxEarlyStreamsError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.MaxEarlyStreamsError.html",
14
- "MemoryStorage": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.MemoryStorage.html",
15
- "MockStream": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.MockStream.html",
16
- "MovingAverage": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.MovingAverage.html",
17
- "PeerQueue": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.PeerQueue.html",
18
- "PriorityQueue": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.PriorityQueue.html",
19
- "Queue": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.Queue.html",
20
- "QueueFullError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.QueueFullError.html",
21
- "RateLimiter": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.RateLimiter.html",
22
- "RateLimitError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.RateLimitError.html",
23
- "ScalableCuckooFilter": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.ScalableCuckooFilter.html",
24
- "StreamClosedError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.StreamClosedError.html",
25
- "UnexpectedEOFError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.UnexpectedEOFError.html",
26
- "UnwrappedError": "https://libp2p.github.io/js-libp2p/classes/_libp2p_utils.UnwrappedError.html",
27
- "AbstractMultiaddrConnectionInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.AbstractMultiaddrConnectionInit.html",
28
- "AbstractStreamInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.AbstractStreamInit.html",
29
- "AbstractStreamMuxerInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.AbstractStreamMuxerInit.html",
30
- "AdaptiveTimeoutInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.AdaptiveTimeoutInit.html",
31
- "AdaptiveTimeoutSignal": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.AdaptiveTimeoutSignal.html",
32
- "BloomFilterOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.BloomFilterOptions.html",
33
- "Bucket": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Bucket.html",
34
- "ByteStream": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ByteStream.html",
35
- "ByteStreamOpts": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ByteStreamOpts.html",
36
- "Comparator": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Comparator.html",
37
- "CreateTrackedListInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.CreateTrackedListInit.html",
38
- "CreateTrackedMapInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.CreateTrackedMapInit.html",
39
- "CuckooFilterInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.CuckooFilterInit.html",
40
- "DebouncedFunction": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.DebouncedFunction.html",
41
- "DNS4NetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.DNS4NetConfig.html",
42
- "DNS6NetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.DNS6NetConfig.html",
43
- "DNSAddrNetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.DNSAddrNetConfig.html",
44
- "DNSNetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.DNSNetConfig.html",
45
- "Filter": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Filter.html",
46
- "Fingerprint": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Fingerprint.html",
47
- "GetKeySecDurationOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.GetKeySecDurationOptions.html",
48
- "GetTimeoutSignalOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.GetTimeoutSignalOptions.html",
49
- "Hash": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Hash.html",
50
- "IP4NetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.IP4NetConfig.html",
51
- "IP6NetConfig": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.IP6NetConfig.html",
52
- "Job": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.Job.html",
53
- "JobMatcher": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.JobMatcher.html",
54
- "JobRecipient": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.JobRecipient.html",
55
- "JobTimeline": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.JobTimeline.html",
56
- "LengthPrefixedDecoderInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.LengthPrefixedDecoderInit.html",
57
- "LengthPrefixedStream": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.LengthPrefixedStream.html",
58
- "LengthPrefixedStreamOpts": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.LengthPrefixedStreamOpts.html",
59
- "MessageStreamInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.MessageStreamInit.html",
60
- "MockMultiaddrConnectionInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.MockMultiaddrConnectionInit.html",
61
- "MockMuxedStreamInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.MockMuxedStreamInit.html",
62
- "MultiaddrConnectionPairOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.MultiaddrConnectionPairOptions.html",
63
- "PeerQueueJobOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.PeerQueueJobOptions.html",
64
- "PriorityQueueJobOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.PriorityQueueJobOptions.html",
65
- "ProtobufDecoder": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ProtobufDecoder.html",
66
- "ProtobufEncoder": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ProtobufEncoder.html",
67
- "ProtobufMessageStream": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ProtobufMessageStream.html",
68
- "ProtobufStream": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ProtobufStream.html",
69
- "ProtobufStreamOpts": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ProtobufStreamOpts.html",
70
- "QueueEvents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.QueueEvents.html",
71
- "QueueInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.QueueInit.html",
72
- "QueueJobFailure": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.QueueJobFailure.html",
73
- "QueueJobSuccess": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.QueueJobSuccess.html",
74
- "RateLimiterInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RateLimiterInit.html",
75
- "RateLimiterResult": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RateLimiterResult.html",
76
- "RateRecord": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RateRecord.html",
77
- "ReadBytesOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ReadBytesOptions.html",
78
- "RepeatingTask": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RepeatingTask.html",
79
- "RepeatingTaskOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RepeatingTaskOptions.html",
80
- "RunFunction": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.RunFunction.html",
81
- "ScalableCuckooFilterInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.ScalableCuckooFilterInit.html",
82
- "SendResult": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.SendResult.html",
83
- "StreamPairOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.StreamPairOptions.html",
84
- "TrackedMapInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_utils.TrackedMapInit.html",
85
- "JobStatus": "https://libp2p.github.io/js-libp2p/types/_libp2p_utils.JobStatus.html",
86
- "NetConfig": "https://libp2p.github.io/js-libp2p/types/_libp2p_utils.NetConfig.html",
87
- "PipeInput": "https://libp2p.github.io/js-libp2p/types/_libp2p_utils.PipeInput.html",
88
- "DEFAULT_FAILURE_MULTIPLIER": "https://libp2p.github.io/js-libp2p/variables/_libp2p_utils.DEFAULT_FAILURE_MULTIPLIER.html",
89
- "DEFAULT_INTERVAL": "https://libp2p.github.io/js-libp2p/variables/_libp2p_utils.DEFAULT_INTERVAL.html",
90
- "DEFAULT_MAX_TIMEOUT": "https://libp2p.github.io/js-libp2p/variables/_libp2p_utils.DEFAULT_MAX_TIMEOUT.html",
91
- "DEFAULT_MIN_TIMEOUT": "https://libp2p.github.io/js-libp2p/variables/_libp2p_utils.DEFAULT_MIN_TIMEOUT.html",
92
- "DEFAULT_TIMEOUT_MULTIPLIER": "https://libp2p.github.io/js-libp2p/variables/_libp2p_utils.DEFAULT_TIMEOUT_MULTIPLIER.html",
93
- "byteStream": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.byteStream.html",
94
- "circuitRelayAddressesLast": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.circuitRelayAddressesLast.html",
95
- "createBloomFilter": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.createBloomFilter.html",
96
- "createCuckooFilter": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.createCuckooFilter.html",
97
- "createScalableCuckooFilter": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.createScalableCuckooFilter.html",
98
- "debounce": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.debounce.html",
99
- "defaultMultiaddrSorter": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.defaultMultiaddrSorter.html",
100
- "echo": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.echo.html",
101
- "echoStream": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.echoStream.html",
102
- "getNetConfig": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.getNetConfig.html",
103
- "getThinWaistAddresses": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.getThinWaistAddresses.html",
104
- "ipPortToMultiaddr": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.ipPortToMultiaddr.html",
105
- "isAsyncGenerator": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isAsyncGenerator.html",
106
- "isGenerator": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isGenerator.html",
107
- "isGlobalUnicast": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isGlobalUnicast.html",
108
- "isGlobalUnicastIp": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isGlobalUnicastIp.html",
109
- "isLinkLocal": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isLinkLocal.html",
110
- "isLinkLocalIp": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isLinkLocalIp.html",
111
- "isLoopback": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isLoopback.html",
112
- "isNetworkAddress": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isNetworkAddress.html",
113
- "isPrivate": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isPrivate.html",
114
- "isPrivateIp": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isPrivateIp.html",
115
- "isPromise": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.isPromise.html",
116
- "loopbackAddressLast": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.loopbackAddressLast.html",
117
- "lpStream": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.lpStream.html",
118
- "messageStreamToDuplex": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.messageStreamToDuplex.html",
119
- "mockMuxer": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.mockMuxer.html",
120
- "multiaddrConnectionPair": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.multiaddrConnectionPair.html",
121
- "pbStream": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.pbStream.html",
122
- "pipe": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.pipe.html",
123
- "publicAddressesFirst": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.publicAddressesFirst.html",
124
- "reliableTransportsFirst": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.reliableTransportsFirst.html",
125
- "repeatingTask": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.repeatingTask.html",
126
- "streamPair": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.streamPair.html",
127
- "trackedList": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.trackedList.html",
128
- "trackedMap": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.trackedMap.html",
129
- "tryGetNetConfig": "https://libp2p.github.io/js-libp2p/functions/_libp2p_utils.tryGetNetConfig.html"
130
- }