@helia/bitswap 0.0.0 → 1.0.0-59de059

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 (62) hide show
  1. package/dist/index.min.js +6 -1
  2. package/dist/src/bitswap.d.ts +3 -2
  3. package/dist/src/bitswap.d.ts.map +1 -1
  4. package/dist/src/bitswap.js +7 -14
  5. package/dist/src/bitswap.js.map +1 -1
  6. package/dist/src/constants.d.ts +2 -0
  7. package/dist/src/constants.d.ts.map +1 -1
  8. package/dist/src/constants.js +2 -0
  9. package/dist/src/constants.js.map +1 -1
  10. package/dist/src/index.d.ts +22 -45
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/network.d.ts +8 -7
  14. package/dist/src/network.d.ts.map +1 -1
  15. package/dist/src/network.js +71 -169
  16. package/dist/src/network.js.map +1 -1
  17. package/dist/src/pb/message.d.ts +6 -6
  18. package/dist/src/pb/message.d.ts.map +1 -1
  19. package/dist/src/pb/message.js +37 -20
  20. package/dist/src/pb/message.js.map +1 -1
  21. package/dist/src/peer-want-lists/index.d.ts +3 -2
  22. package/dist/src/peer-want-lists/index.d.ts.map +1 -1
  23. package/dist/src/peer-want-lists/index.js +7 -3
  24. package/dist/src/peer-want-lists/index.js.map +1 -1
  25. package/dist/src/peer-want-lists/ledger.d.ts +3 -1
  26. package/dist/src/peer-want-lists/ledger.d.ts.map +1 -1
  27. package/dist/src/peer-want-lists/ledger.js +8 -0
  28. package/dist/src/peer-want-lists/ledger.js.map +1 -1
  29. package/dist/src/session.d.ts +13 -8
  30. package/dist/src/session.d.ts.map +1 -1
  31. package/dist/src/session.js +25 -88
  32. package/dist/src/session.js.map +1 -1
  33. package/dist/src/stats.d.ts +2 -2
  34. package/dist/src/stats.d.ts.map +1 -1
  35. package/dist/src/stats.js +4 -4
  36. package/dist/src/stats.js.map +1 -1
  37. package/dist/src/utils/merge-messages.d.ts +3 -0
  38. package/dist/src/utils/merge-messages.d.ts.map +1 -0
  39. package/dist/src/utils/merge-messages.js +51 -0
  40. package/dist/src/utils/merge-messages.js.map +1 -0
  41. package/dist/src/utils/split-message.d.ts +14 -0
  42. package/dist/src/utils/split-message.d.ts.map +1 -0
  43. package/dist/src/utils/split-message.js +99 -0
  44. package/dist/src/utils/split-message.js.map +1 -0
  45. package/dist/src/want-list.d.ts +20 -23
  46. package/dist/src/want-list.d.ts.map +1 -1
  47. package/dist/src/want-list.js +136 -133
  48. package/dist/src/want-list.js.map +1 -1
  49. package/package.json +6 -6
  50. package/src/bitswap.ts +9 -16
  51. package/src/constants.ts +2 -0
  52. package/src/index.ts +24 -51
  53. package/src/network.ts +83 -200
  54. package/src/pb/message.ts +40 -20
  55. package/src/peer-want-lists/index.ts +9 -5
  56. package/src/peer-want-lists/ledger.ts +11 -1
  57. package/src/session.ts +31 -120
  58. package/src/stats.ts +6 -6
  59. package/src/utils/merge-messages.ts +70 -0
  60. package/src/utils/split-message.ts +131 -0
  61. package/src/want-list.ts +205 -212
  62. package/dist/typedoc-urls.json +0 -24
package/src/want-list.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { AbortError } from '@libp2p/interface'
2
- import { trackedPeerMap, PeerSet } from '@libp2p/peer-collections'
1
+ import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
2
+ import { trackedPeerMap } from '@libp2p/peer-collections'
3
3
  import { trackedMap } from '@libp2p/utils/tracked-map'
4
4
  import all from 'it-all'
5
5
  import filter from 'it-filter'
@@ -8,14 +8,16 @@ import { pipe } from 'it-pipe'
8
8
  import { CID } from 'multiformats/cid'
9
9
  import { sha256 } from 'multiformats/hashes/sha2'
10
10
  import pDefer from 'p-defer'
11
+ import { raceEvent } from 'race-event'
12
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
11
13
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
12
14
  import { DEFAULT_MESSAGE_SEND_DELAY } from './constants.js'
13
15
  import { BlockPresenceType, WantType } from './pb/message.js'
14
16
  import vd from './utils/varint-decoder.js'
15
- import type { MultihashHasherLoader } from './index.js'
17
+ import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.js'
16
18
  import type { BitswapNetworkWantProgressEvents, Network } from './network.js'
17
19
  import type { BitswapMessage } from './pb/message.js'
18
- import type { ComponentLogger, Metrics, PeerId, Startable, AbortOptions } from '@libp2p/interface'
20
+ import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget } from '@libp2p/interface'
19
21
  import type { Logger } from '@libp2p/logger'
20
22
  import type { PeerMap } from '@libp2p/peer-collections'
21
23
  import type { DeferredPromise } from 'p-defer'
@@ -24,7 +26,7 @@ import type { ProgressOptions } from 'progress-events'
24
26
  export interface WantListComponents {
25
27
  network: Network
26
28
  logger: ComponentLogger
27
- metrics?: Metrics
29
+ libp2p: Libp2p
28
30
  }
29
31
 
30
32
  export interface WantListInit {
@@ -58,29 +60,9 @@ export interface WantListEntry {
58
60
  * Whether the remote should tell us if they have the block or not
59
61
  */
60
62
  sendDontHave: boolean
61
-
62
- /**
63
- * If this set has members, the want will only be sent to these peers
64
- */
65
- session: PeerSet
66
-
67
- /**
68
- * Promises returned from `.wantBlock` for this block
69
- */
70
- blockWantListeners: Array<DeferredPromise<WantBlockResult>>
71
-
72
- /**
73
- * Promises returned from `.wantPresence` for this block
74
- */
75
- blockPresenceListeners: Array<DeferredPromise<WantPresenceResult>>
76
63
  }
77
64
 
78
65
  export interface WantOptions extends AbortOptions, ProgressOptions<BitswapNetworkWantProgressEvents> {
79
- /**
80
- * If set, this WantList entry will only be sent to this peer
81
- */
82
- peerId?: PeerId
83
-
84
66
  /**
85
67
  * Allow prioritising blocks
86
68
  */
@@ -108,7 +90,12 @@ export interface WantHaveResult {
108
90
 
109
91
  export type WantPresenceResult = WantDontHaveResult | WantHaveResult
110
92
 
111
- export class WantList implements Startable {
93
+ export interface WantListEvents {
94
+ block: CustomEvent<WantBlockResult>
95
+ presence: CustomEvent<WantPresenceResult>
96
+ }
97
+
98
+ export class WantList extends TypedEventEmitter<WantListEvents> implements Startable, TypedEventTarget<WantListEvents> {
112
99
  /**
113
100
  * Tracks what CIDs we've previously sent to which peers
114
101
  */
@@ -119,15 +106,19 @@ export class WantList implements Startable {
119
106
  private readonly sendMessagesDelay: number
120
107
  private sendMessagesTimeout?: ReturnType<typeof setTimeout>
121
108
  private readonly hashLoader?: MultihashHasherLoader
109
+ private sendingMessages?: DeferredPromise<void>
122
110
 
123
111
  constructor (components: WantListComponents, init: WantListInit = {}) {
112
+ super()
113
+
114
+ setMaxListeners(Infinity, this)
124
115
  this.peers = trackedPeerMap({
125
- name: 'ipfs_bitswap_peers',
126
- metrics: components.metrics
116
+ name: 'helia_bitswap_peers',
117
+ metrics: components.libp2p.metrics
127
118
  })
128
119
  this.wants = trackedMap({
129
- name: 'ipfs_bitswap_wantlist',
130
- metrics: components.metrics
120
+ name: 'helia_bitswap_wantlist',
121
+ metrics: components.libp2p.metrics
131
122
  })
132
123
  this.network = components.network
133
124
  this.sendMessagesDelay = init.sendMessagesDelay ?? DEFAULT_MESSAGE_SEND_DELAY
@@ -160,17 +151,10 @@ export class WantList implements Startable {
160
151
  if (entry == null) {
161
152
  entry = {
162
153
  cid,
163
- session: new PeerSet(),
164
154
  priority: options.priority ?? 1,
165
155
  wantType: options.wantType ?? WantType.WantBlock,
166
156
  cancel: false,
167
- sendDontHave: true,
168
- blockWantListeners: [],
169
- blockPresenceListeners: []
170
- }
171
-
172
- if (options.peerId != null) {
173
- entry.session.add(options.peerId)
157
+ sendDontHave: true
174
158
  }
175
159
 
176
160
  this.wants.set(cidStr, entry)
@@ -182,46 +166,41 @@ export class WantList implements Startable {
182
166
  entry.wantType = WantType.WantBlock
183
167
  }
184
168
 
185
- // if this want was part of a session..
186
- if (entry.session.size > 0) {
187
- // if the new want is also part of a session, expand the want session to
188
- // include both sets of peers
189
- if (options.peerId != null) {
190
- entry.session.add(options.peerId)
191
- }
192
-
193
- // if the new want is not part of a session, make this want a non-session
194
- // want - nb. this will cause this WantList entry to be sent to every peer
195
- // instead of just the ones in the session
196
- if (options.peerId == null) {
197
- entry.session.clear()
198
- }
199
- }
200
-
201
- // add a promise that will be resolved or rejected when the response arrives
202
- let deferred: DeferredPromise<WantBlockResult | WantPresenceResult>
203
-
204
- if (options.wantType === WantType.WantBlock) {
205
- const p = deferred = pDefer<WantBlockResult>()
169
+ // broadcast changes
170
+ await this.sendMessagesDebounced()
206
171
 
207
- entry.blockWantListeners.push(p)
208
- } else {
209
- const p = deferred = pDefer<WantPresenceResult>()
172
+ try {
173
+ if (options.wantType === WantType.WantBlock) {
174
+ const event = await raceEvent<CustomEvent<WantBlockResult>>(this, 'block', options?.signal, {
175
+ filter: (event) => {
176
+ return uint8ArrayEquals(cid.multihash.digest, event.detail.cid.multihash.digest)
177
+ },
178
+ errorMessage: 'Want was aborted'
179
+ })
210
180
 
211
- entry.blockPresenceListeners.push(p)
212
- }
181
+ return event.detail
182
+ }
213
183
 
214
- // reject the promise if the want is rejected
215
- const abortListener = (): void => {
216
- this.log('want for %c was aborted, cancelling want', cid)
184
+ const event = await raceEvent<CustomEvent<WantPresenceResult>>(this, 'presence', options?.signal, {
185
+ filter: (event) => {
186
+ return uint8ArrayEquals(cid.multihash.digest, event.detail.cid.multihash.digest)
187
+ },
188
+ errorMessage: 'Want was aborted'
189
+ })
217
190
 
218
- if (entry != null) {
191
+ return event.detail
192
+ } finally {
193
+ if (options.signal?.aborted === true) {
194
+ this.log('want for %c was aborted, cancelling want', cid)
219
195
  entry.cancel = true
196
+ // broadcast changes
197
+ await this.sendMessagesDebounced()
220
198
  }
221
-
222
- deferred.reject(new AbortError('Want was aborted'))
223
199
  }
224
- options.signal?.addEventListener('abort', abortListener)
200
+ }
201
+
202
+ private async sendMessagesDebounced (): Promise<void> {
203
+ await this.sendingMessages?.promise
225
204
 
226
205
  // broadcast changes
227
206
  clearTimeout(this.sendMessagesTimeout)
@@ -231,77 +210,65 @@ export class WantList implements Startable {
231
210
  this.log('error sending messages to peers', err)
232
211
  })
233
212
  }, this.sendMessagesDelay)
234
-
235
- try {
236
- return await deferred.promise
237
- } finally {
238
- // remove listener
239
- options.signal?.removeEventListener('abort', abortListener)
240
- // remove deferred promise
241
- if (options.wantType === WantType.WantBlock) {
242
- entry.blockWantListeners = entry.blockWantListeners.filter(recipient => recipient !== deferred)
243
- } else {
244
- entry.blockPresenceListeners = entry.blockPresenceListeners.filter(recipient => recipient !== deferred)
245
- }
246
- }
247
213
  }
248
214
 
249
215
  private async sendMessages (): Promise<void> {
250
- for (const [peerId, sentWants] of this.peers) {
251
- const sent = new Set<string>()
252
- const message: Partial<BitswapMessage> = {
253
- wantlist: {
254
- full: false,
255
- entries: pipe(
256
- this.wants.entries(),
257
- (source) => filter(source, ([key, entry]) => {
258
- // skip session-only wants
259
- if (entry.session.size > 0 && !entry.session.has(peerId)) {
260
- return false
261
- }
262
-
263
- const sentPreviously = sentWants.has(key)
264
-
265
- // don't cancel if we've not sent it to them before
266
- if (entry.cancel) {
267
- return sentPreviously
268
- }
269
-
270
- // only send if we've not sent it to them before
271
- return !sentPreviously
272
- }),
273
- (source) => map(source, ([key, entry]) => {
274
- sent.add(key)
275
-
276
- return {
277
- cid: entry.cid.bytes,
278
- priority: entry.priority,
279
- wantType: entry.wantType,
280
- cancel: entry.cancel,
281
- sendDontHave: entry.sendDontHave
282
- }
283
- }),
284
- (source) => all(source)
285
- )
216
+ this.sendingMessages = pDefer()
217
+
218
+ await Promise.all(
219
+ [...this.peers.entries()].map(async ([peerId, sentWants]) => {
220
+ const sent = new Set<string>()
221
+ const message: Partial<BitswapMessage> = {
222
+ wantlist: {
223
+ full: false,
224
+ entries: pipe(
225
+ this.wants.entries(),
226
+ (source) => filter(source, ([key, entry]) => {
227
+ const sentPreviously = sentWants.has(key)
228
+
229
+ // don't cancel if we've not sent it to them before
230
+ if (entry.cancel) {
231
+ return sentPreviously
232
+ }
233
+
234
+ // only send if we've not sent it to them before
235
+ return !sentPreviously
236
+ }),
237
+ (source) => map(source, ([key, entry]) => {
238
+ sent.add(key)
239
+
240
+ return {
241
+ cid: entry.cid.bytes,
242
+ priority: entry.priority,
243
+ wantType: entry.wantType,
244
+ cancel: entry.cancel,
245
+ sendDontHave: entry.sendDontHave
246
+ }
247
+ }),
248
+ (source) => all(source)
249
+ )
250
+ }
286
251
  }
287
- }
288
252
 
289
- if (message.wantlist?.entries.length === 0) {
290
- return
291
- }
253
+ if (message.wantlist?.entries.length === 0) {
254
+ return
255
+ }
292
256
 
293
- // add message to send queue
294
- try {
295
- await this.network.sendMessage(peerId, message)
257
+ // add message to send queue
258
+ try {
259
+ await this.network.sendMessage(peerId, message)
296
260
 
297
- // update list of messages sent to remote
298
- for (const key of sent) {
299
- sentWants.add(key)
261
+ // update list of messages sent to remote
262
+ for (const key of sent) {
263
+ sentWants.add(key)
264
+ }
265
+ } catch (err: any) {
266
+ this.log.error('error sending full wantlist to new peer', err)
300
267
  }
301
- } catch (err: any) {
302
- this.log.error('error sending full wantlist to new peer', err)
303
- }
304
- }
268
+ })
269
+ ).catch(err => {
270
+ this.log.error('error sending messages', err)
271
+ })
305
272
 
306
273
  // queued all message sends, remove cancelled wants from wantlist and sent
307
274
  // wants
@@ -314,6 +281,8 @@ export class WantList implements Startable {
314
281
  }
315
282
  }
316
283
  }
284
+
285
+ this.sendingMessages.resolve()
317
286
  }
318
287
 
319
288
  has (cid: CID): boolean {
@@ -324,38 +293,28 @@ export class WantList implements Startable {
324
293
  /**
325
294
  * Add a CID to the wantlist
326
295
  */
327
- async wantPresence (cid: CID, options: WantOptions = {}): Promise<WantPresenceResult> {
328
- if (options.peerId != null && this.peers.get(options.peerId) == null) {
329
- const cidStr = uint8ArrayToString(cid.multihash.bytes, 'base64')
330
-
331
- try {
332
- // if we don't have them as a peer, add them
333
- this.peers.set(options.peerId, new Set([cidStr]))
334
-
335
- // sending WantHave directly to peer
336
- await this.network.sendMessage(options.peerId, {
337
- wantlist: {
338
- full: false,
339
- entries: [{
340
- cid: cid.bytes,
341
- sendDontHave: true,
342
- wantType: WantType.WantHave,
343
- priority: 1
344
- }]
345
- }
346
- })
347
- } catch (err) {
348
- // sending failed, remove them as a peer
349
- this.peers.delete(options.peerId)
350
-
351
- throw err
296
+ async wantSessionPresence (cid: CID, peerId: PeerId, options: WantOptions = {}): Promise<WantPresenceResult> {
297
+ // sending WantHave directly to peer
298
+ await this.network.sendMessage(peerId, {
299
+ wantlist: {
300
+ full: false,
301
+ entries: [{
302
+ cid: cid.bytes,
303
+ sendDontHave: true,
304
+ wantType: WantType.WantHave,
305
+ priority: 1
306
+ }]
352
307
  }
353
- }
308
+ })
354
309
 
355
- return this.addEntry(cid, {
356
- ...options,
357
- wantType: WantType.WantHave
310
+ // wait for peer response
311
+ const event = await raceEvent<CustomEvent<WantHaveResult | WantDontHaveResult>>(this, 'presence', options.signal, {
312
+ filter: (event) => {
313
+ return peerId.equals(event.detail.sender) && uint8ArrayEquals(cid.multihash.digest, event.detail.cid.multihash.digest)
314
+ }
358
315
  })
316
+
317
+ return event.detail
359
318
  }
360
319
 
361
320
  /**
@@ -368,15 +327,56 @@ export class WantList implements Startable {
368
327
  })
369
328
  }
370
329
 
330
+ /**
331
+ * Add a CID to the wantlist
332
+ */
333
+ async wantSessionBlock (cid: CID, peerId: PeerId, options: WantOptions = {}): Promise<WantPresenceResult> {
334
+ // sending WantBlockResult directly to peer
335
+ await this.network.sendMessage(peerId, {
336
+ wantlist: {
337
+ full: false,
338
+ entries: [{
339
+ cid: cid.bytes,
340
+ sendDontHave: true,
341
+ wantType: WantType.WantBlock,
342
+ priority: 1
343
+ }]
344
+ }
345
+ })
346
+
347
+ // wait for peer response
348
+ const event = await raceEvent<CustomEvent<WantPresenceResult>>(this, 'presence', options.signal, {
349
+ filter: (event) => {
350
+ return peerId.equals(event.detail.sender) && uint8ArrayEquals(cid.multihash.digest, event.detail.cid.multihash.digest)
351
+ }
352
+ })
353
+
354
+ return event.detail
355
+ }
356
+
357
+ /**
358
+ * Invoked when a block has been received from an external source
359
+ */
360
+ async receivedBlock (cid: CID, options: ProgressOptions<BitswapNotifyProgressEvents> & AbortOptions): Promise<void> {
361
+ const cidStr = uint8ArrayToString(cid.multihash.bytes, 'base64')
362
+
363
+ const entry = this.wants.get(cidStr)
364
+
365
+ if (entry == null) {
366
+ return
367
+ }
368
+
369
+ entry.cancel = true
370
+
371
+ await this.sendMessagesDebounced()
372
+ }
373
+
371
374
  /**
372
375
  * Invoked when a message is received from a bitswap peer
373
376
  */
374
377
  private async receiveMessage (sender: PeerId, message: BitswapMessage): Promise<void> {
375
- this.log('received message from %p', sender)
376
-
377
- // blocks received
378
- const blockResults: WantBlockResult[] = []
379
- const presenceResults: WantPresenceResult[] = []
378
+ this.log('received message %d from %p with %d blocks', sender, message.blocks.length)
379
+ let blocksCancelled = false
380
380
 
381
381
  // process blocks
382
382
  for (const block of message.blocks) {
@@ -384,7 +384,6 @@ export class WantList implements Startable {
384
384
  continue
385
385
  }
386
386
 
387
- this.log('received block')
388
387
  const values = vd(block.prefix)
389
388
  const cidVersion = values[0]
390
389
  const multicodec = values[1]
@@ -398,71 +397,65 @@ export class WantList implements Startable {
398
397
  continue
399
398
  }
400
399
 
401
- const hash = await hasher.digest(block.data)
400
+ let hash: any = hasher.digest(block.data)
401
+
402
+ if (hash.then != null) {
403
+ hash = await hash
404
+ }
405
+
402
406
  const cid = CID.create(cidVersion === 0 ? 0 : 1, multicodec, hash)
403
407
 
404
408
  this.log('received block from %p for %c', sender, cid)
405
409
 
406
- blockResults.push({
407
- sender,
408
- cid,
409
- block: block.data
410
- })
411
-
412
- presenceResults.push({
413
- sender,
414
- cid,
415
- has: true
410
+ this.safeDispatchEvent<WantBlockResult>('block', {
411
+ detail: {
412
+ sender,
413
+ cid,
414
+ block: block.data
415
+ }
416
416
  })
417
- }
418
-
419
- // process block presences
420
- for (const { cid: cidBytes, type } of message.blockPresences) {
421
- const cid = CID.decode(cidBytes)
422
-
423
- this.log('received %s from %p for %c', type, sender, cid)
424
417
 
425
- presenceResults.push({
426
- sender,
427
- cid,
428
- has: type === BlockPresenceType.HaveBlock
418
+ this.safeDispatchEvent<WantHaveResult | WantDontHaveResult>('presence', {
419
+ detail: {
420
+ sender,
421
+ cid,
422
+ has: true,
423
+ block: block.data
424
+ }
429
425
  })
430
- }
431
426
 
432
- for (const result of blockResults) {
433
- const cidStr = uint8ArrayToString(result.cid.multihash.bytes, 'base64')
427
+ const cidStr = uint8ArrayToString(cid.multihash.bytes, 'base64')
434
428
  const entry = this.wants.get(cidStr)
435
429
 
436
430
  if (entry == null) {
437
- return
431
+ continue
438
432
  }
439
433
 
440
- const recipients = entry.blockWantListeners
441
- entry.blockWantListeners = []
442
- recipients.forEach((p) => {
443
- p.resolve(result)
444
- })
445
-
446
434
  // since we received the block, flip the cancel flag to send cancels to
447
435
  // any peers on the next message sending iteration, this will remove it
448
436
  // from the internal want list
449
437
  entry.cancel = true
438
+ blocksCancelled = true
450
439
  }
451
440
 
452
- for (const result of presenceResults) {
453
- const cidStr = uint8ArrayToString(result.cid.multihash.bytes, 'base64')
454
- const entry = this.wants.get(cidStr)
441
+ // process block presences
442
+ for (const { cid: cidBytes, type } of message.blockPresences) {
443
+ const cid = CID.decode(cidBytes)
455
444
 
456
- if (entry == null) {
457
- return
458
- }
445
+ this.log('received %s from %p for %c', type, sender, cid)
459
446
 
460
- const recipients = entry.blockPresenceListeners
461
- entry.blockPresenceListeners = []
462
- recipients.forEach((p) => {
463
- p.resolve(result)
447
+ this.safeDispatchEvent<WantHaveResult | WantDontHaveResult>('presence', {
448
+ detail: {
449
+ sender,
450
+ cid,
451
+ has: type === BlockPresenceType.HaveBlock
452
+ }
464
453
  })
465
454
  }
455
+
456
+ if (blocksCancelled) {
457
+ await this.sendMessagesDebounced()
458
+ }
466
459
  }
467
460
 
468
461
  /**
@@ -477,7 +470,6 @@ export class WantList implements Startable {
477
470
  full: true,
478
471
  entries: pipe(
479
472
  this.wants.entries(),
480
- (source) => filter(source, ([key, entry]) => !entry.cancel && (entry.session.size > 0 && !entry.session.has(peerId))),
481
473
  (source) => filter(source, ([key, entry]) => !entry.cancel),
482
474
  (source) => map(source, ([key, entry]) => {
483
475
  sentWants.add(key)
@@ -525,5 +517,6 @@ export class WantList implements Startable {
525
517
 
526
518
  stop (): void {
527
519
  this.peers.clear()
520
+ clearTimeout(this.sendMessagesTimeout)
528
521
  }
529
522
  }
@@ -1,24 +0,0 @@
1
- {
2
- "Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
3
- ".:Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
4
- "BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
5
- ".:BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
6
- "BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
7
- ".:BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
8
- "BitswapSession": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapSession.html",
9
- ".:BitswapSession": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapSession.html",
10
- "CreateBitswapSessionOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.CreateBitswapSessionOptions.html",
11
- ".:CreateBitswapSessionOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.CreateBitswapSessionOptions.html",
12
- "MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
13
- ".:MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
14
- "WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
15
- ".:WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
16
- "BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
17
- ".:BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
18
- "BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
19
- ".:BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
20
- "BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
21
- ".:BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
22
- "createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html",
23
- ".:createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html"
24
- }