Skip to content
This repository was archived by the owner on Apr 29, 2020. It is now read-only.

feat: support storing metadata in unixfs nodes #39

Merged
merged 6 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ stages:
- cov

node_js:
- '10'
- '12'

os:
- linux
Expand Down
27 changes: 13 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ipfs-unixfs-importer
# ipfs-unixfs-importer <!-- omit in toc -->

[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
Expand All @@ -13,22 +13,19 @@

> JavaScript implementation of the layout and chunking mechanisms used by IPFS to handle Files

## Lead Maintainer
## Lead Maintainer <!-- omit in toc -->

[Alex Potsides](https://github.com/achingbrain)

## Table of Contents
## Table of Contents <!-- omit in toc -->

- [ipfs-unixfs-importer](#ipfs-unixfs-importer)
- [Lead Maintainer](#lead-maintainer)
- [Table of Contents](#table-of-contents)
- [Install](#install)
- [Usage](#usage)
- [Example](#example)
- [API](#api)
- [const import = importer(source, ipld [, options])](#const-import--importersource-ipld--options)
- [Contribute](#contribute)
- [License](#license)
- [Install](#install)
- [Usage](#usage)
- [Example](#example)
- [API](#api)
- [const import = importer(source, ipld [, options])](#const-import--importersource-ipld--options)
- [Contribute](#contribute)
- [License](#license)

## Install

Expand Down Expand Up @@ -108,7 +105,9 @@ The `import` function returns an async iterator takes a source async iterator th
```js
{
path: 'a name',
content: (Buffer or iterator emitting Buffers)
content: (Buffer or iterator emitting Buffers),
mtime: (Number representing seconds since (positive) or before (negative) the Unix Epoch),
mode: (Number representing ugo-rwx, setuid, setguid and sticky bit)
}
```

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"cids": "~0.7.1",
"detect-node": "^2.0.4",
"dirty-chai": "^2.0.1",
"ipfs-unixfs-exporter": "~0.37.0",
"ipfs-unixfs-exporter": "^0.39.0",
"ipld": "^0.25.0",
"ipld-in-memory": "^3.0.0",
"multihashes": "~0.4.14",
Expand All @@ -55,16 +55,16 @@
"async-iterator-all": "^1.0.0",
"async-iterator-batch": "~0.0.1",
"async-iterator-first": "^1.0.0",
"bl": "^3.0.0",
"bl": "^4.0.0",
"deep-extend": "~0.6.0",
"err-code": "^2.0.0",
"hamt-sharding": "~0.0.2",
"ipfs-unixfs": "~0.1.16",
"ipfs-unixfs": "^0.2.0",
"ipld-dag-pb": "^0.18.0",
"multicodec": "~0.5.1",
"multihashing-async": "~0.7.0",
"multihashing-async": "^0.8.0",
"rabin-wasm": "~0.0.8",
"superstruct": "~0.6.1"
"superstruct": "^0.8.2"
},
"contributors": [
"Alan Shaw <[email protected]>",
Expand Down
9 changes: 9 additions & 0 deletions src/dag-builder/dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ const {

const dirBuilder = async (item, ipld, options) => {
const unixfs = new UnixFS('directory')

if (item.mtime) {
unixfs.mtime = item.mtime
}

if (item.mode) {
unixfs.mode = item.mode
}

const node = new DAGNode(unixfs.marshal(), [])
const cid = await persist(node, ipld, options)
const path = item.path
Expand Down
21 changes: 19 additions & 2 deletions src/dag-builder/file/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const dagBuilders = {
trickle: require('./trickle')
}

async function * buildFile (source, ipld, options) {
async function * buildFile (file, source, ipld, options) {
let count = -1
let previous

Expand All @@ -36,6 +36,15 @@ async function * buildFile (source, ipld, options) {
opts.cidVersion = 1
} else {
unixfs = new UnixFS(options.leafType, buffer)

if (file.mtime) {
unixfs.mtime = file.mtime
}

if (file.mode) {
unixfs.mode = file.mode
}

node = new DAGNode(unixfs.marshal())
}

Expand Down Expand Up @@ -81,6 +90,14 @@ const reduce = (file, ipld, options) => {
// create a parent node and add all the leaves
const f = new UnixFS('file')

if (file.mtime) {
f.mtime = file.mtime
}

if (file.mode) {
f.mode = file.mode
}

const links = leaves
.filter(leaf => {
if (leaf.cid.codec === 'raw' && leaf.node.length) {
Expand Down Expand Up @@ -132,7 +149,7 @@ const fileBuilder = async (file, source, ipld, options) => {
throw errCode(new Error(`Unknown importer build strategy name: ${options.strategy}`), 'ERR_BAD_STRATEGY')
}

const roots = await all(dagBuilder(buildFile(source, ipld, options), reduce(file, ipld, options), options.builderOptions))
const roots = await all(dagBuilder(buildFile(file, source, ipld, options), reduce(file, ipld, options), options.builderOptions))

if (roots.length > 1) {
throw errCode(new Error('expected a maximum of 1 roots and got ' + roots.length), 'ETOOMANYROOTS')
Expand Down
10 changes: 10 additions & 0 deletions src/dir-flat.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DirFlat extends Dir {
put (name, value) {
this.cid = undefined
this.size = undefined

this._children[name] = value
}

Expand Down Expand Up @@ -68,6 +69,15 @@ class DirFlat extends Dir {
}

const unixfs = new UnixFS('directory')

if (this.mtime) {
unixfs.mtime = this.mtime
}

if (this.mode) {
unixfs.mode = this.mode
}

const node = new DAGNode(unixfs.marshal(), links)
const cid = await persist(node, ipld, this.options)

Expand Down
14 changes: 11 additions & 3 deletions src/dir-sharded.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class DirSharded extends Dir {
}

async * flush (path, ipld) {
for await (const entry of flush(path, this._bucket, ipld, this.options)) {
for await (const entry of flush(path, this._bucket, ipld, this, this.options)) {
yield entry
}
}
Expand All @@ -83,7 +83,7 @@ module.exports = DirSharded

module.exports.hashFn = hashFn

async function * flush (path, bucket, ipld, options) {
async function * flush (path, bucket, ipld, shardRoot, options) {
const children = bucket._children
const links = []

Expand All @@ -99,7 +99,7 @@ async function * flush (path, bucket, ipld, options) {
if (Bucket.isBucket(child)) {
let shard

for await (const subShard of await flush('', child, ipld, options)) {
for await (const subShard of await flush('', child, ipld, null, options)) {
shard = subShard
}

Expand Down Expand Up @@ -141,6 +141,14 @@ async function * flush (path, bucket, ipld, options) {
dir.fanout = bucket.tableSize()
dir.hashType = options.hashFn.code

if (shardRoot && shardRoot.mtime) {
dir.mtime = shardRoot.mtime
}

if (shardRoot && shardRoot.mode) {
dir.mode = shardRoot.mode
}

const node = new DAGNode(dir.marshal(), links)
const cid = await persist(node, ipld, options)

Expand Down
8 changes: 4 additions & 4 deletions src/flat-to-shard.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ module.exports = async function flatToShard (child, dir, threshold, options) {
await parent.put(newDir.parentKey, newDir)
}

if (parent) {
return flatToShard(newDir, parent, threshold, options)
}
return flatToShard(newDir, parent, threshold, options)
}

return newDir
Expand All @@ -36,7 +34,9 @@ async function convertToShard (oldDir, options) {
parentKey: oldDir.parentKey,
path: oldDir.path,
dirty: oldDir.dirty,
flat: false
flat: false,
mtime: oldDir.mtime,
mode: oldDir.mode
}, options)

for await (const { key, child } of oldDir.eachChildSeries()) {
Expand Down
36 changes: 18 additions & 18 deletions src/tree-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ async function addToTree (elem, tree, options) {
parentKey: pathElem,
path: currentPath,
dirty: true,
flat: true
flat: true,
mtime: dir && dir.unixfs && dir.unixfs.mtime,
mode: dir && dir.unixfs && dir.unixfs.mode
}, options)
}

Expand Down Expand Up @@ -64,28 +66,26 @@ async function * treeBuilder (source, ipld, options) {
yield entry
}

if (tree) {
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 (!options.wrapWithDirectory) {
if (tree.childCount() > 1) {
throw errCode(new Error('detected more than one root'), 'ERR_MORE_THAN_ONE_ROOT')
}

if (!tree.dir) {
const unwrapped = await first(tree.eachChildSeries())

if (!unwrapped) {
return
}

for await (const entry of tree.flush(tree.path, ipld)) {
yield entry
}
tree = unwrapped.child
}

if (!tree.dir) {
return
}

for await (const entry of tree.flush(tree.path, ipld)) {
yield entry
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/benchmark.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe.skip('benchmark', function () {
const times = []

after(() => {
console.info(`Percent\tms`) // eslint-disable-line no-console
console.info('Percent\tms') // eslint-disable-line no-console
times.forEach((time, index) => {
console.info(`${index}\t${parseInt(time / REPEATS)}`) // eslint-disable-line no-console
})
Expand Down
Loading