@helia/car 5.0.1 → 5.1.0-faac4ad3
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/README.md +54 -4
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/car.d.ts +1 -2
- package/dist/src/car.d.ts.map +1 -1
- package/dist/src/car.js +46 -124
- package/dist/src/car.js.map +1 -1
- package/dist/src/errors.d.ts +8 -0
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +8 -0
- package/dist/src/errors.js.map +1 -1
- package/dist/src/export-strategies/block-exporter.d.ts +5 -2
- package/dist/src/export-strategies/block-exporter.d.ts.map +1 -1
- package/dist/src/export-strategies/block-exporter.js +9 -3
- package/dist/src/export-strategies/block-exporter.js.map +1 -1
- package/dist/src/export-strategies/subgraph-exporter.d.ts +5 -2
- package/dist/src/export-strategies/subgraph-exporter.d.ts.map +1 -1
- package/dist/src/export-strategies/subgraph-exporter.js +8 -3
- package/dist/src/export-strategies/subgraph-exporter.js.map +1 -1
- package/dist/src/export-strategies/unixfs-exporter.d.ts +10 -4
- package/dist/src/export-strategies/unixfs-exporter.d.ts.map +1 -1
- package/dist/src/export-strategies/unixfs-exporter.js +15 -8
- package/dist/src/export-strategies/unixfs-exporter.js.map +1 -1
- package/dist/src/index.d.ts +64 -12
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +56 -6
- package/dist/src/index.js.map +1 -1
- package/dist/src/traversal-strategies/cid-path.d.ts +9 -6
- package/dist/src/traversal-strategies/cid-path.d.ts.map +1 -1
- package/dist/src/traversal-strategies/cid-path.js +35 -12
- package/dist/src/traversal-strategies/cid-path.js.map +1 -1
- package/dist/src/traversal-strategies/graph-search.d.ts +15 -7
- package/dist/src/traversal-strategies/graph-search.d.ts.map +1 -1
- package/dist/src/traversal-strategies/graph-search.js +57 -11
- package/dist/src/traversal-strategies/graph-search.js.map +1 -1
- package/dist/src/traversal-strategies/unixfs-path.d.ts +53 -3
- package/dist/src/traversal-strategies/unixfs-path.d.ts.map +1 -1
- package/dist/src/traversal-strategies/unixfs-path.js +70 -30
- package/dist/src/traversal-strategies/unixfs-path.js.map +1 -1
- package/package.json +7 -5
- package/src/car.ts +54 -163
- package/src/errors.ts +10 -0
- package/src/export-strategies/block-exporter.ts +13 -4
- package/src/export-strategies/subgraph-exporter.ts +13 -4
- package/src/export-strategies/unixfs-exporter.ts +20 -9
- package/src/index.ts +66 -15
- package/src/traversal-strategies/cid-path.ts +43 -13
- package/src/traversal-strategies/graph-search.ts +70 -12
- package/src/traversal-strategies/unixfs-path.ts +77 -41
- package/dist/typedoc-urls.json +0 -20
|
@@ -1,25 +1,83 @@
|
|
|
1
|
+
import { breadthFirstWalker, depthFirstWalker } from '@helia/utils'
|
|
2
|
+
import { InvalidParametersError } from '@libp2p/interface'
|
|
3
|
+
import toBuffer from 'it-to-buffer'
|
|
4
|
+
import { createUnsafe } from 'multiformats/block'
|
|
5
|
+
import { InvalidTraversalError } from '../errors.ts'
|
|
1
6
|
import type { TraversalStrategy } from '../index.js'
|
|
2
|
-
import type {
|
|
7
|
+
import type { CodecLoader } from '@helia/interface'
|
|
8
|
+
import type { GraphWalker } from '@helia/utils'
|
|
9
|
+
import type { AbortOptions } from '@libp2p/interface'
|
|
10
|
+
import type { Blockstore } from 'interface-blockstore'
|
|
11
|
+
import type { BlockView } from 'multiformats'
|
|
3
12
|
import type { CID } from 'multiformats/cid'
|
|
4
13
|
|
|
14
|
+
export interface GraphSearchOptions {
|
|
15
|
+
strategy?: 'depth-first' | 'breadth-first'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isCID (obj?: any): obj is CID {
|
|
19
|
+
return obj != null && obj?.asCID === obj
|
|
20
|
+
}
|
|
21
|
+
|
|
5
22
|
/**
|
|
6
|
-
* A traversal strategy that performs a
|
|
7
|
-
*
|
|
23
|
+
* A traversal strategy that performs a depth-first search looking for a target
|
|
24
|
+
* CID.
|
|
8
25
|
*/
|
|
9
26
|
export class GraphSearch implements TraversalStrategy {
|
|
10
|
-
private
|
|
27
|
+
private haystack?: CID
|
|
28
|
+
private readonly needle: CID
|
|
29
|
+
private readonly options?: GraphSearchOptions
|
|
11
30
|
|
|
12
|
-
constructor (
|
|
13
|
-
|
|
31
|
+
constructor (needle: CID, options?: GraphSearchOptions)
|
|
32
|
+
constructor (haystack: CID, needle: CID, options?: GraphSearchOptions)
|
|
33
|
+
constructor (...args: any[]) {
|
|
34
|
+
if (isCID(args[0])) {
|
|
35
|
+
if (isCID(args[1])) {
|
|
36
|
+
this.haystack = args[0]
|
|
37
|
+
this.needle = args[1]
|
|
38
|
+
this.options = args[2]
|
|
39
|
+
} else {
|
|
40
|
+
this.needle = args[0]
|
|
41
|
+
this.options = args[1]
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
throw new InvalidParametersError('needle must be specified')
|
|
45
|
+
}
|
|
14
46
|
}
|
|
15
47
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
48
|
+
async * traverse (root: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined> {
|
|
49
|
+
const start = this.haystack ?? root
|
|
50
|
+
let walker: GraphWalker
|
|
19
51
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
52
|
+
if (this.options?.strategy === 'breadth-first') {
|
|
53
|
+
walker = breadthFirstWalker({
|
|
54
|
+
blockstore,
|
|
55
|
+
getCodec
|
|
56
|
+
})
|
|
57
|
+
} else {
|
|
58
|
+
walker = depthFirstWalker({
|
|
59
|
+
blockstore,
|
|
60
|
+
getCodec
|
|
61
|
+
})
|
|
23
62
|
}
|
|
63
|
+
|
|
64
|
+
for await (const node of walker.walk(start, options)) {
|
|
65
|
+
if (node.block.cid.equals(this.needle)) {
|
|
66
|
+
for (const cid of node.path) {
|
|
67
|
+
const bytes = await toBuffer(blockstore.get(cid, options))
|
|
68
|
+
const block = createUnsafe({
|
|
69
|
+
cid,
|
|
70
|
+
bytes,
|
|
71
|
+
codec: await getCodec(cid.code)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
yield block
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
throw new InvalidTraversalError(`${this.needle} was not a child of ${start}`)
|
|
24
82
|
}
|
|
25
83
|
}
|
|
@@ -1,58 +1,94 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { NotUnixFSError } from '../errors.js'
|
|
1
|
+
import * as dagPb from '@ipld/dag-pb'
|
|
2
|
+
import { walkPath } from 'ipfs-unixfs-exporter'
|
|
3
|
+
import { createUnsafe } from 'multiformats/block'
|
|
5
4
|
import type { TraversalStrategy } from '../index.js'
|
|
6
|
-
import type {
|
|
5
|
+
import type { CodecLoader } from '@helia/interface'
|
|
6
|
+
import type { AbortOptions } from '@libp2p/interface'
|
|
7
|
+
import type { Blockstore } from 'interface-blockstore'
|
|
8
|
+
import type { BlockView } from 'multiformats'
|
|
7
9
|
import type { CID } from 'multiformats/cid'
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Traverses a DAG containing UnixFS directories
|
|
13
|
+
*
|
|
14
|
+
* A root CID may be specified to begin traversal from, otherwise the root
|
|
15
|
+
* currently being exported will be used.
|
|
16
|
+
*
|
|
17
|
+
* @example Begin traversal from the root being exported
|
|
18
|
+
*
|
|
19
|
+
* In this example, the UnixFS path `/foo/bar/baz.txt` path should be resolvable
|
|
20
|
+
* beneath the `root` CID.
|
|
21
|
+
*
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { createHelia } from 'helia'
|
|
24
|
+
* import { car, UnixFSPath } from '@helia/car'
|
|
25
|
+
* import { CID } from 'multiformats/cid'
|
|
26
|
+
*
|
|
27
|
+
* const helia = await createHelia()
|
|
28
|
+
* const c = car(helia)
|
|
29
|
+
* const root = CID.parse('QmRoot')
|
|
30
|
+
*
|
|
31
|
+
* for await (const buf of c.export(root, {
|
|
32
|
+
* traversal: new UnixFSPath('/foo/bar/baz.txt')
|
|
33
|
+
* })) {
|
|
34
|
+
* // do something with `buf`
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example Begin traversal from a parent node
|
|
39
|
+
*
|
|
40
|
+
* In this example, the `root` CID should be resolvable at the UnixFS path
|
|
41
|
+
* beneath `parentCID`.
|
|
42
|
+
*
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import { createHelia } from 'helia'
|
|
45
|
+
* import { car, UnixFSPath } from '@helia/car'
|
|
46
|
+
* import { CID } from 'multiformats/cid'
|
|
47
|
+
*
|
|
48
|
+
* const helia = await createHelia()
|
|
49
|
+
* const c = car(helia)
|
|
50
|
+
* const root = CID.parse('QmRoot')
|
|
51
|
+
* const parentCID = CID.parse('QmParent')
|
|
52
|
+
*
|
|
53
|
+
* for await (const buf of c.export(root, {
|
|
54
|
+
* traversal: new UnixFSPath(parentCID, '/foo/bar/baz.txt')
|
|
55
|
+
* })) {
|
|
56
|
+
* // do something with `buf`
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
11
59
|
*/
|
|
12
60
|
export class UnixFSPath implements TraversalStrategy {
|
|
13
|
-
private readonly
|
|
61
|
+
private readonly root?: CID
|
|
62
|
+
private readonly path: string
|
|
14
63
|
|
|
15
|
-
constructor (path: string)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
isTarget (): boolean {
|
|
21
|
-
return this.path.length === 0
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async * traverse <T extends BlockView<any, any, any, 0 | 1>>(cid: CID, block: T): AsyncGenerator<CID, void, undefined> {
|
|
25
|
-
if (cid.code !== DAG_PB_CODEC_CODE) {
|
|
26
|
-
throw new NotUnixFSError('Target CID is not UnixFS')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const segment = this.path.shift()
|
|
64
|
+
constructor (path: string)
|
|
65
|
+
constructor (root: CID, path: string)
|
|
66
|
+
constructor (...args: any[]) {
|
|
67
|
+
let root: CID | string | undefined = args[0]
|
|
68
|
+
let path: string = args[1]
|
|
30
69
|
|
|
31
|
-
if (
|
|
32
|
-
|
|
70
|
+
if (typeof root === 'string') {
|
|
71
|
+
path = root
|
|
72
|
+
root = undefined
|
|
73
|
+
} else if (args.length < 2) {
|
|
74
|
+
throw new Error('path or CID and path must be specified')
|
|
33
75
|
}
|
|
34
76
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (pb.Data == null) {
|
|
38
|
-
throw new NotUnixFSError('Target CID has no UnixFS data in decoded bytes')
|
|
77
|
+
if (!path.startsWith('/')) {
|
|
78
|
+
path = `/${path}`
|
|
39
79
|
}
|
|
40
80
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const link = pb.Links.filter(link => link.Name === segment).pop()
|
|
45
|
-
|
|
46
|
-
if (link == null) {
|
|
47
|
-
throw new NotUnixFSError(`Target CID directory has no link with name ${segment}`)
|
|
48
|
-
}
|
|
81
|
+
this.root = root
|
|
82
|
+
this.path = path
|
|
83
|
+
}
|
|
49
84
|
|
|
50
|
-
|
|
51
|
-
|
|
85
|
+
async * traverse (root: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined> {
|
|
86
|
+
for await (const entry of walkPath(`${this.root ?? root}${this.path}`, blockstore, options)) {
|
|
87
|
+
yield createUnsafe({
|
|
88
|
+
cid: entry.cid,
|
|
89
|
+
bytes: entry.node instanceof Uint8Array ? entry.node : dagPb.encode(entry.node),
|
|
90
|
+
codec: await getCodec(entry.cid.code)
|
|
91
|
+
})
|
|
52
92
|
}
|
|
53
|
-
|
|
54
|
-
// TODO: HAMT support
|
|
55
|
-
|
|
56
|
-
throw new NotUnixFSError('Target CID is not a UnixFS directory')
|
|
57
93
|
}
|
|
58
94
|
}
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"BlockExporter": "https://ipfs.github.io/helia/classes/_helia_car.BlockExporter.html",
|
|
3
|
-
"CIDPath": "https://ipfs.github.io/helia/classes/_helia_car.CIDPath.html",
|
|
4
|
-
"GraphSearch": "https://ipfs.github.io/helia/classes/_helia_car.GraphSearch.html",
|
|
5
|
-
"SubgraphExporter": "https://ipfs.github.io/helia/classes/_helia_car.SubgraphExporter.html",
|
|
6
|
-
"UnixFSExporter": "https://ipfs.github.io/helia/classes/_helia_car.UnixFSExporter.html",
|
|
7
|
-
"UnixFSPath": "https://ipfs.github.io/helia/classes/_helia_car.UnixFSPath.html",
|
|
8
|
-
"Car": "https://ipfs.github.io/helia/interfaces/_helia_car.Car.html",
|
|
9
|
-
".:Car": "https://ipfs.github.io/helia/interfaces/_helia_car.Car.html",
|
|
10
|
-
"CarComponents": "https://ipfs.github.io/helia/interfaces/_helia_car.CarComponents.html",
|
|
11
|
-
".:CarComponents": "https://ipfs.github.io/helia/interfaces/_helia_car.CarComponents.html",
|
|
12
|
-
"ExportCarOptions": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportCarOptions.html",
|
|
13
|
-
".:ExportCarOptions": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportCarOptions.html",
|
|
14
|
-
"ExportStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportStrategy.html",
|
|
15
|
-
".:ExportStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportStrategy.html",
|
|
16
|
-
"TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
|
|
17
|
-
".:TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
|
|
18
|
-
"car": "https://ipfs.github.io/helia/functions/_helia_car.car.html",
|
|
19
|
-
".:car": "https://ipfs.github.io/helia/functions/_helia_car.car.html"
|
|
20
|
-
}
|