@helia/utils 2.4.2-2c225e85 → 2.4.2-397f2d86

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/src/routing.ts CHANGED
@@ -2,10 +2,11 @@ import { NoRoutersAvailableError } from '@helia/interface'
2
2
  import { NotFoundError, start, stop } from '@libp2p/interface'
3
3
  import { PeerQueue } from '@libp2p/utils'
4
4
  import merge from 'it-merge'
5
+ import { CustomProgressEvent } from 'progress-events'
5
6
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
6
7
  import { GetFailedError } from './errors.ts'
7
- import type { Routing as RoutingInterface, Provider, RoutingOptions } from '@helia/interface'
8
- import type { AbortOptions, ComponentLogger, Logger, Metrics, PeerId, PeerInfo, Startable } from '@libp2p/interface'
8
+ import type { Routing as RoutingInterface, Provider, RoutingOptions, RoutingFindProvidersProgressEvents, RoutingProvideProgressEvents, RoutingPutProgressEvents, RoutingGetProgressEvents, RoutingFindPeerProgressEvents, RoutingGetClosestPeersProgressEvents, RoutingCancelReprovideProgressEvents } from '@helia/interface'
9
+ import type { ComponentLogger, Logger, Metrics, PeerId, PeerInfo, Startable } from '@libp2p/interface'
9
10
  import type { CID } from 'multiformats/cid'
10
11
 
11
12
  const DEFAULT_PROVIDER_LOOKUP_CONCURRENCY = 5
@@ -21,11 +22,14 @@ export interface RoutingComponents {
21
22
  }
22
23
 
23
24
  export class Routing implements RoutingInterface, Startable {
25
+ public name: string
26
+
24
27
  private readonly log: Logger
25
28
  private readonly routers: Array<Partial<RoutingInterface>>
26
29
  private readonly providerLookupConcurrency: number
27
30
 
28
31
  constructor (components: RoutingComponents, init: RoutingInit) {
32
+ this.name = 'helia'
29
33
  this.log = components.logger.forComponent('helia:routing')
30
34
  this.routers = init.routers ?? []
31
35
  this.providerLookupConcurrency = init.providerLookupConcurrency ?? DEFAULT_PROVIDER_LOOKUP_CONCURRENCY
@@ -65,7 +69,7 @@ export class Routing implements RoutingInterface, Startable {
65
69
  * Iterates over all content routers in parallel to find providers of the
66
70
  * given key
67
71
  */
68
- async * findProviders (key: CID, options: RoutingOptions = {}): AsyncIterable<Provider> {
72
+ async * findProviders (key: CID, options: RoutingOptions<RoutingFindProvidersProgressEvents> = {}): AsyncIterable<Provider> {
69
73
  if (this.routers.length === 0) {
70
74
  throw new NoRoutersAvailableError('No content routers available')
71
75
  }
@@ -89,9 +93,22 @@ export class Routing implements RoutingInterface, Startable {
89
93
  .map(async function * (router) {
90
94
  let foundProviders = 0
91
95
 
96
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:find-providers:start', {
97
+ routing: router.name,
98
+ cid: key
99
+ }))
100
+
92
101
  try {
93
102
  for await (const prov of router.findProviders(key, options)) {
94
103
  foundProviders++
104
+
105
+ // @ts-expect-error router.name is a string, needs to be specific
106
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:find-providers:provider', {
107
+ routing: router.name,
108
+ cid: key,
109
+ provider: prov
110
+ }))
111
+
95
112
  yield prov
96
113
  }
97
114
  } catch (err: any) {
@@ -99,6 +116,12 @@ export class Routing implements RoutingInterface, Startable {
99
116
  } finally {
100
117
  self.log('router %s found %d providers for %c', router, foundProviders, key)
101
118
 
119
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:find-providers:end', {
120
+ routing: router.name,
121
+ cid: key,
122
+ found: foundProviders
123
+ }))
124
+
102
125
  routersFinished++
103
126
 
104
127
  // if all routers have finished and there are no jobs to find updated
@@ -165,7 +188,7 @@ export class Routing implements RoutingInterface, Startable {
165
188
  * Iterates over all content routers in parallel to notify it is
166
189
  * a provider of the given key
167
190
  */
168
- async provide (key: CID, options: AbortOptions = {}): Promise<void> {
191
+ async provide (key: CID, options: RoutingOptions<RoutingProvideProgressEvents> = {}): Promise<void> {
169
192
  if (this.routers.length === 0) {
170
193
  throw new NoRoutersAvailableError('No content routers available')
171
194
  }
@@ -173,16 +196,36 @@ export class Routing implements RoutingInterface, Startable {
173
196
  await Promise.all(
174
197
  supports(this.routers, 'provide')
175
198
  .map(async (router) => {
199
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:provide:start', {
200
+ routing: router.name,
201
+ cid: key
202
+ }))
203
+
176
204
  await router.provide(key, options)
205
+
206
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:provide:end', {
207
+ routing: router.name,
208
+ cid: key
209
+ }))
177
210
  })
178
211
  )
179
212
  }
180
213
 
181
- async cancelReprovide (key: CID, options: AbortOptions = {}): Promise<void> {
214
+ async cancelReprovide (key: CID, options: RoutingOptions<RoutingCancelReprovideProgressEvents> = {}): Promise<void> {
182
215
  await Promise.all(
183
216
  supports(this.routers, 'cancelReprovide')
184
217
  .map(async (router) => {
218
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:cancel-reprovide:start', {
219
+ routing: router.name,
220
+ cid: key
221
+ }))
222
+
185
223
  await router.cancelReprovide(key, options)
224
+
225
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:cancel-reprovide:end', {
226
+ routing: router.name,
227
+ cid: key
228
+ }))
186
229
  })
187
230
  )
188
231
  }
@@ -190,11 +233,23 @@ export class Routing implements RoutingInterface, Startable {
190
233
  /**
191
234
  * Store the given key/value pair in the available content routings
192
235
  */
193
- async put (key: Uint8Array, value: Uint8Array, options?: AbortOptions): Promise<void> {
236
+ async put (key: Uint8Array, value: Uint8Array, options?: RoutingOptions<RoutingPutProgressEvents>): Promise<void> {
194
237
  await Promise.all(
195
238
  supports(this.routers, 'put')
196
239
  .map(async (router) => {
240
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:put:start', {
241
+ routing: router.name,
242
+ key,
243
+ value
244
+ }))
245
+
197
246
  await router.put(key, value, options)
247
+
248
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:put:end', {
249
+ routing: router.name,
250
+ key,
251
+ value
252
+ }))
198
253
  })
199
254
  )
200
255
  }
@@ -203,7 +258,7 @@ export class Routing implements RoutingInterface, Startable {
203
258
  * Get the value to the given key. The first value offered by any configured
204
259
  * router will be returned.
205
260
  */
206
- async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
261
+ async get (key: Uint8Array, options?: RoutingOptions<RoutingGetProgressEvents>): Promise<Uint8Array> {
207
262
  const errors: Error[] = []
208
263
  let result: Uint8Array | undefined
209
264
 
@@ -211,11 +266,21 @@ export class Routing implements RoutingInterface, Startable {
211
266
  result = await Promise.any(
212
267
  supports(this.routers, 'get')
213
268
  .map(async (router) => {
269
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:get:start', {
270
+ routing: router.name,
271
+ key
272
+ }))
273
+
214
274
  try {
215
275
  return await router.get(key, options)
216
276
  } catch (err: any) {
217
277
  this.log('router %s failed with %e', router, err)
218
278
  errors.push(err)
279
+ } finally {
280
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:get:end', {
281
+ routing: router.name,
282
+ key
283
+ }))
219
284
  }
220
285
  })
221
286
  )
@@ -233,7 +298,7 @@ export class Routing implements RoutingInterface, Startable {
233
298
  /**
234
299
  * Iterates over all peer routers in parallel to find the given peer
235
300
  */
236
- async findPeer (id: PeerId, options?: RoutingOptions): Promise<PeerInfo> {
301
+ async findPeer (id: PeerId, options?: RoutingOptions<RoutingFindPeerProgressEvents>): Promise<PeerInfo> {
237
302
  if (this.routers.length === 0) {
238
303
  throw new NoRoutersAvailableError('No peer routers available')
239
304
  }
@@ -242,10 +307,20 @@ export class Routing implements RoutingInterface, Startable {
242
307
  const source = merge(
243
308
  ...supports(this.routers, 'findPeer')
244
309
  .map(router => (async function * () {
310
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:find-peer:start', {
311
+ routing: router.name,
312
+ peerId: id
313
+ }))
314
+
245
315
  try {
246
316
  yield await router.findPeer(id, options)
247
317
  } catch (err) {
248
318
  self.log.error(err)
319
+ } finally {
320
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:find-peer:end', {
321
+ routing: router.name,
322
+ peerId: id
323
+ }))
249
324
  }
250
325
  })())
251
326
  )
@@ -264,14 +339,28 @@ export class Routing implements RoutingInterface, Startable {
264
339
  /**
265
340
  * Attempt to find the closest peers on the network to the given key
266
341
  */
267
- async * getClosestPeers (key: Uint8Array, options: RoutingOptions = {}): AsyncIterable<PeerInfo> {
342
+ async * getClosestPeers (key: Uint8Array, options: RoutingOptions<RoutingGetClosestPeersProgressEvents> = {}): AsyncIterable<PeerInfo> {
268
343
  if (this.routers.length === 0) {
269
344
  throw new NoRoutersAvailableError('No peer routers available')
270
345
  }
271
346
 
272
347
  for await (const peer of merge(
273
348
  ...supports(this.routers, 'getClosestPeers')
274
- .map(router => router.getClosestPeers(key, options))
349
+ .map(async function * (router) {
350
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:get-closest-peers:start', {
351
+ routing: router.name,
352
+ key
353
+ }))
354
+
355
+ try {
356
+ yield * router.getClosestPeers(key, options)
357
+ } finally {
358
+ options?.onProgress?.(new CustomProgressEvent('helia:routing:get-closest-peers:end', {
359
+ routing: router.name,
360
+ key
361
+ }))
362
+ }
363
+ })
275
364
  )) {
276
365
  if (peer == null) {
277
366
  continue
@@ -282,6 +371,6 @@ export class Routing implements RoutingInterface, Startable {
282
371
  }
283
372
  }
284
373
 
285
- function supports <Operation extends keyof Routing> (routers: any[], key: Operation): Array<Pick<Routing, Operation>> {
374
+ function supports <Operation extends keyof Routing> (routers: any[], key: Operation): Array<Pick<Routing, Operation | 'name'>> {
286
375
  return routers.filter(router => router[key] != null)
287
376
  }
package/src/storage.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { start, stop } from '@libp2p/interface'
2
2
  import createMortice from 'mortice'
3
- import { BlockPinnedError } from './errors.js'
3
+ import { BlockPinnedError } from './errors.ts'
4
4
  import type { Blocks, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions, SessionBlockstore } from '@helia/interface/blocks'
5
5
  import type { Pins } from '@helia/interface/pins'
6
6
  import type { AbortOptions, Startable } from '@libp2p/interface'
@@ -1,7 +1,7 @@
1
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 { InvalidDatastoreVersionError } from '../errors.js'
4
+ import { InvalidDatastoreVersionError } from '../errors.ts'
5
5
  import type { Datastore } from 'interface-datastore'
6
6
 
7
7
  const DS_VERSION_KEY = new Key('/version')
@@ -6,7 +6,7 @@ import * as dagJson from '@ipld/dag-json'
6
6
  import * as dagPb from '@ipld/dag-pb'
7
7
  import * as json from 'multiformats/codecs/json'
8
8
  import * as raw from 'multiformats/codecs/raw'
9
- import { isPromise } from './is-promise.js'
9
+ import { isPromise } from './is-promise.ts'
10
10
  import type { Await } from '@helia/interface'
11
11
  import type { BlockCodec } from 'multiformats/codecs/interface'
12
12
 
@@ -1,7 +1,7 @@
1
1
  import { UnknownHashAlgorithmError } from '@helia/interface'
2
2
  import { identity } from 'multiformats/hashes/identity'
3
3
  import { sha256, sha512 } from 'multiformats/hashes/sha2'
4
- import { isPromise } from './is-promise.js'
4
+ import { isPromise } from './is-promise.ts'
5
5
  import type { Await } from '@helia/interface'
6
6
  import type { MultihashHasher } from 'multiformats/hashes/interface'
7
7
 
@@ -6,7 +6,7 @@ import forEach from 'it-foreach'
6
6
  import { CustomProgressEvent } from 'progress-events'
7
7
  import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
8
8
  import { BlockNotFoundWhileOfflineError, InvalidConfigurationError, LoadBlockFailedError } from '../errors.ts'
9
- import { isPromise } from './is-promise.js'
9
+ import { isPromise } from './is-promise.ts'
10
10
  import type { HasherLoader } from '@helia/interface'
11
11
  import type { BlockBroker, Pair, DeleteManyBlocksProgressEvents, DeleteBlockProgressEvents, GetBlockProgressEvents, GetManyBlocksProgressEvents, PutManyBlocksProgressEvents, PutBlockProgressEvents, GetAllBlocksProgressEvents, GetOfflineOptions, BlockRetrievalOptions } from '@helia/interface/blocks'
12
12
  import type { AbortOptions, ComponentLogger, Logger, LoggerOptions } from '@libp2p/interface'