From 53ad3cf3aeba207e2df10d311824e9af6d32d7c6 Mon Sep 17 00:00:00 2001 From: David Dias Date: Wed, 8 Feb 2017 15:33:04 -0800 Subject: [PATCH] feat: the dag resolve and dag get --- API/dag/README.md | 34 ++++----- package.json | 5 +- src/dag-resolve.js | 142 ------------------------------------ src/dag.js | 174 ++++++++++++++++++++++++++++++++++++++++----- src/index.js | 1 - 5 files changed, 173 insertions(+), 183 deletions(-) delete mode 100644 src/dag-resolve.js diff --git a/API/dag/README.md b/API/dag/README.md index 71aaa76f..4d0dfe20 100644 --- a/API/dag/README.md +++ b/API/dag/README.md @@ -9,11 +9,14 @@ dag API ##### `Go` **WIP** -##### `JavaScript` - ipfs.dag.put(dagNode, formatMulticodec, hashAlg, callback) +##### `JavaScript` - ipfs.dag.put(dagNode, options, callback) - `dagNode` - a DAG node that follows one of the supported IPLD formats. -- `formatMulticodec` - The IPLD format multicodec. -- `hashAlg` - The hash algorithm to be used over the serialized dagNode. +- `options` - a object that might contain the follwing values: + - `format` - The IPLD format multicodec. + - `hashAlg` - The hash algorithm to be used over the serialized dagNode. + - `cid` - the CID of the node passed. + - **Note** - You should only pass the CID or the format + hashAlg pair and not both - `callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. If no `callback` is passed, a [promise][] is returned. @@ -24,23 +27,14 @@ If no `callback` is passed, a [promise][] is returned. ##### `Go` **WIP** -##### `JavaScript` - ipfs.dag.get(cid, callback) +##### `JavaScript` - ipfs.dag.get(cid [, path, options], callback) -- `cid` is a [CID][https://github.com/ipfs/js-cid] instance. +- `cid` - a [CID][https://github.com/ipfs/js-cid] instance. +- `path` - the path to be resolved. Optional. +- `options` - a object that might contain the following values: + - `localResolve` - bool - if set to true, it will avoid resolving through different objects. -`callback` must follow `function (err, dagNode) {}` signature, where `err` is an error if the operation was not successful and `dagNode` is the IPLD format DAG node retrieved. +`callback` must follow `function (err, result) {}` signature, where `err` is an error if the operation was not successful and `result` is an object containing: -#### `dag.resolve` - -> Resolves an IPLD path - -##### `Go` **WIP** - -##### `JavaScript` - ipfs.dag.resolve(cid, path, callback) - -- `cid` is a [CID][https://github.com/ipfs/js-cid] instance. -- `path` is a String that represents a valid path to be resolved - -`callback` must follow `function (err, value) {}` signature, where `err` is an error if the operation was not successful and `value` is the value it was retrieved. - -If no `callback` is passed, a [promise][] is returned. +- `value` - the value or node that was fetched during the get operation. +- `remainderPath` - The remainder of the Path that the node was unable to resolve or what was left in a localResolve scenario. diff --git a/package.json b/package.json index 6489a077..673f0eed 100644 --- a/package.json +++ b/package.json @@ -37,10 +37,11 @@ "ipld-dag-pb": "^0.9.4", "multiaddr": "^2.2.0", "multihashes": "^0.3.2", + "pull-stream": "^3.5.0", "readable-stream": "2.2.2" }, "devDependencies": { - "aegir": "^9.4.0" + "aegir": "^10.0.0" }, "contributors": [ "David Dias ", @@ -53,4 +54,4 @@ "haad ", "nginnever " ] -} \ No newline at end of file +} diff --git a/src/dag-resolve.js b/src/dag-resolve.js deleted file mode 100644 index 5bb93531..00000000 --- a/src/dag-resolve.js +++ /dev/null @@ -1,142 +0,0 @@ -/* eslint-env mocha */ -/* eslint max-nested-callbacks: ["error", 8] */ - -'use strict' - -const expect = require('chai').expect -const dagPB = require('ipld-dag-pb') -const dagCBOR = require('ipld-dag-cbor') -const series = require('async/series') -const pull = require('pull-stream') - -module.exports = (common) => { - describe('.dag.resolve', () => { - let ipfs - let nodePb - let nodeCbor - let cidPb - let cidCbor - - before((done) => { - common.setup((err, factory) => { - expect(err).to.not.exist - factory.spawnNode((err, node) => { - expect(err).to.not.exist - ipfs = node - done() - }) - }) - }) - - after((done) => { - common.teardown(done) - }) - - it('populate', (done) => { - series([ - (cb) => { - dagPB.DAGNode.create(new Buffer('I am inside a Protobuf'), (err, node) => { - expect(err).to.not.exist - nodePb = node - cb() - }) - }, - (cb) => { - dagPB.util.cid(nodePb, (err, cid) => { - expect(err).to.not.exist - cidPb = cid - cb() - }) - }, - (cb) => { - nodeCbor = { - someData: 'I am inside a Cbor object', - pb: { '/': cidPb.toBaseEncodedString() } - } - - dagCBOR.util.cid(nodeCbor, (err, cid) => { - expect(err).to.not.exist - cidCbor = cid - cb() - }) - } - ], store) - - function store () { - pull( - pull.values([ - { node: nodePb, multicodec: 'dag-pb', hashAlg: 'sha2-256' }, - { node: nodeCbor, multicodec: 'dag-cbor', hashAlg: 'sha2-256' } - ]), - pull.asyncMap((el, cb) => { - ipfs.dag.put(el.node, el.multicodec, el.hashAlg, cb) - }), - pull.onEnd(done) - ) - } - }) - - describe('callback API', () => { - describe('.resolve', () => { - it('dag-pb get the node', (done) => { - ipfs.dag.resolve(cidPb, '/', (err, result) => { - expect(err).to.not.exist - - dagPB.util.cid(result, (err, cid) => { - expect(err).to.not.exist - expect(cid).to.eql(cidPb) - done() - }) - }) - }) - - it('dag-pb local scope', (done) => { - ipfs.dag.resolve(cidPb, 'data', (err, result) => { - expect(err).to.not.exist - expect(result).to.eql(new Buffer('I am inside a Protobuf')) - done() - }) - }) - - it.skip('dag-pb one level', (done) => {}) - it.skip('dag-pb two levels', (done) => {}) - - it('dag-cbor get the node', (done) => { - ipfs.dag.resolve(cidCbor, '/', (err, result) => { - expect(err).to.not.exist - - dagCBOR.util.cid(result, (err, cid) => { - expect(err).to.not.exist - expect(cid).to.eql(cidCbor) - done() - }) - }) - }) - - it('dag-cbor local scope', (done) => { - ipfs.dag.resolve(cidCbor, 'someData', (err, result) => { - expect(err).to.not.exist - expect(result).to.eql('I am inside a Cbor object') - done() - }) - }) - - it.skip('dag-cbor one level', (done) => {}) - it.skip('dag-cbor two levels', (done) => {}) - it.skip('from dag-pb to dag-cbor', (done) => {}) - - it('from dag-cbor to dag-pb', (done) => { - ipfs.dag.resolve(cidCbor, 'pb/data', (err, result) => { - expect(err).to.not.exist - expect(result).to.eql(new Buffer('I am inside a Protobuf')) - done() - }) - }) - }) - }) - - describe('promise API', () => { - describe('.resolve', () => {}) - }) - }) -} diff --git a/src/dag.js b/src/dag.js index 7881bcae..3fb3bdeb 100644 --- a/src/dag.js +++ b/src/dag.js @@ -4,12 +4,14 @@ 'use strict' const expect = require('chai').expect +const series = require('async/series') +const pull = require('pull-stream') const dagPB = require('ipld-dag-pb') const DAGNode = dagPB.DAGNode const dagCBOR = require('ipld-dag-cbor') module.exports = (common) => { - describe('.dag (basics)', () => { + describe('.dag', () => { let ipfs before(function (done) { @@ -50,11 +52,17 @@ module.exports = (common) => { describe('.put', () => { it('dag-pb with default hash func (sha2-256)', (done) => { - ipfs.dag.put(pbNode, 'dag-pb', 'sha2-256', done) + ipfs.dag.put(pbNode, { + format: 'dag-pb', + hashAlg: 'sha2-256' + }, done) }) it('dag-pb with custom hash func (sha3-512)', (done) => { - ipfs.dag.put(pbNode, 'dag-pb', 'sha3-512', done) + ipfs.dag.put(pbNode, { + format: 'dag-pb', + hashAlg: 'sha3-512' + }, done) }) /* @@ -70,15 +78,24 @@ module.exports = (common) => { */ it('dag-cbor with default hash func (sha2-256)', (done) => { - ipfs.dag.put(cborNode, 'dag-cbor', 'sha2-256', done) + ipfs.dag.put(cborNode, { + format: 'dag-cbor', + hashAlg: 'sha2-256' + }, done) }) it('dag-cbor with custom hash func (sha3-512)', (done) => { - ipfs.dag.put(cborNode, 'dag-cbor', 'sha3-512', done) + ipfs.dag.put(cborNode, { + format: 'dag-cbor', + hashAlg: 'sha3-512' + }, done) }) it('dag-cbor node with wrong multicodec', (done) => { - ipfs.dag.put(cborNode, 'dag-pb', 'sha3-512', (err) => { + ipfs.dag.put(cborNode, { + format: 'dag-pb', + hashAlg: 'sha3-512' + }, (err) => { expect(err).to.exist done() }) @@ -89,27 +106,82 @@ module.exports = (common) => { let pbNode let cborNode + let nodePb + let nodeCbor + let cidPb + let cidCbor + before((done) => { - const someData = new Buffer('some other data') + series([ + (cb) => { + const someData = new Buffer('some other data') - pbNode = DAGNode.create(someData, (err, node) => { - expect(err).to.not.exist - pbNode = node - done() - }) + pbNode = DAGNode.create(someData, (err, node) => { + expect(err).to.not.exist + pbNode = node + cb() + }) + + cborNode = { + data: someData + } + }, + (cb) => { + dagPB.DAGNode.create(new Buffer('I am inside a Protobuf'), (err, node) => { + expect(err).to.not.exist + nodePb = node + cb() + }) + }, + (cb) => { + dagPB.util.cid(nodePb, (err, cid) => { + expect(err).to.not.exist + cidPb = cid + cb() + }) + }, + (cb) => { + nodeCbor = { + someData: 'I am inside a Cbor object', + pb: { '/': cidPb.toBaseEncodedString() } + } + + dagCBOR.util.cid(nodeCbor, (err, cid) => { + expect(err).to.not.exist + cidCbor = cid + cb() + }) + } + ], store) - cborNode = { - data: someData + function store () { + pull( + pull.values([ + { node: nodePb, multicodec: 'dag-pb', hashAlg: 'sha2-256' }, + { node: nodeCbor, multicodec: 'dag-cbor', hashAlg: 'sha2-256' } + ]), + pull.asyncMap((el, cb) => { + ipfs.dag.put(el.node, { + format: el.multicodec, + hashAlg: el.hashAlg + }, cb) + }), + pull.onEnd(done) + ) } }) it('dag-pb node', (done) => { - ipfs.dag.put(pbNode, 'dag-pb', 'sha2-256', (err) => { + ipfs.dag.put(pbNode, { + format: 'dag-pb', + hashAlg: 'sha2-256' + }, (err) => { expect(err).to.not.exist dagPB.util.cid(pbNode, (err, cid) => { expect(err).to.not.exist - ipfs.dag.get(cid, (err, node) => { + ipfs.dag.get(cid, (err, result) => { expect(err).to.not.exist + const node = result.value expect(pbNode.toJSON()).to.eql(node.toJSON()) done() }) @@ -118,18 +190,84 @@ module.exports = (common) => { }) it('dag-cbor node', (done) => { - ipfs.dag.put(cborNode, 'dag-cbor', 'sha2-256', (err) => { + ipfs.dag.put(cborNode, { + format: 'dag-cbor', + hashAlg: 'sha2-256' + }, (err) => { expect(err).to.not.exist dagCBOR.util.cid(cborNode, (err, cid) => { expect(err).to.not.exist - ipfs.dag.get(cid, (err, node) => { + ipfs.dag.get(cid, (err, result) => { expect(err).to.not.exist + + const node = result.value expect(cborNode).to.eql(node) done() }) }) }) }) + + describe('with path', () => { + it('dag-pb get the node', (done) => { + ipfs.dag.get(cidPb, '/', (err, result) => { + expect(err).to.not.exist + + const node = result.value + + dagPB.util.cid(node, (err, cid) => { + expect(err).to.not.exist + expect(cid).to.eql(cidPb) + done() + }) + }) + }) + + it('dag-pb local scope', (done) => { + ipfs.dag.get(cidPb, 'data', (err, result) => { + expect(err).to.not.exist + expect(result.value).to.eql(new Buffer('I am inside a Protobuf')) + done() + }) + }) + + it.skip('dag-pb one level', (done) => {}) + it.skip('dag-pb two levels', (done) => {}) + + it('dag-cbor get the node', (done) => { + ipfs.dag.get(cidCbor, '/', (err, result) => { + expect(err).to.not.exist + + const node = result.value + + dagCBOR.util.cid(node, (err, cid) => { + expect(err).to.not.exist + expect(cid).to.eql(cidCbor) + done() + }) + }) + }) + + it('dag-cbor local scope', (done) => { + ipfs.dag.get(cidCbor, 'someData', (err, result) => { + expect(err).to.not.exist + expect(result.value).to.eql('I am inside a Cbor object') + done() + }) + }) + + it.skip('dag-cbor one level', (done) => {}) + it.skip('dag-cbor two levels', (done) => {}) + it.skip('from dag-pb to dag-cbor', (done) => {}) + + it('from dag-cbor to dag-pb', (done) => { + ipfs.dag.get(cidCbor, 'pb/data', (err, result) => { + expect(err).to.not.exist + expect(result.value).to.eql(new Buffer('I am inside a Protobuf')) + done() + }) + }) + }) }) }) diff --git a/src/index.js b/src/index.js index 19f45844..4a4a4e13 100644 --- a/src/index.js +++ b/src/index.js @@ -9,5 +9,4 @@ exports.swarm = require('./swarm') exports.block = require('./block') exports.dht = require('./dht') exports.dag = require('./dag') -exports.dagResolve = require('./dag-resolve') exports.pubsub = require('./pubsub')