@helia/car 5.1.0 → 5.1.1-4e5ff555
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/dist/index.min.js +1 -1
- package/dist/index.min.js.map +4 -4
- package/dist/src/car.d.ts.map +1 -1
- package/dist/src/car.js +11 -5
- package/dist/src/car.js.map +1 -1
- package/dist/src/constants.d.ts +4 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +4 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/export-strategies/unixfs-exporter.d.ts +31 -0
- package/dist/src/export-strategies/unixfs-exporter.d.ts.map +1 -1
- package/dist/src/export-strategies/unixfs-exporter.js +91 -2
- package/dist/src/export-strategies/unixfs-exporter.js.map +1 -1
- package/package.json +7 -5
- package/src/car.ts +14 -5
- package/src/constants.ts +5 -0
- package/src/export-strategies/unixfs-exporter.ts +144 -3
- package/dist/typedoc-urls.json +0 -21
package/dist/src/car.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"car.d.ts","sourceRoot":"","sources":["../../src/car.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACtF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,qBAAa,GAAI,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;gBAEf,UAAU,EAAE,aAAa;IAKhC,MAAM,CAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,eAAe,CAAC,2BAA2B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9H,MAAM,CAAE,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"car.d.ts","sourceRoot":"","sources":["../../src/car.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AACtF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAU,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEtD,qBAAa,GAAI,YAAW,YAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;gBAEf,UAAU,EAAE,aAAa;IAKhC,MAAM,CAAE,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,eAAe,CAAC,2BAA2B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9H,MAAM,CAAE,IAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC;YAoC7F,OAAO;CAuEtB"}
|
package/dist/src/car.js
CHANGED
|
@@ -2,7 +2,7 @@ import { CarWriter } from '@ipld/car';
|
|
|
2
2
|
import drain from 'it-drain';
|
|
3
3
|
import map from 'it-map';
|
|
4
4
|
import { raceSignal } from 'race-signal';
|
|
5
|
-
import { DAG_PB_CODEC_CODE } from "./constants.js";
|
|
5
|
+
import { DAG_PB_CODEC_CODE, IDENTITY_CODEC_CODE } from "./constants.js";
|
|
6
6
|
import { SubgraphExporter } from './export-strategies/subgraph-exporter.js';
|
|
7
7
|
import { UnixFSExporter } from './index.js';
|
|
8
8
|
export class Car {
|
|
@@ -16,12 +16,13 @@ export class Car {
|
|
|
16
16
|
await drain(this.components.blockstore.putMany(map(reader.blocks(), ({ cid, bytes }) => ({ cid, bytes })), options));
|
|
17
17
|
}
|
|
18
18
|
async *export(root, options) {
|
|
19
|
-
const
|
|
19
|
+
const roots = (Array.isArray(root) ? root : [root]);
|
|
20
|
+
const { writer, out } = CarWriter.create(roots);
|
|
20
21
|
const iter = out[Symbol.asyncIterator]();
|
|
21
22
|
const controller = new AbortController();
|
|
22
23
|
// has to be done async so we write to `writer` and read from `out` at the
|
|
23
24
|
// same time
|
|
24
|
-
this._export(
|
|
25
|
+
this._export(roots, writer, options)
|
|
25
26
|
.catch((err) => {
|
|
26
27
|
this.log.error('error during streaming export - %e', err);
|
|
27
28
|
controller.abort(err);
|
|
@@ -43,10 +44,12 @@ export class Car {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
|
-
async _export(
|
|
47
|
-
const roots = Array.isArray(root) ? root : [root];
|
|
47
|
+
async _export(roots, writer, options) {
|
|
48
48
|
const traversalStrategy = options?.traversal;
|
|
49
49
|
for (const root of roots) {
|
|
50
|
+
if (root.multihash.code === IDENTITY_CODEC_CODE) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
50
53
|
const exportStrategy = options?.exporter ?? (root.code === DAG_PB_CODEC_CODE ? new UnixFSExporter() : new SubgraphExporter());
|
|
51
54
|
let current = root;
|
|
52
55
|
let underRoot = false;
|
|
@@ -79,6 +82,9 @@ export class Car {
|
|
|
79
82
|
if (options?.blockFilter?.has(cid.multihash.bytes) === true) {
|
|
80
83
|
continue;
|
|
81
84
|
}
|
|
85
|
+
if (cid.multihash.code === IDENTITY_CODEC_CODE) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
82
88
|
// skip the export target block if we have already included it during
|
|
83
89
|
// traversal
|
|
84
90
|
if (underRoot && cid.equals(current)) {
|
package/dist/src/car.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"car.js","sourceRoot":"","sources":["../../src/car.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,KAAK,MAAM,UAAU,CAAA;AAC5B,OAAO,GAAG,MAAM,QAAQ,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"car.js","sourceRoot":"","sources":["../../src/car.ts"],"names":[],"mappings":"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"}
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -7,4 +7,8 @@ export declare const DAG_PB_CODEC_CODE = 112;
|
|
|
7
7
|
* The multicodec code for raw binary data
|
|
8
8
|
*/
|
|
9
9
|
export declare const RAW_PB_CODEC_CODE = 85;
|
|
10
|
+
/**
|
|
11
|
+
* The multicodec code for identity hashes
|
|
12
|
+
*/
|
|
13
|
+
export declare const IDENTITY_CODEC_CODE = 0;
|
|
10
14
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,iBAAiB,MAAO,CAAA;AAErC;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAAO,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,IAAI,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,iBAAiB,MAAO,CAAA;AAErC;;GAEG;AACH,eAAO,MAAM,iBAAiB,KAAO,CAAA;AAErC;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAAO,CAAA"}
|
package/dist/src/constants.js
CHANGED
|
@@ -7,4 +7,8 @@ export const DAG_PB_CODEC_CODE = 0x70;
|
|
|
7
7
|
* The multicodec code for raw binary data
|
|
8
8
|
*/
|
|
9
9
|
export const RAW_PB_CODEC_CODE = 0x55;
|
|
10
|
+
/**
|
|
11
|
+
* The multicodec code for identity hashes
|
|
12
|
+
*/
|
|
13
|
+
export const IDENTITY_CODEC_CODE = 0x00;
|
|
10
14
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA"}
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAA;AAE3C;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAA"}
|
|
@@ -4,6 +4,35 @@ import type { AbortOptions } from '@libp2p/interface';
|
|
|
4
4
|
import type { Blockstore } from 'interface-blockstore';
|
|
5
5
|
import type { BlockView } from 'multiformats';
|
|
6
6
|
import type { CID } from 'multiformats/cid';
|
|
7
|
+
export interface UnixFSExporterOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Include blocks that start with this offset.
|
|
10
|
+
*
|
|
11
|
+
* If the CID being exported is a directory, this option is ignored.
|
|
12
|
+
*
|
|
13
|
+
* @default 0
|
|
14
|
+
*/
|
|
15
|
+
offset?: number;
|
|
16
|
+
/**
|
|
17
|
+
* Only include blocks that would include this many file bytes (exclusive,
|
|
18
|
+
* inclusive of offset).
|
|
19
|
+
*
|
|
20
|
+
* If the CID being exported is a directory, this option is ignored.
|
|
21
|
+
*
|
|
22
|
+
* @default Infinity
|
|
23
|
+
*/
|
|
24
|
+
length?: number;
|
|
25
|
+
/**
|
|
26
|
+
* By default an exported CAR file will include all blocks that make up a
|
|
27
|
+
* directory, and the files that are stored there.
|
|
28
|
+
*
|
|
29
|
+
* To only include blocks that allow the initial enumeration of the directory,
|
|
30
|
+
* pass `true` here
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*/
|
|
34
|
+
listingOnly?: boolean;
|
|
35
|
+
}
|
|
7
36
|
/**
|
|
8
37
|
* Traverses the DAG depth-first starting at the target CID and yields all
|
|
9
38
|
* encountered blocks.
|
|
@@ -12,6 +41,8 @@ import type { CID } from 'multiformats/cid';
|
|
|
12
41
|
* the helia config.
|
|
13
42
|
*/
|
|
14
43
|
export declare class UnixFSExporter implements ExportStrategy {
|
|
44
|
+
private options?;
|
|
45
|
+
constructor(options?: UnixFSExporterOptions);
|
|
15
46
|
export(cid: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined>;
|
|
16
47
|
}
|
|
17
48
|
//# sourceMappingURL=unixfs-exporter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unixfs-exporter.d.ts","sourceRoot":"","sources":["../../../src/export-strategies/unixfs-exporter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unixfs-exporter.d.ts","sourceRoot":"","sources":["../../../src/export-strategies/unixfs-exporter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,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,EAAW,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IAEf;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAsBD;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,cAAc;IACnD,OAAO,CAAC,OAAO,CAAC,CAAuB;gBAE1B,OAAO,CAAC,EAAE,qBAAqB;IAIpC,MAAM,CAAE,GAAG,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;CA6F7K"}
|
|
@@ -1,6 +1,27 @@
|
|
|
1
1
|
import { depthFirstWalker } from '@helia/utils';
|
|
2
|
+
import { setMaxListeners, InvalidParametersError } from '@libp2p/interface';
|
|
3
|
+
import { anySignal } from 'any-signal';
|
|
4
|
+
import { UnixFS } from 'ipfs-unixfs';
|
|
2
5
|
import { DAG_PB_CODEC_CODE, RAW_PB_CODEC_CODE } from "../constants.js";
|
|
3
6
|
import { NotUnixFSError } from "../errors.js";
|
|
7
|
+
function isRawBlock(block) {
|
|
8
|
+
return block.cid.code === RAW_PB_CODEC_CODE;
|
|
9
|
+
}
|
|
10
|
+
function isDagPBBlock(block) {
|
|
11
|
+
return block.cid.code === DAG_PB_CODEC_CODE;
|
|
12
|
+
}
|
|
13
|
+
function isFile(block) {
|
|
14
|
+
if (isRawBlock(block)) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
else if (isDagPBBlock(block) && block.value.Data != null) {
|
|
18
|
+
const u = UnixFS.unmarshal(block.value.Data);
|
|
19
|
+
return u.type === 'file' || u.type === 'raw';
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
throw new NotUnixFSError('Encountered non raw/dag-pb CID in UnixFS DAG');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
4
25
|
/**
|
|
5
26
|
* Traverses the DAG depth-first starting at the target CID and yields all
|
|
6
27
|
* encountered blocks.
|
|
@@ -9,6 +30,10 @@ import { NotUnixFSError } from "../errors.js";
|
|
|
9
30
|
* the helia config.
|
|
10
31
|
*/
|
|
11
32
|
export class UnixFSExporter {
|
|
33
|
+
options;
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.options = options;
|
|
36
|
+
}
|
|
12
37
|
async *export(cid, blockstore, getCodec, options) {
|
|
13
38
|
if (cid.code !== DAG_PB_CODEC_CODE && cid.code !== RAW_PB_CODEC_CODE) {
|
|
14
39
|
throw new NotUnixFSError('Target CID was not UnixFS - use the SubGraphExporter to export arbitrary graphs');
|
|
@@ -17,8 +42,72 @@ export class UnixFSExporter {
|
|
|
17
42
|
blockstore,
|
|
18
43
|
getCodec
|
|
19
44
|
});
|
|
20
|
-
|
|
21
|
-
|
|
45
|
+
const offset = this.options?.offset ?? 0;
|
|
46
|
+
const length = this.options?.length ?? Infinity;
|
|
47
|
+
const listingOnly = this.options?.listingOnly ?? false;
|
|
48
|
+
if (offset < 0) {
|
|
49
|
+
throw new InvalidParametersError('Offset cannot be negative');
|
|
50
|
+
}
|
|
51
|
+
if (length < 0) {
|
|
52
|
+
throw new InvalidParametersError('Length cannot be negative');
|
|
53
|
+
}
|
|
54
|
+
let exportingFile;
|
|
55
|
+
const abortController = new AbortController();
|
|
56
|
+
const signal = anySignal([
|
|
57
|
+
abortController.signal,
|
|
58
|
+
options?.signal
|
|
59
|
+
]);
|
|
60
|
+
setMaxListeners(Infinity, abortController.signal, signal);
|
|
61
|
+
function includeChild(child, parent) {
|
|
62
|
+
if (exportingFile == null) {
|
|
63
|
+
exportingFile = isFile(parent);
|
|
64
|
+
}
|
|
65
|
+
// ignore offset/length if not exporting a file
|
|
66
|
+
if (!exportingFile) {
|
|
67
|
+
const link = parent.value.Links.find(l => l.Hash.equals(child));
|
|
68
|
+
const u = UnixFS.unmarshal(parent.value.Data ?? new Uint8Array());
|
|
69
|
+
if (u.type === 'directory') {
|
|
70
|
+
// do not include directory files
|
|
71
|
+
return !listingOnly;
|
|
72
|
+
}
|
|
73
|
+
if (u.type === 'hamt-sharded-directory' && listingOnly) {
|
|
74
|
+
// only include sub-shards, not directory files
|
|
75
|
+
return link?.Name?.length === 2;
|
|
76
|
+
}
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const childIndex = parent.value.Links.findIndex(link => link.Hash.equals(child));
|
|
80
|
+
const layout = UnixFS.unmarshal(parent.value.Data ?? new Uint8Array());
|
|
81
|
+
const start = offset;
|
|
82
|
+
const end = start + length;
|
|
83
|
+
const childStart = Number([...layout.blockSizes].slice(0, childIndex).reduce((curr, acc) => curr + acc, 0n));
|
|
84
|
+
const childEnd = childStart + Number(layout.blockSizes[childIndex]);
|
|
85
|
+
// slice starts in child
|
|
86
|
+
if (start >= childStart && start < childEnd) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// slice ends in child
|
|
90
|
+
if (end >= childStart && end < childEnd) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
// slice contains child
|
|
94
|
+
if (start <= childStart && end >= childEnd) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
for await (const node of walker.walk(cid, {
|
|
101
|
+
...options,
|
|
102
|
+
includeChild,
|
|
103
|
+
signal
|
|
104
|
+
})) {
|
|
105
|
+
yield node.block;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
abortController.abort();
|
|
110
|
+
signal.clear();
|
|
22
111
|
}
|
|
23
112
|
}
|
|
24
113
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unixfs-exporter.js","sourceRoot":"","sources":["../../../src/export-strategies/unixfs-exporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"unixfs-exporter.js","sourceRoot":"","sources":["../../../src/export-strategies/unixfs-exporter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/car",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.1-4e5ff555",
|
|
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",
|
|
@@ -47,13 +47,15 @@
|
|
|
47
47
|
"test:electron-main": "aegir test -t electron-main"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@helia/interface": "
|
|
51
|
-
"@helia/utils": "
|
|
50
|
+
"@helia/interface": "6.0.0-4e5ff555",
|
|
51
|
+
"@helia/utils": "2.1.1-4e5ff555",
|
|
52
52
|
"@ipld/car": "^5.4.2",
|
|
53
53
|
"@ipld/dag-pb": "^4.1.5",
|
|
54
54
|
"@libp2p/interface": "^3.0.2",
|
|
55
55
|
"@libp2p/utils": "^7.0.5",
|
|
56
|
+
"any-signal": "^4.1.1",
|
|
56
57
|
"interface-blockstore": "^6.0.1",
|
|
58
|
+
"ipfs-unixfs": "^12.0.0",
|
|
57
59
|
"ipfs-unixfs-exporter": "^14.0.1",
|
|
58
60
|
"it-drain": "^3.0.10",
|
|
59
61
|
"it-map": "^3.1.4",
|
|
@@ -63,8 +65,8 @@
|
|
|
63
65
|
"race-signal": "^2.0.0"
|
|
64
66
|
},
|
|
65
67
|
"devDependencies": {
|
|
66
|
-
"@helia/mfs": "
|
|
67
|
-
"@helia/unixfs": "
|
|
68
|
+
"@helia/mfs": "6.0.1-4e5ff555",
|
|
69
|
+
"@helia/unixfs": "6.0.1-4e5ff555",
|
|
68
70
|
"@ipld/dag-cbor": "^9.2.5",
|
|
69
71
|
"@libp2p/logger": "^6.0.5",
|
|
70
72
|
"aegir": "^47.0.22",
|
package/src/car.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { CarWriter } from '@ipld/car'
|
|
|
2
2
|
import drain from 'it-drain'
|
|
3
3
|
import map from 'it-map'
|
|
4
4
|
import { raceSignal } from 'race-signal'
|
|
5
|
-
import { DAG_PB_CODEC_CODE } from './constants.ts'
|
|
5
|
+
import { DAG_PB_CODEC_CODE, IDENTITY_CODEC_CODE } from './constants.ts'
|
|
6
6
|
import { SubgraphExporter } from './export-strategies/subgraph-exporter.js'
|
|
7
7
|
import { UnixFSExporter } from './index.js'
|
|
8
8
|
import type { CarComponents, Car as CarInterface, ExportCarOptions } from './index.js'
|
|
@@ -29,13 +29,15 @@ export class Car implements CarInterface {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async * export (root: CID | CID[], options?: ExportCarOptions): AsyncGenerator<Uint8Array, void, undefined> {
|
|
32
|
-
const
|
|
32
|
+
const roots = (Array.isArray(root) ? root : [root])
|
|
33
|
+
|
|
34
|
+
const { writer, out } = CarWriter.create(roots)
|
|
33
35
|
const iter = out[Symbol.asyncIterator]()
|
|
34
36
|
const controller = new AbortController()
|
|
35
37
|
|
|
36
38
|
// has to be done async so we write to `writer` and read from `out` at the
|
|
37
39
|
// same time
|
|
38
|
-
this._export(
|
|
40
|
+
this._export(roots, writer, options)
|
|
39
41
|
.catch((err) => {
|
|
40
42
|
this.log.error('error during streaming export - %e', err)
|
|
41
43
|
controller.abort(err)
|
|
@@ -62,11 +64,14 @@ export class Car implements CarInterface {
|
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
private async _export (
|
|
66
|
-
const roots = Array.isArray(root) ? root : [root]
|
|
67
|
+
private async _export (roots: CID[], writer: Pick<CarWriter, 'put' | 'close'>, options?: ExportCarOptions): Promise<void> {
|
|
67
68
|
const traversalStrategy = options?.traversal
|
|
68
69
|
|
|
69
70
|
for (const root of roots) {
|
|
71
|
+
if (root.multihash.code === IDENTITY_CODEC_CODE) {
|
|
72
|
+
continue
|
|
73
|
+
}
|
|
74
|
+
|
|
70
75
|
const exportStrategy = options?.exporter ?? (root.code === DAG_PB_CODEC_CODE ? new UnixFSExporter() : new SubgraphExporter())
|
|
71
76
|
let current = root
|
|
72
77
|
let underRoot = false
|
|
@@ -106,6 +111,10 @@ export class Car implements CarInterface {
|
|
|
106
111
|
continue
|
|
107
112
|
}
|
|
108
113
|
|
|
114
|
+
if (cid.multihash.code === IDENTITY_CODEC_CODE) {
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
|
|
109
118
|
// skip the export target block if we have already included it during
|
|
110
119
|
// traversal
|
|
111
120
|
if (underRoot && cid.equals(current)) {
|
package/src/constants.ts
CHANGED
|
@@ -1,12 +1,68 @@
|
|
|
1
1
|
import { depthFirstWalker } from '@helia/utils'
|
|
2
|
+
import { setMaxListeners, InvalidParametersError } from '@libp2p/interface'
|
|
3
|
+
import { anySignal } from 'any-signal'
|
|
4
|
+
import { UnixFS } from 'ipfs-unixfs'
|
|
2
5
|
import { DAG_PB_CODEC_CODE, RAW_PB_CODEC_CODE } from '../constants.ts'
|
|
3
6
|
import { NotUnixFSError } from '../errors.ts'
|
|
4
7
|
import type { ExportStrategy } from '../index.js'
|
|
5
8
|
import type { CodecLoader } from '@helia/interface'
|
|
9
|
+
import type { PBNode } from '@ipld/dag-pb'
|
|
6
10
|
import type { AbortOptions } from '@libp2p/interface'
|
|
7
11
|
import type { Blockstore } from 'interface-blockstore'
|
|
8
12
|
import type { BlockView } from 'multiformats'
|
|
9
|
-
import type { CID } from 'multiformats/cid'
|
|
13
|
+
import type { CID, Version } from 'multiformats/cid'
|
|
14
|
+
|
|
15
|
+
export interface UnixFSExporterOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Include blocks that start with this offset.
|
|
18
|
+
*
|
|
19
|
+
* If the CID being exported is a directory, this option is ignored.
|
|
20
|
+
*
|
|
21
|
+
* @default 0
|
|
22
|
+
*/
|
|
23
|
+
offset?: number
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Only include blocks that would include this many file bytes (exclusive,
|
|
27
|
+
* inclusive of offset).
|
|
28
|
+
*
|
|
29
|
+
* If the CID being exported is a directory, this option is ignored.
|
|
30
|
+
*
|
|
31
|
+
* @default Infinity
|
|
32
|
+
*/
|
|
33
|
+
length?: number
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* By default an exported CAR file will include all blocks that make up a
|
|
37
|
+
* directory, and the files that are stored there.
|
|
38
|
+
*
|
|
39
|
+
* To only include blocks that allow the initial enumeration of the directory,
|
|
40
|
+
* pass `true` here
|
|
41
|
+
*
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
listingOnly?: boolean
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isRawBlock (block: BlockView<any, number, number, Version>): block is BlockView<Uint8Array, 0x55, number, 1> {
|
|
48
|
+
return block.cid.code === RAW_PB_CODEC_CODE
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isDagPBBlock (block: BlockView<any, number, number, Version>): block is BlockView<PBNode, 0x70, number, 1> {
|
|
52
|
+
return block.cid.code === DAG_PB_CODEC_CODE
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function isFile (block: BlockView<any, number, number, 0 | 1>): boolean {
|
|
56
|
+
if (isRawBlock(block)) {
|
|
57
|
+
return true
|
|
58
|
+
} else if (isDagPBBlock(block) && block.value.Data != null) {
|
|
59
|
+
const u = UnixFS.unmarshal(block.value.Data)
|
|
60
|
+
|
|
61
|
+
return u.type === 'file' || u.type === 'raw'
|
|
62
|
+
} else {
|
|
63
|
+
throw new NotUnixFSError('Encountered non raw/dag-pb CID in UnixFS DAG')
|
|
64
|
+
}
|
|
65
|
+
}
|
|
10
66
|
|
|
11
67
|
/**
|
|
12
68
|
* Traverses the DAG depth-first starting at the target CID and yields all
|
|
@@ -16,6 +72,12 @@ import type { CID } from 'multiformats/cid'
|
|
|
16
72
|
* the helia config.
|
|
17
73
|
*/
|
|
18
74
|
export class UnixFSExporter implements ExportStrategy {
|
|
75
|
+
private options?: UnixFSExporterOptions
|
|
76
|
+
|
|
77
|
+
constructor (options?: UnixFSExporterOptions) {
|
|
78
|
+
this.options = options
|
|
79
|
+
}
|
|
80
|
+
|
|
19
81
|
async * export (cid: CID, blockstore: Blockstore, getCodec: CodecLoader, options?: AbortOptions): AsyncGenerator<BlockView<unknown, number, number, 0 | 1>, void, undefined> {
|
|
20
82
|
if (cid.code !== DAG_PB_CODEC_CODE && cid.code !== RAW_PB_CODEC_CODE) {
|
|
21
83
|
throw new NotUnixFSError('Target CID was not UnixFS - use the SubGraphExporter to export arbitrary graphs')
|
|
@@ -26,8 +88,87 @@ export class UnixFSExporter implements ExportStrategy {
|
|
|
26
88
|
getCodec
|
|
27
89
|
})
|
|
28
90
|
|
|
29
|
-
|
|
30
|
-
|
|
91
|
+
const offset = this.options?.offset ?? 0
|
|
92
|
+
const length = this.options?.length ?? Infinity
|
|
93
|
+
const listingOnly = this.options?.listingOnly ?? false
|
|
94
|
+
|
|
95
|
+
if (offset < 0) {
|
|
96
|
+
throw new InvalidParametersError('Offset cannot be negative')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (length < 0) {
|
|
100
|
+
throw new InvalidParametersError('Length cannot be negative')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let exportingFile: boolean
|
|
104
|
+
const abortController = new AbortController()
|
|
105
|
+
const signal = anySignal([
|
|
106
|
+
abortController.signal,
|
|
107
|
+
options?.signal
|
|
108
|
+
])
|
|
109
|
+
setMaxListeners(Infinity, abortController.signal, signal)
|
|
110
|
+
|
|
111
|
+
function includeChild (child: CID, parent: BlockView<PBNode>): boolean {
|
|
112
|
+
if (exportingFile == null) {
|
|
113
|
+
exportingFile = isFile(parent)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ignore offset/length if not exporting a file
|
|
117
|
+
if (!exportingFile) {
|
|
118
|
+
const link = parent.value.Links.find(l => l.Hash.equals(child))
|
|
119
|
+
const u = UnixFS.unmarshal(parent.value.Data ?? new Uint8Array())
|
|
120
|
+
|
|
121
|
+
if (u.type === 'directory') {
|
|
122
|
+
// do not include directory files
|
|
123
|
+
return !listingOnly
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (u.type === 'hamt-sharded-directory' && listingOnly) {
|
|
127
|
+
// only include sub-shards, not directory files
|
|
128
|
+
return link?.Name?.length === 2
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return true
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const childIndex = parent.value.Links.findIndex(link => link.Hash.equals(child))
|
|
135
|
+
const layout = UnixFS.unmarshal(parent.value.Data ?? new Uint8Array())
|
|
136
|
+
|
|
137
|
+
const start = offset
|
|
138
|
+
const end = start + length
|
|
139
|
+
|
|
140
|
+
const childStart = Number([...layout.blockSizes].slice(0, childIndex).reduce((curr, acc) => curr + acc, 0n))
|
|
141
|
+
const childEnd = childStart + Number(layout.blockSizes[childIndex])
|
|
142
|
+
|
|
143
|
+
// slice starts in child
|
|
144
|
+
if (start >= childStart && start < childEnd) {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// slice ends in child
|
|
149
|
+
if (end >= childStart && end < childEnd) {
|
|
150
|
+
return true
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// slice contains child
|
|
154
|
+
if (start <= childStart && end >= childEnd) {
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return false
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
try {
|
|
162
|
+
for await (const node of walker.walk(cid, {
|
|
163
|
+
...options,
|
|
164
|
+
includeChild,
|
|
165
|
+
signal
|
|
166
|
+
})) {
|
|
167
|
+
yield node.block
|
|
168
|
+
}
|
|
169
|
+
} finally {
|
|
170
|
+
abortController.abort()
|
|
171
|
+
signal.clear()
|
|
31
172
|
}
|
|
32
173
|
}
|
|
33
174
|
}
|
package/dist/typedoc-urls.json
DELETED
|
@@ -1,21 +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
|
-
"GraphSearchOptions": "https://ipfs.github.io/helia/interfaces/_helia_car.GraphSearchOptions.html",
|
|
17
|
-
"TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
|
|
18
|
-
".:TraversalStrategy": "https://ipfs.github.io/helia/interfaces/_helia_car.TraversalStrategy.html",
|
|
19
|
-
"car": "https://ipfs.github.io/helia/functions/_helia_car.car.html",
|
|
20
|
-
".:car": "https://ipfs.github.io/helia/functions/_helia_car.car.html"
|
|
21
|
-
}
|