@helia/utils 1.2.2 → 1.3.0-d43efc7

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.
@@ -1,12 +1,13 @@
1
1
  import { DEFAULT_SESSION_MIN_PROVIDERS, DEFAULT_SESSION_MAX_PROVIDERS, InsufficientProvidersError } from '@helia/interface'
2
- import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
2
+ import { AbortError, TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
3
3
  import { createScalableCuckooFilter } from '@libp2p/utils/filters'
4
4
  import { Queue } from '@libp2p/utils/queue'
5
5
  import { base64 } from 'multiformats/bases/base64'
6
6
  import pDefer from 'p-defer'
7
7
  import type { BlockBroker, BlockRetrievalOptions, CreateSessionOptions } from '@helia/interface'
8
- import type { AbortOptions, ComponentLogger, Logger } from '@libp2p/interface'
8
+ import type { AbortOptions, ComponentLogger, Logger, PeerId } from '@libp2p/interface'
9
9
  import type { Filter } from '@libp2p/utils/filters'
10
+ import type { Multiaddr } from '@multiformats/multiaddr'
10
11
  import type { CID } from 'multiformats/cid'
11
12
  import type { DeferredPromise } from 'p-defer'
12
13
  import type { ProgressEvent } from 'progress-events'
@@ -33,6 +34,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
33
34
  private readonly maxProviders: number
34
35
  public readonly providers: Provider[]
35
36
  private readonly evictionFilter: Filter
37
+ private readonly initialProviders: Array<PeerId | Multiaddr | Multiaddr[]>
36
38
 
37
39
  constructor (components: AbstractSessionComponents, init: AbstractCreateSessionOptions) {
38
40
  super()
@@ -46,6 +48,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
46
48
  this.maxProviders = init.maxProviders ?? DEFAULT_SESSION_MAX_PROVIDERS
47
49
  this.providers = []
48
50
  this.evictionFilter = createScalableCuckooFilter(this.maxProviders)
51
+ this.initialProviders = init.providers ?? []
49
52
  }
50
53
 
51
54
  async retrieve (cid: CID, options: BlockRetrievalOptions<RetrieveBlockProgressEvents> = {}): Promise<Uint8Array> {
@@ -97,6 +100,7 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
97
100
  })
98
101
  queue.addEventListener('idle', () => {
99
102
  if (foundBlock || options.signal?.aborted === true) {
103
+ this.log.trace('session idle, found block')
100
104
  // we either found the block or the user gave up
101
105
  return
102
106
  }
@@ -168,10 +172,18 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
168
172
  this.log.error('error retrieving session block for %c', cid, err)
169
173
  })
170
174
 
175
+ const signalAbortedListener = (): void => {
176
+ deferred.reject(new AbortError(options.signal?.reason ?? 'Session aborted'))
177
+ queue.abort()
178
+ }
179
+
180
+ options.signal?.addEventListener('abort', signalAbortedListener)
181
+
171
182
  try {
172
183
  return await deferred.promise
173
184
  } finally {
174
185
  this.removeEventListener('provider', peerAddedToSessionListener)
186
+ options.signal?.removeEventListener('abort', signalAbortedListener)
175
187
  queue.clear()
176
188
  this.requests.delete(cidStr)
177
189
  }
@@ -216,34 +228,83 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
216
228
  .then(async () => {
217
229
  this.log('finding %d-%d new provider(s) for %c', count, this.maxProviders, cid)
218
230
 
219
- for await (const provider of this.findNewProviders(cid, options)) {
220
- if (found === this.maxProviders || options.signal?.aborted === true) {
221
- break
222
- }
231
+ // process any specific providers for this session
232
+ if (this.initialProviders.length > 0) {
233
+ while (found < count && this.initialProviders.length > 0) {
234
+ const prov = this.initialProviders.pop()
223
235
 
224
- if (this.hasProvider(provider)) {
225
- continue
226
- }
236
+ if (prov == null) {
237
+ break
238
+ }
239
+
240
+ const provider = await this.convertToProvider(prov, options)
241
+
242
+ if (options.signal?.aborted === true) {
243
+ break
244
+ }
227
245
 
228
- this.log('found %d/%d new providers', found, this.maxProviders)
229
- this.providers.push(provider)
246
+ if (provider == null) {
247
+ continue
248
+ }
249
+
250
+ if (this.hasProvider(provider)) {
251
+ continue
252
+ }
230
253
 
231
- // let the new peer join current queries
232
- this.safeDispatchEvent('provider', {
233
- detail: provider
234
- })
254
+ this.log('found %d/%d new providers', found, this.maxProviders)
255
+ this.providers.push(provider)
235
256
 
236
- found++
257
+ // let the new peer join current queries
258
+ this.safeDispatchEvent('provider', {
259
+ detail: provider
260
+ })
237
261
 
238
- if (found === count) {
239
- this.log('session is ready')
240
- deferred.resolve()
241
- // continue finding peers until we reach this.maxProviders
262
+ found++
263
+
264
+ if (found === count) {
265
+ this.log('session is ready')
266
+ deferred.resolve()
267
+ // continue finding peers until we reach this.maxProviders
268
+ }
269
+
270
+ if (this.providers.length === this.maxProviders) {
271
+ this.log('found max session peers', found)
272
+ break
273
+ }
242
274
  }
275
+ }
276
+
277
+ // still not got enough providers, search routing for more
278
+ if (found < this.maxProviders) {
279
+ for await (const provider of this.findNewProviders(cid, options)) {
280
+ if (found === this.maxProviders || options.signal?.aborted === true) {
281
+ break
282
+ }
283
+
284
+ if (this.hasProvider(provider)) {
285
+ continue
286
+ }
287
+
288
+ this.log('found %d/%d new providers', found, this.maxProviders)
289
+ this.providers.push(provider)
290
+
291
+ // let the new peer join current queries
292
+ this.safeDispatchEvent('provider', {
293
+ detail: provider
294
+ })
243
295
 
244
- if (this.providers.length === this.maxProviders) {
245
- this.log('found max session peers', found)
246
- break
296
+ found++
297
+
298
+ if (found === count) {
299
+ this.log('session is ready')
300
+ deferred.resolve()
301
+ // continue finding peers until we reach this.maxProviders
302
+ }
303
+
304
+ if (this.providers.length === this.maxProviders) {
305
+ this.log('found max session peers', found)
306
+ break
307
+ }
247
308
  }
248
309
  }
249
310
 
@@ -261,6 +322,13 @@ export abstract class AbstractSession<Provider, RetrieveBlockProgressEvents exte
261
322
  return deferred.promise
262
323
  }
263
324
 
325
+ /**
326
+ * If this session was created with specific providers, convert one of them
327
+ * into the format required or return `undefined` if the provider is not
328
+ * compatible with this session implementation
329
+ */
330
+ abstract convertToProvider (provider: PeerId | Multiaddr | Multiaddr[], options?: AbortOptions): Promise<Provider | undefined>
331
+
264
332
  /**
265
333
  * This method should search for new providers and yield them.
266
334
  */
package/src/pins.ts CHANGED
@@ -1,16 +1,19 @@
1
1
  import { Queue } from '@libp2p/utils/queue'
2
2
  import * as cborg from 'cborg'
3
- import { type Datastore, Key } from 'interface-datastore'
3
+ import { Key } from 'interface-datastore'
4
4
  import { base36 } from 'multiformats/bases/base36'
5
5
  import { createUnsafe } from 'multiformats/block'
6
- import { CID, type Version } from 'multiformats/cid'
7
- import { CustomProgressEvent, type ProgressOptions } from 'progress-events'
6
+ import { CID } from 'multiformats/cid'
7
+ import { CustomProgressEvent } from 'progress-events'
8
8
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
9
9
  import type { CodecLoader } from '@helia/interface'
10
10
  import type { GetBlockProgressEvents } from '@helia/interface/blocks'
11
11
  import type { AddOptions, AddPinEvents, IsPinnedOptions, LsOptions, Pin, Pins, RmOptions } from '@helia/interface/pins'
12
12
  import type { AbortOptions } from '@libp2p/interface'
13
13
  import type { Blockstore } from 'interface-blockstore'
14
+ import type { Datastore } from 'interface-datastore'
15
+ import type { Version } from 'multiformats/cid'
16
+ import type { ProgressOptions } from 'progress-events'
14
17
 
15
18
  interface DatastorePin {
16
19
  /**
@@ -1,6 +1,7 @@
1
- import { type Datastore, Key } from 'interface-datastore'
1
+ import { Key } from 'interface-datastore'
2
2
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
3
3
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
4
+ import type { Datastore } from 'interface-datastore'
4
5
 
5
6
  const DS_VERSION_KEY = new Key('/version')
6
7
  const CURRENT_VERSION = 1
@@ -3,7 +3,7 @@ import { anySignal } from 'any-signal'
3
3
  import { IdentityBlockstore } from 'blockstore-core/identity'
4
4
  import filter from 'it-filter'
5
5
  import forEach from 'it-foreach'
6
- import { CustomProgressEvent, type ProgressOptions } from 'progress-events'
6
+ import { CustomProgressEvent } from 'progress-events'
7
7
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
8
8
  import { isPromise } from './is-promise.js'
9
9
  import type { HasherLoader } from '@helia/interface'
@@ -13,6 +13,7 @@ import type { Blockstore } from 'interface-blockstore'
13
13
  import type { AwaitIterable } from 'interface-store'
14
14
  import type { CID } from 'multiformats/cid'
15
15
  import type { MultihashDigest, MultihashHasher } from 'multiformats/hashes/interface'
16
+ import type { ProgressOptions } from 'progress-events'
16
17
 
17
18
  export interface GetOptions extends AbortOptions {
18
19
  progress?(evt: Event): void
@@ -1,12 +0,0 @@
1
- {
2
- "AbstractSession": "https://ipfs.github.io/helia/classes/_helia_utils.AbstractSession.html",
3
- "BlockStorage": "https://ipfs.github.io/helia/classes/_helia_utils.BlockStorage.html",
4
- "Helia": "https://ipfs.github.io/helia/classes/_helia_utils.Helia.html",
5
- ".:Helia": "https://ipfs.github.io/helia/classes/_helia_utils.Helia.html",
6
- "AbstractCreateSessionOptions": "https://ipfs.github.io/helia/interfaces/_helia_utils.AbstractCreateSessionOptions.html",
7
- "AbstractSessionComponents": "https://ipfs.github.io/helia/interfaces/_helia_utils.AbstractSessionComponents.html",
8
- "BlockStorageInit": "https://ipfs.github.io/helia/interfaces/_helia_utils.BlockStorageInit.html",
9
- "BlockstoreSessionEvents": "https://ipfs.github.io/helia/interfaces/_helia_utils.BlockstoreSessionEvents.html",
10
- "HeliaInit": "https://ipfs.github.io/helia/interfaces/_helia_utils.HeliaInit.html",
11
- ".:HeliaInit": "https://ipfs.github.io/helia/interfaces/_helia_utils.HeliaInit.html"
12
- }