ipfs-unixfs-importer
Version:
JavaScript implementation of the UnixFs importer used by IPFS
96 lines • 3.27 kB
JavaScript
import { DirFlat } from './dir-flat.js';
import { flatToShard } from './flat-to-shard.js';
import { Dir } from './dir.js';
import { toPathComponents } from './utils/to-path-components.js';
async function addToTree(elem, tree, options) {
const pathElems = toPathComponents(elem.path ?? '');
const lastIndex = pathElems.length - 1;
let parent = tree;
let currentPath = '';
for (let i = 0; i < pathElems.length; i++) {
const pathElem = pathElems[i];
currentPath += `${currentPath !== '' ? '/' : ''}${pathElem}`;
const last = (i === lastIndex);
parent.dirty = true;
parent.cid = undefined;
parent.size = undefined;
if (last) {
await parent.put(pathElem, elem);
tree = await flatToShard(null, parent, options.shardSplitThresholdBytes, options);
}
else {
let dir = await parent.get(pathElem);
if ((dir == null) || !(dir instanceof Dir)) {
dir = new DirFlat({
root: false,
dir: true,
parent,
parentKey: pathElem,
path: currentPath,
dirty: true,
flat: true,
mtime: dir?.unixfs?.mtime,
mode: dir?.unixfs?.mode
}, options);
}
await parent.put(pathElem, dir);
parent = dir;
}
}
return tree;
}
async function* flushAndYield(tree, blockstore) {
if (!(tree instanceof Dir)) {
if (tree.unixfs?.isDirectory() === true) {
yield tree;
}
return;
}
yield* tree.flush(blockstore);
}
export function defaultTreeBuilder(options) {
return async function* treeBuilder(source, block) {
let tree = new DirFlat({
root: true,
dir: true,
path: '',
dirty: true,
flat: true
}, options);
let rootDir;
let singleRoot = false;
for await (const entry of source) {
if (entry == null) {
continue;
}
// if all paths are from the same root directory, we should
// wrap them all in that root directory
const dir = `${entry.originalPath ?? ''}`.split('/')[0];
if (dir != null && dir !== '') {
if (rootDir == null) {
rootDir = dir;
singleRoot = true;
}
else if (rootDir !== dir) {
singleRoot = false;
}
}
tree = await addToTree(entry, tree, options);
if (entry.unixfs == null || !entry.unixfs.isDirectory()) {
yield entry;
}
}
if (options.wrapWithDirectory || (singleRoot && tree.childCount() > 1)) {
yield* flushAndYield(tree, block);
}
else {
for await (const unwrapped of tree.eachChildSeries()) {
if (unwrapped == null) {
continue;
}
yield* flushAndYield(unwrapped.child, block);
}
}
};
}
//# sourceMappingURL=tree-builder.js.map