@helia/car 5.0.1 → 5.1.0

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.
Files changed (50) hide show
  1. package/README.md +54 -4
  2. package/dist/index.min.js +1 -1
  3. package/dist/index.min.js.map +4 -4
  4. package/dist/src/car.d.ts +1 -2
  5. package/dist/src/car.d.ts.map +1 -1
  6. package/dist/src/car.js +46 -124
  7. package/dist/src/car.js.map +1 -1
  8. package/dist/src/errors.d.ts +8 -0
  9. package/dist/src/errors.d.ts.map +1 -1
  10. package/dist/src/errors.js +8 -0
  11. package/dist/src/errors.js.map +1 -1
  12. package/dist/src/export-strategies/block-exporter.d.ts +5 -2
  13. package/dist/src/export-strategies/block-exporter.d.ts.map +1 -1
  14. package/dist/src/export-strategies/block-exporter.js +9 -3
  15. package/dist/src/export-strategies/block-exporter.js.map +1 -1
  16. package/dist/src/export-strategies/subgraph-exporter.d.ts +5 -2
  17. package/dist/src/export-strategies/subgraph-exporter.d.ts.map +1 -1
  18. package/dist/src/export-strategies/subgraph-exporter.js +8 -3
  19. package/dist/src/export-strategies/subgraph-exporter.js.map +1 -1
  20. package/dist/src/export-strategies/unixfs-exporter.d.ts +10 -4
  21. package/dist/src/export-strategies/unixfs-exporter.d.ts.map +1 -1
  22. package/dist/src/export-strategies/unixfs-exporter.js +15 -8
  23. package/dist/src/export-strategies/unixfs-exporter.js.map +1 -1
  24. package/dist/src/index.d.ts +64 -12
  25. package/dist/src/index.d.ts.map +1 -1
  26. package/dist/src/index.js +56 -6
  27. package/dist/src/index.js.map +1 -1
  28. package/dist/src/traversal-strategies/cid-path.d.ts +9 -6
  29. package/dist/src/traversal-strategies/cid-path.d.ts.map +1 -1
  30. package/dist/src/traversal-strategies/cid-path.js +35 -12
  31. package/dist/src/traversal-strategies/cid-path.js.map +1 -1
  32. package/dist/src/traversal-strategies/graph-search.d.ts +15 -7
  33. package/dist/src/traversal-strategies/graph-search.d.ts.map +1 -1
  34. package/dist/src/traversal-strategies/graph-search.js +57 -11
  35. package/dist/src/traversal-strategies/graph-search.js.map +1 -1
  36. package/dist/src/traversal-strategies/unixfs-path.d.ts +53 -3
  37. package/dist/src/traversal-strategies/unixfs-path.d.ts.map +1 -1
  38. package/dist/src/traversal-strategies/unixfs-path.js +70 -30
  39. package/dist/src/traversal-strategies/unixfs-path.js.map +1 -1
  40. package/dist/typedoc-urls.json +1 -0
  41. package/package.json +4 -2
  42. package/src/car.ts +54 -163
  43. package/src/errors.ts +10 -0
  44. package/src/export-strategies/block-exporter.ts +13 -4
  45. package/src/export-strategies/subgraph-exporter.ts +13 -4
  46. package/src/export-strategies/unixfs-exporter.ts +20 -9
  47. package/src/index.ts +66 -15
  48. package/src/traversal-strategies/cid-path.ts +43 -13
  49. package/src/traversal-strategies/graph-search.ts +70 -12
  50. package/src/traversal-strategies/unixfs-path.ts +77 -41
package/dist/src/index.js CHANGED
@@ -23,7 +23,9 @@
23
23
  * const c = car(helia)
24
24
  * const out = nodeFs.createWriteStream('example.car')
25
25
  *
26
- * for await (const buf of c.export(cid)) {
26
+ * for await (const buf of c.export(cid, {
27
+ * signal: AbortSignal.timeout(5_000)
28
+ * })) {
27
29
  * out.write(buf)
28
30
  * }
29
31
  *
@@ -32,6 +34,14 @@
32
34
  *
33
35
  * @example Exporting a part of a UnixFS DAG as a CAR file
34
36
  *
37
+ * Here the graph traversal will start at `root` and include the blocks for
38
+ * `root`, `/foo`, `/bar`, and all the blocks that make up `baz.txt`.
39
+ *
40
+ * If there are other files/directories in the UnixFS DAG under `root`, they
41
+ * will not be included.
42
+ *
43
+ * `root` will be the only entry in the CAR file roots.
44
+ *
35
45
  * ```typescript
36
46
  * import { createHelia } from 'helia'
37
47
  * import { car, UnixFSPath } from '@helia/car'
@@ -39,12 +49,13 @@
39
49
  * import nodeFs from 'node:fs'
40
50
  *
41
51
  * const helia = await createHelia()
42
- * const cid = CID.parse('QmFoo...')
52
+ * const root = CID.parse('QmFoo...')
43
53
  *
44
54
  * const c = car(helia)
45
55
  * const out = nodeFs.createWriteStream('example.car')
46
56
  *
47
- * for await (const buf of c.export(cid, {
57
+ * for await (const buf of c.export(root, {
58
+ * signal: AbortSignal.timeout(5_000),
48
59
  * traversal: new UnixFSPath('/foo/bar/baz.txt')
49
60
  * })) {
50
61
  * out.write(buf)
@@ -53,6 +64,43 @@
53
64
  * out.end()
54
65
  * ```
55
66
  *
67
+ * @example Including traversal path above the root in a CAR
68
+ *
69
+ * The `includeTraversalBlocks` option will include the traversal blocks in the
70
+ * CAR when they would otherwise be excluded (for example when the traversal
71
+ * starts in a parent of the export root).
72
+ *
73
+ * Here `baz` is the CID for `baz.txt`.
74
+ *
75
+ * The CAR file will include the blocks for `parent`, `/foo`, `/bar`, and
76
+ * `/baz.txt`.
77
+ *
78
+ * `baz` will be the only entry in the CAR file roots.
79
+ *
80
+ * ```typescript
81
+ * import { createHelia } from 'helia'
82
+ * import { car, UnixFSPath } from '@helia/car'
83
+ * import { CID } from 'multiformats/cid'
84
+ * import nodeFs from 'node:fs'
85
+ *
86
+ * const helia = await createHelia()
87
+ * const parent = CID.parse('QmFoo...')
88
+ * const baz = CID.parse('QmBar...')
89
+ *
90
+ * const c = car(helia)
91
+ * const out = nodeFs.createWriteStream('example.car')
92
+ *
93
+ * for await (const buf of c.export(baz, {
94
+ * signal: AbortSignal.timeout(5_000),
95
+ * traversal: new UnixFSPath(parent, '/foo/bar/baz.txt'),
96
+ * includeTraversalBlocks: true
97
+ * })) {
98
+ * out.write(buf)
99
+ * }
100
+ *
101
+ * out.end()
102
+ * ```
103
+ *
56
104
  * @example Importing all blocks from a CAR file
57
105
  *
58
106
  * ```typescript
@@ -72,7 +120,9 @@
72
120
  * const reader = await CarReader.fromIterable(inStream)
73
121
  *
74
122
  * const c = car(helia)
75
- * await c.import(reader)
123
+ * await c.import(reader, {
124
+ * signal: AbortSignal.timeout(5_000)
125
+ * })
76
126
  * ```
77
127
  */
78
128
  import { Car as CarClass } from './car.js';
@@ -81,7 +131,7 @@ export * from './traversal-strategies/index.js';
81
131
  /**
82
132
  * Create a {@link Car} instance for use with {@link https://github.com/ipfs/helia Helia}
83
133
  */
84
- export function car(helia, init = {}) {
85
- return new CarClass(helia, init);
134
+ export function car(helia) {
135
+ return new CarClass(helia);
86
136
  }
87
137
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAEH,OAAO,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,UAAU,CAAA;AAgD1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAgF/C;;GAEG;AACH,MAAM,UAAU,GAAG,CAAE,KAAoB,EAAE,OAAY,EAAE;IACvD,OAAO,IAAI,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AAClC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8HG;AAEH,OAAO,EAAE,GAAG,IAAI,QAAQ,EAAE,MAAM,UAAU,CAAA;AA0C1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAuF/C;;GAEG;AACH,MAAM,UAAU,GAAG,CAAE,KAAoB;IACvC,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC"}
@@ -1,16 +1,19 @@
1
1
  import type { TraversalStrategy } from '../index.js';
2
- import type { BlockView } from 'multiformats/block/interface';
2
+ import type { CodecLoader } from '@helia/interface';
3
+ import type { AbortOptions } from '@libp2p/interface';
4
+ import type { Blockstore } from 'interface-blockstore';
5
+ import type { BlockView } from 'multiformats';
3
6
  import type { CID } from 'multiformats/cid';
4
7
  /**
5
8
  * Simple strategy that traverses a known path to a target CID.
6
9
  *
7
10
  * All this strategy does is yield the next CID in the known path.
11
+ *
12
+ * The path should end with the CID to be exported
8
13
  */
9
14
  export declare class CIDPath implements TraversalStrategy {
10
- private readonly pathToTarget;
11
- private readonly target;
12
- constructor(pathToTarget: CID[]);
13
- isTarget(cid: CID): boolean;
14
- traverse<T extends BlockView<any, any, any, 0 | 1>>(cid: CID, _block?: T): AsyncGenerator<CID, void, undefined>;
15
+ private readonly path;
16
+ constructor(path: CID[]);
17
+ traverse(root: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined>;
15
18
  }
16
19
  //# sourceMappingURL=cid-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cid-path.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/cid-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;;;GAIG;AACH,qBAAa,OAAQ,YAAW,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAO;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAK;gBAEf,YAAY,EAAE,GAAG,EAAE;IAKhC,QAAQ,CAAE,GAAG,EAAE,GAAG,GAAG,OAAO;IAIpB,QAAQ,CAAE,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;CAMzH"}
1
+ {"version":3,"file":"cid-path.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/cid-path.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;;;;;GAMG;AACH,qBAAa,OAAQ,YAAW,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;gBAEf,IAAI,EAAE,GAAG,EAAE;IAIhB,QAAQ,CAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC;CAkChL"}
@@ -1,22 +1,45 @@
1
+ import toBuffer from 'it-to-buffer';
2
+ import { createUnsafe } from 'multiformats/block';
3
+ import { InvalidTraversalError, NotDescendantError } from '../errors.js';
1
4
  /**
2
5
  * Simple strategy that traverses a known path to a target CID.
3
6
  *
4
7
  * All this strategy does is yield the next CID in the known path.
8
+ *
9
+ * The path should end with the CID to be exported
5
10
  */
6
11
  export class CIDPath {
7
- pathToTarget;
8
- target;
9
- constructor(pathToTarget) {
10
- this.pathToTarget = pathToTarget;
11
- this.target = pathToTarget[pathToTarget.length - 1];
12
- }
13
- isTarget(cid) {
14
- return this.target.equals(cid);
12
+ path;
13
+ constructor(path) {
14
+ this.path = path;
15
15
  }
16
- async *traverse(cid, _block) {
17
- const givenCidIndex = this.pathToTarget.indexOf(cid);
18
- const nextCid = this.pathToTarget[givenCidIndex + 1];
19
- yield nextCid;
16
+ async *traverse(root, blockstore, getCodec, options) {
17
+ if (!this.path.some(c => c.equals(root))) {
18
+ throw new InvalidTraversalError(`CIDPath traversal must include ${root}`);
19
+ }
20
+ let parentBlock;
21
+ for (const cid of this.path) {
22
+ if (parentBlock != null) {
23
+ let isChild = false;
24
+ for (const [, child] of parentBlock.links()) {
25
+ if (child.equals(cid)) {
26
+ isChild = true;
27
+ break;
28
+ }
29
+ }
30
+ if (!isChild) {
31
+ throw new NotDescendantError(`${cid} is not a child of ${parentBlock.cid}`);
32
+ }
33
+ }
34
+ const bytes = await toBuffer(blockstore.get(cid, options));
35
+ const block = createUnsafe({
36
+ cid,
37
+ bytes,
38
+ codec: await getCodec(cid.code)
39
+ });
40
+ parentBlock = block;
41
+ yield block;
42
+ }
20
43
  }
21
44
  }
22
45
  //# sourceMappingURL=cid-path.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cid-path.js","sourceRoot":"","sources":["../../../src/traversal-strategies/cid-path.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,OAAO,OAAO;IACD,YAAY,CAAO;IACnB,MAAM,CAAK;IAE5B,YAAa,YAAmB;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAChC,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,QAAQ,CAAE,GAAQ;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAA6C,GAAQ,EAAE,MAAU;QAC/E,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,GAAG,CAAC,CAAC,CAAA;QAEpD,MAAM,OAAO,CAAA;IACf,CAAC;CACF"}
1
+ {"version":3,"file":"cid-path.js","sourceRoot":"","sources":["../../../src/traversal-strategies/cid-path.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAQxE;;;;;;GAMG;AACH,MAAM,OAAO,OAAO;IACD,IAAI,CAAO;IAE5B,YAAa,IAAW;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAAE,IAAS,EAAE,UAAsB,EAAE,QAAqB,EAAE,OAAsB;QAChG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,qBAAqB,CAAC,kCAAkC,IAAI,EAAE,CAAC,CAAA;QAC3E,CAAC;QAED,IAAI,WAAkE,CAAA;QAEtE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;gBACxB,IAAI,OAAO,GAAG,KAAK,CAAA;gBAEnB,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC;oBAC5C,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtB,OAAO,GAAG,IAAI,CAAA;wBACd,MAAK;oBACP,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,MAAM,IAAI,kBAAkB,CAAC,GAAG,GAAG,sBAAsB,WAAW,CAAC,GAAG,EAAE,CAAC,CAAA;gBAC7E,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;YAC1D,MAAM,KAAK,GAAG,YAAY,CAAC;gBACzB,GAAG;gBACH,KAAK;gBACL,KAAK,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;aAChC,CAAC,CAAA;YAEF,WAAW,GAAG,KAAK,CAAA;YACnB,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;CACF"}
@@ -1,14 +1,22 @@
1
1
  import type { TraversalStrategy } from '../index.js';
2
- import type { BlockView } from 'multiformats/block/interface';
2
+ import type { CodecLoader } from '@helia/interface';
3
+ import type { AbortOptions } from '@libp2p/interface';
4
+ import type { Blockstore } from 'interface-blockstore';
5
+ import type { BlockView } from 'multiformats';
3
6
  import type { CID } from 'multiformats/cid';
7
+ export interface GraphSearchOptions {
8
+ strategy?: 'depth-first' | 'breadth-first';
9
+ }
4
10
  /**
5
- * A traversal strategy that performs a breadth-first search (so as to not load blocks unnecessarily) looking for a
6
- * target CID. Traversal stops when we reach the target CID or run out of nodes.
11
+ * A traversal strategy that performs a depth-first search looking for a target
12
+ * CID.
7
13
  */
8
14
  export declare class GraphSearch implements TraversalStrategy {
9
- private readonly target;
10
- constructor(target: CID);
11
- isTarget(cid: CID): boolean;
12
- traverse<T extends BlockView<any, any, any, 0 | 1>>(cid: CID, block: T): AsyncGenerator<CID, void, undefined>;
15
+ private haystack?;
16
+ private readonly needle;
17
+ private readonly options?;
18
+ constructor(needle: CID, options?: GraphSearchOptions);
19
+ constructor(haystack: CID, needle: CID, options?: GraphSearchOptions);
20
+ traverse(root: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined>;
13
21
  }
14
22
  //# sourceMappingURL=graph-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-search.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/graph-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;;GAGG;AACH,qBAAa,WAAY,YAAW,iBAAiB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAK;gBAEf,MAAM,EAAE,GAAG;IAIxB,QAAQ,CAAE,GAAG,EAAE,GAAG,GAAG,OAAO;IAIpB,QAAQ,CAAE,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;CAKvH"}
1
+ {"version":3,"file":"graph-search.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/graph-search.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,aAAa,GAAG,eAAe,CAAA;CAC3C;AAMD;;;GAGG;AACH,qBAAa,WAAY,YAAW,iBAAiB;IACnD,OAAO,CAAC,QAAQ,CAAC,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAoB;gBAEhC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,kBAAkB;gBACzC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAgB7D,QAAQ,CAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC;CAmChL"}
@@ -1,19 +1,65 @@
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.js";
6
+ function isCID(obj) {
7
+ return obj != null && obj?.asCID === obj;
8
+ }
1
9
  /**
2
- * A traversal strategy that performs a breadth-first search (so as to not load blocks unnecessarily) looking for a
3
- * target CID. Traversal stops when we reach the target CID or run out of nodes.
10
+ * A traversal strategy that performs a depth-first search looking for a target
11
+ * CID.
4
12
  */
5
13
  export class GraphSearch {
6
- target;
7
- constructor(target) {
8
- this.target = target;
9
- }
10
- isTarget(cid) {
11
- return this.target.equals(cid);
14
+ haystack;
15
+ needle;
16
+ options;
17
+ constructor(...args) {
18
+ if (isCID(args[0])) {
19
+ if (isCID(args[1])) {
20
+ this.haystack = args[0];
21
+ this.needle = args[1];
22
+ this.options = args[2];
23
+ }
24
+ else {
25
+ this.needle = args[0];
26
+ this.options = args[1];
27
+ }
28
+ }
29
+ else {
30
+ throw new InvalidParametersError('needle must be specified');
31
+ }
12
32
  }
13
- async *traverse(cid, block) {
14
- for (const [, linkedCid] of block.links()) {
15
- yield linkedCid;
33
+ async *traverse(root, blockstore, getCodec, options) {
34
+ const start = this.haystack ?? root;
35
+ let walker;
36
+ if (this.options?.strategy === 'breadth-first') {
37
+ walker = breadthFirstWalker({
38
+ blockstore,
39
+ getCodec
40
+ });
41
+ }
42
+ else {
43
+ walker = depthFirstWalker({
44
+ blockstore,
45
+ getCodec
46
+ });
47
+ }
48
+ for await (const node of walker.walk(start, options)) {
49
+ if (node.block.cid.equals(this.needle)) {
50
+ for (const cid of node.path) {
51
+ const bytes = await toBuffer(blockstore.get(cid, options));
52
+ const block = createUnsafe({
53
+ cid,
54
+ bytes,
55
+ codec: await getCodec(cid.code)
56
+ });
57
+ yield block;
58
+ }
59
+ return;
60
+ }
16
61
  }
62
+ throw new InvalidTraversalError(`${this.needle} was not a child of ${start}`);
17
63
  }
18
64
  }
19
65
  //# sourceMappingURL=graph-search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph-search.js","sourceRoot":"","sources":["../../../src/traversal-strategies/graph-search.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACL,MAAM,CAAK;IAE5B,YAAa,MAAW;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,QAAQ,CAAE,GAAQ;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAA6C,GAAQ,EAAE,KAAQ;QAC7E,KAAK,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1C,MAAM,SAAS,CAAA;QACjB,CAAC;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"graph-search.js","sourceRoot":"","sources":["../../../src/traversal-strategies/graph-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,QAAQ,MAAM,cAAc,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAapD,SAAS,KAAK,CAAE,GAAS;IACvB,OAAO,GAAG,IAAI,IAAI,IAAI,GAAG,EAAE,KAAK,KAAK,GAAG,CAAA;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,WAAW;IACd,QAAQ,CAAM;IACL,MAAM,CAAK;IACX,OAAO,CAAqB;IAI7C,YAAa,GAAG,IAAW;QACzB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACxB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;gBACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,sBAAsB,CAAC,0BAA0B,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAAE,IAAS,EAAE,UAAsB,EAAE,QAAqB,EAAE,OAAsB;QAChG,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAA;QACnC,IAAI,MAAmB,CAAA;QAEvB,IAAI,IAAI,CAAC,OAAO,EAAE,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC/C,MAAM,GAAG,kBAAkB,CAAC;gBAC1B,UAAU;gBACV,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,gBAAgB,CAAC;gBACxB,UAAU;gBACV,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;YACrD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC5B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;oBAC1D,MAAM,KAAK,GAAG,YAAY,CAAC;wBACzB,GAAG;wBACH,KAAK;wBACL,KAAK,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;qBAChC,CAAC,CAAA;oBAEF,MAAM,KAAK,CAAA;gBACb,CAAC;gBAED,OAAM;YACR,CAAC;QACH,CAAC;QAED,MAAM,IAAI,qBAAqB,CAAC,GAAG,IAAI,CAAC,MAAM,uBAAuB,KAAK,EAAE,CAAC,CAAA;IAC/E,CAAC;CACF"}
@@ -1,13 +1,63 @@
1
1
  import type { TraversalStrategy } from '../index.js';
2
- import type { BlockView } from 'multiformats/block/interface';
2
+ import type { CodecLoader } from '@helia/interface';
3
+ import type { AbortOptions } from '@libp2p/interface';
4
+ import type { Blockstore } from 'interface-blockstore';
5
+ import type { BlockView } from 'multiformats';
3
6
  import type { CID } from 'multiformats/cid';
4
7
  /**
5
8
  * Traverses a DAG containing UnixFS directories
9
+ *
10
+ * A root CID may be specified to begin traversal from, otherwise the root
11
+ * currently being exported will be used.
12
+ *
13
+ * @example Begin traversal from the root being exported
14
+ *
15
+ * In this example, the UnixFS path `/foo/bar/baz.txt` path should be resolvable
16
+ * beneath the `root` CID.
17
+ *
18
+ * ```typescript
19
+ * import { createHelia } from 'helia'
20
+ * import { car, UnixFSPath } from '@helia/car'
21
+ * import { CID } from 'multiformats/cid'
22
+ *
23
+ * const helia = await createHelia()
24
+ * const c = car(helia)
25
+ * const root = CID.parse('QmRoot')
26
+ *
27
+ * for await (const buf of c.export(root, {
28
+ * traversal: new UnixFSPath('/foo/bar/baz.txt')
29
+ * })) {
30
+ * // do something with `buf`
31
+ * }
32
+ * ```
33
+ *
34
+ * @example Begin traversal from a parent node
35
+ *
36
+ * In this example, the `root` CID should be resolvable at the UnixFS path
37
+ * beneath `parentCID`.
38
+ *
39
+ * ```typescript
40
+ * import { createHelia } from 'helia'
41
+ * import { car, UnixFSPath } from '@helia/car'
42
+ * import { CID } from 'multiformats/cid'
43
+ *
44
+ * const helia = await createHelia()
45
+ * const c = car(helia)
46
+ * const root = CID.parse('QmRoot')
47
+ * const parentCID = CID.parse('QmParent')
48
+ *
49
+ * for await (const buf of c.export(root, {
50
+ * traversal: new UnixFSPath(parentCID, '/foo/bar/baz.txt')
51
+ * })) {
52
+ * // do something with `buf`
53
+ * }
54
+ * ```
6
55
  */
7
56
  export declare class UnixFSPath implements TraversalStrategy {
57
+ private readonly root?;
8
58
  private readonly path;
9
59
  constructor(path: string);
10
- isTarget(): boolean;
11
- traverse<T extends BlockView<any, any, any, 0 | 1>>(cid: CID, block: T): AsyncGenerator<CID, void, undefined>;
60
+ constructor(root: CID, path: string);
61
+ traverse(root: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined>;
12
62
  }
13
63
  //# sourceMappingURL=unixfs-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"unixfs-path.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/unixfs-path.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;GAEG;AACH,qBAAa,UAAW,YAAW,iBAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;gBAElB,IAAI,EAAE,MAAM;IAKzB,QAAQ,IAAK,OAAO;IAIZ,QAAQ,CAAE,CAAC,SAAS,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,CAAC;CAkCvH"}
1
+ {"version":3,"file":"unixfs-path.d.ts","sourceRoot":"","sources":["../../../src/traversal-strategies/unixfs-path.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBAAa,UAAW,YAAW,iBAAiB;IAClD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAQ;gBAEhB,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM;IAoB5B,QAAQ,CAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC;CAShL"}
@@ -1,42 +1,82 @@
1
- import { decode } from '@ipld/dag-pb';
2
- import { UnixFS } from 'ipfs-unixfs';
3
- import { DAG_PB_CODEC_CODE } from '../constants.js';
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
  /**
6
5
  * Traverses a DAG containing UnixFS directories
6
+ *
7
+ * A root CID may be specified to begin traversal from, otherwise the root
8
+ * currently being exported will be used.
9
+ *
10
+ * @example Begin traversal from the root being exported
11
+ *
12
+ * In this example, the UnixFS path `/foo/bar/baz.txt` path should be resolvable
13
+ * beneath the `root` CID.
14
+ *
15
+ * ```typescript
16
+ * import { createHelia } from 'helia'
17
+ * import { car, UnixFSPath } from '@helia/car'
18
+ * import { CID } from 'multiformats/cid'
19
+ *
20
+ * const helia = await createHelia()
21
+ * const c = car(helia)
22
+ * const root = CID.parse('QmRoot')
23
+ *
24
+ * for await (const buf of c.export(root, {
25
+ * traversal: new UnixFSPath('/foo/bar/baz.txt')
26
+ * })) {
27
+ * // do something with `buf`
28
+ * }
29
+ * ```
30
+ *
31
+ * @example Begin traversal from a parent node
32
+ *
33
+ * In this example, the `root` CID should be resolvable at the UnixFS path
34
+ * beneath `parentCID`.
35
+ *
36
+ * ```typescript
37
+ * import { createHelia } from 'helia'
38
+ * import { car, UnixFSPath } from '@helia/car'
39
+ * import { CID } from 'multiformats/cid'
40
+ *
41
+ * const helia = await createHelia()
42
+ * const c = car(helia)
43
+ * const root = CID.parse('QmRoot')
44
+ * const parentCID = CID.parse('QmParent')
45
+ *
46
+ * for await (const buf of c.export(root, {
47
+ * traversal: new UnixFSPath(parentCID, '/foo/bar/baz.txt')
48
+ * })) {
49
+ * // do something with `buf`
50
+ * }
51
+ * ```
7
52
  */
8
53
  export class UnixFSPath {
54
+ root;
9
55
  path;
10
- constructor(path) {
11
- // "/foo/bar/baz.txt" -> ['foo', 'bar', 'baz.txt']
12
- this.path = path.replace(/^\//, '').split('/');
13
- }
14
- isTarget() {
15
- return this.path.length === 0;
16
- }
17
- async *traverse(cid, block) {
18
- if (cid.code !== DAG_PB_CODEC_CODE) {
19
- throw new NotUnixFSError('Target CID is not UnixFS');
56
+ constructor(...args) {
57
+ let root = args[0];
58
+ let path = args[1];
59
+ if (typeof root === 'string') {
60
+ path = root;
61
+ root = undefined;
20
62
  }
21
- const segment = this.path.shift();
22
- if (segment == null) {
23
- return;
63
+ else if (args.length < 2) {
64
+ throw new Error('path or CID and path must be specified');
24
65
  }
25
- const pb = decode(block.bytes);
26
- if (pb.Data == null) {
27
- throw new NotUnixFSError('Target CID has no UnixFS data in decoded bytes');
66
+ if (!path.startsWith('/')) {
67
+ path = `/${path}`;
28
68
  }
29
- const unixfs = UnixFS.unmarshal(pb.Data);
30
- if (unixfs.type === 'directory') {
31
- const link = pb.Links.filter(link => link.Name === segment).pop();
32
- if (link == null) {
33
- throw new NotUnixFSError(`Target CID directory has no link with name ${segment}`);
34
- }
35
- yield link.Hash;
36
- return;
69
+ this.root = root;
70
+ this.path = path;
71
+ }
72
+ async *traverse(root, blockstore, getCodec, options) {
73
+ for await (const entry of walkPath(`${this.root ?? root}${this.path}`, blockstore, options)) {
74
+ yield createUnsafe({
75
+ cid: entry.cid,
76
+ bytes: entry.node instanceof Uint8Array ? entry.node : dagPb.encode(entry.node),
77
+ codec: await getCodec(entry.cid.code)
78
+ });
37
79
  }
38
- // TODO: HAMT support
39
- throw new NotUnixFSError('Target CID is not a UnixFS directory');
40
80
  }
41
81
  }
42
82
  //# sourceMappingURL=unixfs-path.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"unixfs-path.js","sourceRoot":"","sources":["../../../src/traversal-strategies/unixfs-path.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAK7C;;GAEG;AACH,MAAM,OAAO,UAAU;IACJ,IAAI,CAAU;IAE/B,YAAa,IAAY;QACvB,kDAAkD;QAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAChD,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAA;IAC/B,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAA6C,GAAQ,EAAE,KAAQ;QAC7E,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,cAAc,CAAC,0BAA0B,CAAC,CAAA;QACtD,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;QAEjC,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,OAAM;QACR,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAE9B,IAAI,EAAE,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,cAAc,CAAC,gDAAgD,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAA;QAExC,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,GAAG,EAAE,CAAA;YAEjE,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBACjB,MAAM,IAAI,cAAc,CAAC,8CAA8C,OAAO,EAAE,CAAC,CAAA;YACnF,CAAC;YAED,MAAM,IAAI,CAAC,IAAI,CAAA;YACf,OAAM;QACR,CAAC;QAED,qBAAqB;QAErB,MAAM,IAAI,cAAc,CAAC,sCAAsC,CAAC,CAAA;IAClE,CAAC;CACF"}
1
+ {"version":3,"file":"unixfs-path.js","sourceRoot":"","sources":["../../../src/traversal-strategies/unixfs-path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAQjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAM,OAAO,UAAU;IACJ,IAAI,CAAM;IACV,IAAI,CAAQ;IAI7B,YAAa,GAAG,IAAW;QACzB,IAAI,IAAI,GAA6B,IAAI,CAAC,CAAC,CAAC,CAAA;QAC5C,IAAI,IAAI,GAAW,IAAI,CAAC,CAAC,CAAC,CAAA;QAE1B,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,IAAI,GAAG,IAAI,CAAA;YACX,IAAI,GAAG,SAAS,CAAA;QAClB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,IAAI,GAAG,IAAI,IAAI,EAAE,CAAA;QACnB,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,KAAK,CAAC,CAAE,QAAQ,CAAE,IAAS,EAAE,UAAsB,EAAE,QAAqB,EAAE,OAAsB;QAChG,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;YAC5F,MAAM,YAAY,CAAC;gBACjB,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,KAAK,CAAC,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC/E,KAAK,EAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;aACtC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -13,6 +13,7 @@
13
13
  ".:ExportCarOptions": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportCarOptions.html",
14
14
  "ExportStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportStrategy.html",
15
15
  ".:ExportStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.ExportStrategy.html",
16
+ "GraphSearchOptions": "https://ipfs.github.io/helia/interfaces/_helia_car.GraphSearchOptions.html",
16
17
  "TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
17
18
  ".:TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
18
19
  "car": "https://ipfs.github.io/helia/functions/_helia_car.car.html",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helia/car",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "description": "Import/export car files from Helia",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/ipfs/helia/tree/main/packages/car#readme",
@@ -48,12 +48,13 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "@helia/interface": "^6.0.0",
51
+ "@helia/utils": "^2.1.0",
51
52
  "@ipld/car": "^5.4.2",
52
53
  "@ipld/dag-pb": "^4.1.5",
53
54
  "@libp2p/interface": "^3.0.2",
54
55
  "@libp2p/utils": "^7.0.5",
55
56
  "interface-blockstore": "^6.0.1",
56
- "ipfs-unixfs": "^12.0.0",
57
+ "ipfs-unixfs-exporter": "^14.0.1",
57
58
  "it-drain": "^3.0.10",
58
59
  "it-map": "^3.1.4",
59
60
  "it-to-buffer": "^4.0.10",
@@ -70,6 +71,7 @@
70
71
  "blockstore-core": "^6.1.1",
71
72
  "datastore-core": "^11.0.2",
72
73
  "ipfs-unixfs-importer": "^16.0.1",
74
+ "it-all": "^3.0.9",
73
75
  "it-foreach": "^2.1.4",
74
76
  "it-length": "^3.0.9",
75
77
  "sinon": "^21.0.0"