-
Notifications
You must be signed in to change notification settings - Fork 34
/
tree-builder.js
100 lines (78 loc) · 2.17 KB
/
tree-builder.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
'use strict'
const DirFlat = require('./dir-flat')
const flatToShard = require('./flat-to-shard')
const Dir = require('./dir')
const toPathComponents = require('./utils/to-path-components')
const errCode = require('err-code')
const first = require('it-first')
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 = null
parent.size = null
if (last) {
await parent.put(pathElem, elem)
tree = await flatToShard(null, parent, options.shardSplitThreshold, options)
} else {
let dir = await parent.get(pathElem)
if (!dir || !(dir instanceof Dir)) {
dir = new DirFlat({
dir: true,
parent: parent,
parentKey: pathElem,
path: currentPath,
dirty: true,
flat: true,
mtime: dir && dir.unixfs && dir.unixfs.mtime,
mode: dir && dir.unixfs && dir.unixfs.mode
}, options)
}
await parent.put(pathElem, dir)
parent = dir
}
}
return tree
}
async function * treeBuilder (source, block, options) {
let tree = new DirFlat({
root: true,
dir: true,
path: '',
dirty: true,
flat: true
}, options)
for await (const entry of source) {
if (!entry) {
continue
}
tree = await addToTree(entry, tree, options)
if (!entry.unixfs || !entry.unixfs.isDirectory()) {
yield entry
}
}
if (!options.wrapWithDirectory) {
if (tree.childCount() > 1) {
throw errCode(new Error('detected more than one root'), 'ERR_MORE_THAN_ONE_ROOT')
}
const unwrapped = await first(tree.eachChildSeries())
if (!unwrapped) {
return
}
tree = unwrapped.child
}
if (!(tree instanceof Dir)) {
if (tree && tree.unixfs && tree.unixfs.isDirectory()) {
yield tree
}
return
}
yield * tree.flush(tree.path, block)
}
module.exports = treeBuilder