@helia/bitswap 3.1.2 → 3.1.3-83e1f40d
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.
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +3 -3
- package/dist/src/bitswap.d.ts +6 -6
- package/dist/src/bitswap.d.ts.map +1 -1
- package/dist/src/bitswap.js +5 -5
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +20 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/network.d.ts +5 -5
- package/dist/src/network.js +4 -4
- package/dist/src/peer-want-lists/index.d.ts +9 -5
- package/dist/src/peer-want-lists/index.d.ts.map +1 -1
- package/dist/src/peer-want-lists/index.js +16 -36
- package/dist/src/peer-want-lists/index.js.map +1 -1
- package/dist/src/peer-want-lists/ledger.d.ts +39 -4
- package/dist/src/peer-want-lists/ledger.d.ts.map +1 -1
- package/dist/src/peer-want-lists/ledger.js +146 -10
- package/dist/src/peer-want-lists/ledger.js.map +1 -1
- package/dist/src/session.d.ts +3 -3
- package/dist/src/utils/bitswap-message.d.ts +1 -1
- package/dist/src/utils/cid-prefix.js +1 -1
- package/dist/src/utils/merge-messages.d.ts +1 -1
- package/dist/src/utils/split-message.d.ts +1 -1
- package/dist/src/utils/split-message.js +2 -2
- package/dist/src/want-list.d.ts +3 -3
- package/dist/src/want-list.js +4 -4
- package/package.json +3 -3
- package/src/bitswap.ts +7 -7
- package/src/constants.ts +2 -0
- package/src/index.ts +25 -4
- package/src/network.ts +8 -8
- package/src/peer-want-lists/index.ts +23 -40
- package/src/peer-want-lists/ledger.ts +210 -14
- package/src/session.ts +3 -3
- package/src/utils/bitswap-message.ts +1 -1
- package/src/utils/cid-prefix.ts +1 -1
- package/src/utils/merge-messages.ts +1 -1
- package/src/utils/split-message.ts +3 -3
- package/src/want-list.ts +7 -7
- package/dist/typedoc-urls.json +0 -26
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import toBuffer from 'it-to-buffer'
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
2
|
+
import { CID } from 'multiformats/cid'
|
|
3
|
+
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
4
|
+
import { DEFAULT_MAX_SIZE_REPLACE_HAS_WITH_BLOCK, DEFAULT_DO_NOT_RESEND_BLOCK_WINDOW, DEFAULT_MAX_WANTLIST_SIZE } from '../constants.ts'
|
|
5
|
+
import { BlockPresenceType, WantType } from '../pb/message.ts'
|
|
6
|
+
import { QueuedBitswapMessage } from '../utils/bitswap-message.ts'
|
|
7
|
+
import { cidToPrefix } from '../utils/cid-prefix.ts'
|
|
8
|
+
import type { Network } from '../network.ts'
|
|
9
|
+
import type { Wantlist } from '../pb/message.ts'
|
|
7
10
|
import type { AbortOptions, ComponentLogger, Logger, PeerId } from '@libp2p/interface'
|
|
8
11
|
import type { Blockstore } from 'interface-blockstore'
|
|
9
|
-
import type { CID } from 'multiformats/cid'
|
|
10
12
|
|
|
11
13
|
export interface LedgerComponents {
|
|
12
14
|
peerId: PeerId
|
|
@@ -17,6 +19,8 @@ export interface LedgerComponents {
|
|
|
17
19
|
|
|
18
20
|
export interface LedgerInit {
|
|
19
21
|
maxSizeReplaceHasWithBlock?: number
|
|
22
|
+
doNotResendBlockWindow?: number
|
|
23
|
+
maxWantListSize?: number
|
|
20
24
|
}
|
|
21
25
|
|
|
22
26
|
export interface PeerWantListEntry {
|
|
@@ -45,19 +49,50 @@ export interface PeerWantListEntry {
|
|
|
45
49
|
* If we don't have the block and we've told them we don't have the block
|
|
46
50
|
*/
|
|
47
51
|
sentDoNotHave?: boolean
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* If the status is `sending` or `sent`, the block for this CID is or has been
|
|
55
|
+
* sent to the peer so we should not attempt to send it again
|
|
56
|
+
*/
|
|
57
|
+
status: 'want' | 'sending' | 'sent'
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A timestamp for when this want should be removed from the list, typically
|
|
61
|
+
* this is set with the `sent` status to prevent sending duplicate blocks to a
|
|
62
|
+
* peer. Once it has expired the peer can request the block a subsequent time.
|
|
63
|
+
*/
|
|
64
|
+
expires?: number
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* A timestamp of when this entry was created
|
|
68
|
+
*/
|
|
69
|
+
created: number
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* If this field is false, we have attempted to send this WantList entry but
|
|
73
|
+
* found there is no block for the CID in the blockstore and we are
|
|
74
|
+
* optimistically waiting to see if we come across it later.
|
|
75
|
+
*
|
|
76
|
+
* We only perform the check when we are about to send the block, by which
|
|
77
|
+
* point the entry status is 'sending' so this value with either be false or
|
|
78
|
+
* not set
|
|
79
|
+
*/
|
|
80
|
+
haveBlock?: false
|
|
48
81
|
}
|
|
49
82
|
|
|
50
83
|
export class Ledger {
|
|
51
84
|
public peerId: PeerId
|
|
52
85
|
private readonly blockstore: Blockstore
|
|
53
86
|
private readonly network: Network
|
|
54
|
-
|
|
87
|
+
private wants: Map<string, PeerWantListEntry>
|
|
55
88
|
public exchangeCount: number
|
|
56
89
|
public bytesSent: number
|
|
57
90
|
public bytesReceived: number
|
|
58
91
|
public lastExchange?: number
|
|
59
92
|
private readonly maxSizeReplaceHasWithBlock: number
|
|
60
93
|
private readonly log: Logger
|
|
94
|
+
private readonly doNotResendBlockWindow: number
|
|
95
|
+
private readonly maxWantListSize: number
|
|
61
96
|
|
|
62
97
|
constructor (components: LedgerComponents, init: LedgerInit) {
|
|
63
98
|
this.peerId = components.peerId
|
|
@@ -70,6 +105,8 @@ export class Ledger {
|
|
|
70
105
|
this.bytesSent = 0
|
|
71
106
|
this.bytesReceived = 0
|
|
72
107
|
this.maxSizeReplaceHasWithBlock = init.maxSizeReplaceHasWithBlock ?? DEFAULT_MAX_SIZE_REPLACE_HAS_WITH_BLOCK
|
|
108
|
+
this.doNotResendBlockWindow = init.doNotResendBlockWindow ?? DEFAULT_DO_NOT_RESEND_BLOCK_WINDOW
|
|
109
|
+
this.maxWantListSize = init.maxWantListSize ?? DEFAULT_MAX_WANTLIST_SIZE
|
|
73
110
|
}
|
|
74
111
|
|
|
75
112
|
sentBytes (n: number): void {
|
|
@@ -88,18 +125,174 @@ export class Ledger {
|
|
|
88
125
|
return (this.bytesSent / (this.bytesReceived + 1)) // +1 is to prevent division by zero
|
|
89
126
|
}
|
|
90
127
|
|
|
128
|
+
removeExpiredWants (): void {
|
|
129
|
+
// remove any expired wants
|
|
130
|
+
this.wants.forEach((value, key) => {
|
|
131
|
+
if (value.expires != null && value.expires < Date.now()) {
|
|
132
|
+
this.wants.delete(key)
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public addWants (wantlist?: Wantlist): void {
|
|
138
|
+
if (wantlist == null) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// if the message has a full wantlist, remove all entries not currently
|
|
143
|
+
// being sent to the peer
|
|
144
|
+
if (wantlist.full === true) {
|
|
145
|
+
this.wants.forEach((value, key) => {
|
|
146
|
+
if (value.status === 'want') {
|
|
147
|
+
this.wants.delete(key)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// clear cancelled wants and add new wants to the ledger
|
|
153
|
+
for (const entry of wantlist.entries) {
|
|
154
|
+
const cid = CID.decode(entry.cid)
|
|
155
|
+
const cidStr = uint8ArrayToString(cid.multihash.bytes, 'base64')
|
|
156
|
+
|
|
157
|
+
if (entry.cancel === true) {
|
|
158
|
+
this.log('peer %p cancelled want of block for %c', this.peerId, cid)
|
|
159
|
+
this.wants.delete(cidStr)
|
|
160
|
+
} else {
|
|
161
|
+
if (entry.wantType === WantType.WantHave) {
|
|
162
|
+
this.log('peer %p wanted block presence for %c', this.peerId, cid)
|
|
163
|
+
} else {
|
|
164
|
+
this.log('peer %p wanted block for %c', this.peerId, cid)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const existingWant = this.wants.get(cidStr)
|
|
168
|
+
|
|
169
|
+
// we are already tracking a want for this CID, just update the fields
|
|
170
|
+
if (existingWant != null) {
|
|
171
|
+
const sentOrSending = existingWant.status === 'sent' || existingWant.status === 'sending'
|
|
172
|
+
const wantTypeUpgrade = existingWant.wantType === WantType.WantHave && (entry.wantType == null || entry.wantType === WantType.WantBlock)
|
|
173
|
+
|
|
174
|
+
// allow upgrade from WantHave to WantBlock if we've previously
|
|
175
|
+
// sent or are sending a WantHave
|
|
176
|
+
if (sentOrSending && wantTypeUpgrade) {
|
|
177
|
+
existingWant.status = 'want'
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
existingWant.priority = entry.priority
|
|
181
|
+
existingWant.wantType = entry.wantType ?? WantType.WantBlock
|
|
182
|
+
existingWant.sendDontHave = entry.sendDontHave ?? false
|
|
183
|
+
continue
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// add a new want
|
|
187
|
+
this.wants.set(cidStr, {
|
|
188
|
+
cid,
|
|
189
|
+
priority: entry.priority,
|
|
190
|
+
wantType: entry.wantType ?? WantType.WantBlock,
|
|
191
|
+
sendDontHave: entry.sendDontHave ?? false,
|
|
192
|
+
status: 'want',
|
|
193
|
+
created: Date.now()
|
|
194
|
+
})
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// if we have exceeded maxWantListSize, truncate the list - first select
|
|
199
|
+
// wants that are not currently being sent to the user
|
|
200
|
+
const wants = [...this.wants.entries()]
|
|
201
|
+
.filter(([key, entry]) => entry.status === 'want')
|
|
202
|
+
|
|
203
|
+
if (wants.length > this.maxWantListSize) {
|
|
204
|
+
this.truncateWants(wants)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private truncateWants (wants: Array<[string, PeerWantListEntry]>): void {
|
|
209
|
+
// sort wants by priority, lack of block presence, then age so the wants
|
|
210
|
+
// to be evicted are a older, low priority wants that we don't have the
|
|
211
|
+
// block for
|
|
212
|
+
wants = wants
|
|
213
|
+
.sort((a, b) => {
|
|
214
|
+
if (a[1].created < b[1].created) {
|
|
215
|
+
return -1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (b[1].created < a[1].created) {
|
|
219
|
+
return 1
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return 0
|
|
223
|
+
})
|
|
224
|
+
.sort((a, b) => {
|
|
225
|
+
if (a[1].haveBlock === false) {
|
|
226
|
+
return -1
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (b[1].haveBlock === false) {
|
|
230
|
+
return 1
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return 0
|
|
234
|
+
})
|
|
235
|
+
.sort((a, b) => {
|
|
236
|
+
if (a[1].priority < b[1].priority) {
|
|
237
|
+
return -1
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (b[1].priority < a[1].priority) {
|
|
241
|
+
return 1
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return 0
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
const toRemove = wants.length - this.maxWantListSize
|
|
248
|
+
|
|
249
|
+
for (let i = 0; i < toRemove; i++) {
|
|
250
|
+
this.wants.delete(wants[i][0])
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public getWants (): PeerWantListEntry[] {
|
|
255
|
+
return [...this.wants.values()]
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public hasWant (cid: CID): boolean {
|
|
259
|
+
const cidStr = uint8ArrayToString(cid.multihash.bytes, 'base64')
|
|
260
|
+
|
|
261
|
+
return this.wants.has(cidStr)
|
|
262
|
+
}
|
|
263
|
+
|
|
91
264
|
public async sendBlocksToPeer (options?: AbortOptions): Promise<void> {
|
|
92
265
|
const message = new QueuedBitswapMessage()
|
|
93
266
|
const sentBlocks = new Set<string>()
|
|
94
267
|
|
|
95
|
-
|
|
268
|
+
// remove any expired wants
|
|
269
|
+
this.removeExpiredWants()
|
|
270
|
+
|
|
271
|
+
// pick unsent wants
|
|
272
|
+
const unsent = [...this.wants.entries()]
|
|
273
|
+
.filter(([key, value]) => value.status === 'want')
|
|
274
|
+
|
|
275
|
+
// update status, ensure we don't send the same blocks repeatedly
|
|
276
|
+
unsent.forEach(([key, value]) => {
|
|
277
|
+
value.status = 'sending'
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
for (const [key, entry] of unsent) {
|
|
96
281
|
try {
|
|
97
282
|
const block = await toBuffer(this.blockstore.get(entry.cid, options))
|
|
98
283
|
|
|
284
|
+
// ensure we still need to send the block/status, status may have
|
|
285
|
+
// changed due to incoming message while we were waiting for async block
|
|
286
|
+
// load
|
|
287
|
+
if (entry.status !== 'sending') {
|
|
288
|
+
continue
|
|
289
|
+
}
|
|
290
|
+
|
|
99
291
|
// do they want the block or just us to tell them we have the block
|
|
100
292
|
if (entry.wantType === WantType.WantHave) {
|
|
101
293
|
if (block.byteLength < this.maxSizeReplaceHasWithBlock) {
|
|
102
294
|
this.log('sending have and block for %c', entry.cid)
|
|
295
|
+
|
|
103
296
|
// if the block is small we just send it to them
|
|
104
297
|
sentBlocks.add(key)
|
|
105
298
|
message.addBlock(entry.cid, {
|
|
@@ -123,11 +316,20 @@ export class Ledger {
|
|
|
123
316
|
prefix: cidToPrefix(entry.cid)
|
|
124
317
|
})
|
|
125
318
|
}
|
|
319
|
+
|
|
320
|
+
entry.status = 'sent'
|
|
321
|
+
entry.expires = Date.now() + this.doNotResendBlockWindow
|
|
126
322
|
} catch (err: any) {
|
|
127
323
|
if (err.name !== 'NotFoundError') {
|
|
128
324
|
throw err
|
|
129
325
|
}
|
|
130
326
|
|
|
327
|
+
// reset status to try again later
|
|
328
|
+
entry.status = 'want'
|
|
329
|
+
|
|
330
|
+
// used to maybe delete this want later if the want list grows too large
|
|
331
|
+
entry.haveBlock = false
|
|
332
|
+
|
|
131
333
|
this.log('do not have block for %c', entry.cid)
|
|
132
334
|
|
|
133
335
|
// we don't have the requested block and the remote is not interested
|
|
@@ -157,12 +359,6 @@ export class Ledger {
|
|
|
157
359
|
|
|
158
360
|
// update accounting
|
|
159
361
|
this.sentBytes([...message.blocks.values()].reduce((acc, curr) => acc + curr.data.byteLength, 0))
|
|
160
|
-
|
|
161
|
-
// remove sent blocks from local copy of their want list - they can still
|
|
162
|
-
// re-request if required
|
|
163
|
-
for (const key of sentBlocks) {
|
|
164
|
-
this.wants.delete(key)
|
|
165
|
-
}
|
|
166
362
|
}
|
|
167
363
|
}
|
|
168
364
|
}
|
package/src/session.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { AbstractSession } from '@helia/utils'
|
|
2
2
|
import { isPeerId } from '@libp2p/interface'
|
|
3
3
|
import { CustomProgressEvent } from 'progress-events'
|
|
4
|
-
import type { BitswapProvider, BitswapWantProgressEvents } from './index.
|
|
5
|
-
import type { Network } from './network.
|
|
6
|
-
import type { WantList } from './want-list.
|
|
4
|
+
import type { BitswapProvider, BitswapWantProgressEvents } from './index.ts'
|
|
5
|
+
import type { Network } from './network.ts'
|
|
6
|
+
import type { WantList } from './want-list.ts'
|
|
7
7
|
import type { BlockRetrievalOptions, CreateSessionOptions } from '@helia/interface'
|
|
8
8
|
import type { ComponentLogger, Libp2p, PeerId } from '@libp2p/interface'
|
|
9
9
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
package/src/utils/cid-prefix.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { QueuedBitswapMessage } from './bitswap-message.
|
|
1
|
+
import type { QueuedBitswapMessage } from './bitswap-message.ts'
|
|
2
2
|
|
|
3
3
|
export function mergeMessages (existingMessage: QueuedBitswapMessage, newMessage: QueuedBitswapMessage): QueuedBitswapMessage {
|
|
4
4
|
for (const [key, entry] of newMessage.wantlist.entries()) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { encodingLength } from 'uint8-varint'
|
|
2
|
-
import { BlockTooLargeError } from '../errors.
|
|
3
|
-
import { BitswapMessage, Block, BlockPresence, WantlistEntry } from '../pb/message.
|
|
4
|
-
import type { QueuedBitswapMessage } from './bitswap-message.
|
|
2
|
+
import { BlockTooLargeError } from '../errors.ts'
|
|
3
|
+
import { BitswapMessage, Block, BlockPresence, WantlistEntry } from '../pb/message.ts'
|
|
4
|
+
import type { QueuedBitswapMessage } from './bitswap-message.ts'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* https://github.com/ipfs/kubo/issues/4473#issuecomment-350390693
|
package/src/want-list.ts
CHANGED
|
@@ -7,13 +7,13 @@ import pDefer from 'p-defer'
|
|
|
7
7
|
import { raceEvent } from 'race-event'
|
|
8
8
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
9
9
|
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
|
|
10
|
-
import { DEFAULT_MESSAGE_SEND_DELAY } from './constants.
|
|
11
|
-
import { BlockPresenceType, WantType } from './pb/message.
|
|
12
|
-
import { QueuedBitswapMessage } from './utils/bitswap-message.
|
|
13
|
-
import vd from './utils/varint-decoder.
|
|
14
|
-
import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.
|
|
15
|
-
import type { BitswapNetworkWantProgressEvents, Network } from './network.
|
|
16
|
-
import type { BitswapMessage } from './pb/message.
|
|
10
|
+
import { DEFAULT_MESSAGE_SEND_DELAY } from './constants.ts'
|
|
11
|
+
import { BlockPresenceType, WantType } from './pb/message.ts'
|
|
12
|
+
import { QueuedBitswapMessage } from './utils/bitswap-message.ts'
|
|
13
|
+
import vd from './utils/varint-decoder.ts'
|
|
14
|
+
import type { BitswapNotifyProgressEvents, MultihashHasherLoader } from './index.ts'
|
|
15
|
+
import type { BitswapNetworkWantProgressEvents, Network } from './network.ts'
|
|
16
|
+
import type { BitswapMessage } from './pb/message.ts'
|
|
17
17
|
import type { ComponentLogger, PeerId, Startable, AbortOptions, Libp2p, TypedEventTarget, Metrics } from '@libp2p/interface'
|
|
18
18
|
import type { Logger } from '@libp2p/logger'
|
|
19
19
|
import type { PeerMap } from '@libp2p/peer-collections'
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"codec": "https://ipfs.github.io/helia/functions/_helia_bitswap.WantType.codec.html",
|
|
3
|
-
"WantType": "https://ipfs.github.io/helia/enums/_helia_bitswap.WantType.html",
|
|
4
|
-
"Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
|
|
5
|
-
".:Bitswap": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.Bitswap.html",
|
|
6
|
-
"BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
|
|
7
|
-
".:BitswapComponents": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapComponents.html",
|
|
8
|
-
"BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
|
|
9
|
-
".:BitswapOptions": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapOptions.html",
|
|
10
|
-
"BitswapProvider": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.BitswapProvider.html",
|
|
11
|
-
"MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
|
|
12
|
-
".:MultihashHasherLoader": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.MultihashHasherLoader.html",
|
|
13
|
-
"WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
|
|
14
|
-
".:WantListEntry": "https://ipfs.github.io/helia/interfaces/_helia_bitswap.WantListEntry.html",
|
|
15
|
-
"BitswapNetworkNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNetworkNotifyProgressEvents.html",
|
|
16
|
-
"BitswapNetworkProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNetworkProgressEvents.html",
|
|
17
|
-
"BitswapNetworkWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNetworkWantProgressEvents.html",
|
|
18
|
-
"BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
|
|
19
|
-
".:BitswapNotifyProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapNotifyProgressEvents.html",
|
|
20
|
-
"BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
|
|
21
|
-
".:BitswapWantBlockProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantBlockProgressEvents.html",
|
|
22
|
-
"BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
|
|
23
|
-
".:BitswapWantProgressEvents": "https://ipfs.github.io/helia/types/_helia_bitswap.BitswapWantProgressEvents.html",
|
|
24
|
-
"createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html",
|
|
25
|
-
".:createBitswap": "https://ipfs.github.io/helia/functions/_helia_bitswap.createBitswap.html"
|
|
26
|
-
}
|