Skip to content

Commit 3a5234e

Browse files
authored
fix: pass options to blockstore.get during pin.add (#148)
To allow cancelling pin operations and getting progress events, pass the options to blockstore.get
1 parent 3323a5c commit 3a5234e

File tree

4 files changed

+34
-6
lines changed

4 files changed

+34
-6
lines changed

packages/helia/src/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type { PubSub } from '@libp2p/interface-pubsub'
3333
import type { DualKadDHT } from '@libp2p/kad-dht'
3434
import type { Blockstore } from 'interface-blockstore'
3535
import type { Datastore } from 'interface-datastore'
36+
import type { AbortOptions } from 'interface-store'
3637
import type { Libp2pOptions } from 'libp2p'
3738
import type { CID } from 'multiformats/cid'
3839
import type { MultihashHasher } from 'multiformats/hashes/interface'
@@ -47,6 +48,11 @@ export interface DAGWalker {
4748
walk: (block: Uint8Array) => AsyncGenerator<CID, void, undefined>
4849
}
4950

51+
export interface Thing {
52+
fetch: (cid: CID, options?: AbortOptions) => Promise<Uint8Array>
53+
notify?: (cid: CID, block: Uint8Array, options?: AbortOptions) => void
54+
}
55+
5056
/**
5157
* Options used to create a Helia node.
5258
*/

packages/helia/src/pins.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { base36 } from 'multiformats/bases/base36'
44
import { CID, type Version } from 'multiformats/cid'
55
import defer from 'p-defer'
66
import PQueue from 'p-queue'
7+
import { CustomProgressEvent, type ProgressOptions } from 'progress-events'
78
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
89
import { cborWalker, dagPbWalker, jsonWalker, rawWalker } from './utils/dag-walkers.js'
910
import type { DAGWalker } from './index.js'
10-
import type { AddOptions, IsPinnedOptions, LsOptions, Pin, Pins, RmOptions } from '@helia/interface/pins'
11+
import type { AddOptions, AddPinEvents, IsPinnedOptions, LsOptions, Pin, Pins, RmOptions } from '@helia/interface/pins'
12+
import type { GetBlockProgressEvents } from '@helia/interface/src/blocks.js'
1113
import type { AbortOptions } from '@libp2p/interfaces'
1214
import type { Blockstore } from 'interface-blockstore'
1315

@@ -41,7 +43,7 @@ const DATASTORE_ENCODING = base36
4143
// const DAG_WALK_MAX_QUEUE_LENGTH = 10
4244
const DAG_WALK_QUEUE_CONCURRENCY = 1
4345

44-
interface WalkDagOptions extends AbortOptions {
46+
interface WalkDagOptions extends AbortOptions, ProgressOptions<GetBlockProgressEvents | AddPinEvents> {
4547
depth: number
4648
}
4749

@@ -142,7 +144,7 @@ export class PinsImpl implements Pins {
142144
throw new Error(`No dag walker found for cid codec ${cid.code}`)
143145
}
144146

145-
const block = await this.blockstore.get(cid)
147+
const block = await this.blockstore.get(cid, options)
146148

147149
await this.#updatePinnedBlock(cid, withPinnedBlock, options)
148150

@@ -160,7 +162,7 @@ export class PinsImpl implements Pins {
160162
/**
161163
* Update the pin count for the CID
162164
*/
163-
async #updatePinnedBlock (cid: CID, withPinnedBlock: (pinnedBlock: DatastorePinnedBlock) => void, options: AbortOptions): Promise<void> {
165+
async #updatePinnedBlock (cid: CID, withPinnedBlock: (pinnedBlock: DatastorePinnedBlock) => void, options: AddOptions): Promise<void> {
164166
const blockKey = new Key(`${DATASTORE_BLOCK_PREFIX}${DATASTORE_ENCODING.encode(cid.multihash.bytes)}`)
165167

166168
let pinnedBlock: DatastorePinnedBlock = {
@@ -186,6 +188,7 @@ export class PinsImpl implements Pins {
186188
}
187189

188190
await this.datastore.put(blockKey, cborg.encode(pinnedBlock), options)
191+
options.onProgress?.(new CustomProgressEvent<CID>('helia:pin:add', { detail: cid }))
189192
}
190193

191194
async rm (cid: CID<unknown, number, number, Version>, options: RmOptions = {}): Promise<Pin> {

packages/helia/test/pins.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as raw from 'multiformats/codecs/raw'
77
import { createAndPutBlock } from './fixtures/create-block.js'
88
import { createHelia } from './fixtures/create-helia.js'
99
import type { Helia } from '@helia/interface'
10+
import type { ProgressEvent } from 'progress-events'
1011

1112
describe('pins', () => {
1213
let helia: Helia
@@ -37,6 +38,23 @@ describe('pins', () => {
3738
await expect(helia.pins.isPinned(cidV0)).to.eventually.be.true('did not pin v0 CID')
3839
})
3940

41+
it('pins a block with progress events', async () => {
42+
const cidV1 = await createAndPutBlock(raw.code, Uint8Array.from([0, 1, 2, 3]), helia.blockstore)
43+
44+
const events: ProgressEvent[] = []
45+
46+
await helia.pins.add(cidV1, {
47+
onProgress: (evt) => {
48+
events.push(evt)
49+
}
50+
})
51+
52+
expect(events.map(e => e.type)).to.include.members([
53+
'blocks:get:blockstore:get',
54+
'helia:pin:add'
55+
])
56+
})
57+
4058
it('unpins a block', async () => {
4159
const cidV1 = await createAndPutBlock(raw.code, Uint8Array.from([0, 1, 2, 3]), helia.blockstore)
4260
const cidV0 = CID.createV0(cidV1.multihash)

packages/interface/src/pins.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { GetBlockProgressEvents } from './blocks'
12
import type { AbortOptions } from '@libp2p/interfaces'
23
import type { CID } from 'multiformats/cid'
34
import type { ProgressEvent, ProgressOptions } from 'progress-events'
@@ -11,9 +12,9 @@ export interface Pin {
1112
}
1213

1314
export type AddPinEvents =
14-
ProgressEvent<'helia:pin:add', unknown>
15+
ProgressEvent<'helia:pin:add', CID>
1516

16-
export interface AddOptions extends AbortOptions, ProgressOptions<AddPinEvents> {
17+
export interface AddOptions extends AbortOptions, ProgressOptions<AddPinEvents | GetBlockProgressEvents> {
1718
/**
1819
* How deeply to pin the DAG, defaults to Infinity
1920
*/

0 commit comments

Comments
 (0)