From 0818945459f8ac6564cac2c18296e470bbca074f Mon Sep 17 00:00:00 2001 From: David Dias Date: Sun, 16 Oct 2016 08:11:29 +0100 Subject: [PATCH] feat: main resolver (understands dag-pb) --- package.json | 1 + src/index.js | 44 ++++++++++++++++++++++++-- test/test-ipld-dag-pb.js | 68 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 105 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index f81f1c7..f93f759 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "rimraf": "^2.5.4" }, "dependencies": { + "async": "^2.1.1", "babel-runtime": "^6.11.6", "interface-pull-blob-store": "^0.5.0", "ipfs-block": "^0.3.0", diff --git a/src/index.js b/src/index.js index f5ce8f2..e0897f5 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,8 @@ const Block = require('ipfs-block') const pull = require('pull-stream') const traverse = require('pull-traverse') const utils = require('./utils') +const CID = require('cids') +const until = require('async/until') const IPFSRepo = require('ipfs-repo') const MemoryStore = require('../node_modules/interface-pull-blob-store/lib/reference.js') const BlockService = require('ipfs-block-service') @@ -38,8 +40,46 @@ class IPLDResolver { } } - resolve (cid, path) { - // TODO + resolve (cid, path, callback) { + if (path === '/') { + return this.get(cid, callback) + } + + let value + + until( + () => { + if (!path || path === '' || path === '/') { + return true + } else { + // continue traversing + if (value) { + cid = new CID(value['/']) + } + return false + } + }, + (cb) => { + // get block + // use local resolver + // update path value + this.bs.get(cid, (err, block) => { + if (err) { + return cb(err) + } + const result = this.resolvers[cid.codec].resolver.resolve(block, path) + value = result.value + path = result.remainderPath + cb() + }) + }, + (err, results) => { + if (err) { + return callback(err) + } + return callback(null, value) + } + ) } // Node operations (get and retrieve nodes, not values) diff --git a/test/test-ipld-dag-pb.js b/test/test-ipld-dag-pb.js index 9f267ec..8bb6dff 100644 --- a/test/test-ipld-dag-pb.js +++ b/test/test-ipld-dag-pb.js @@ -10,10 +10,10 @@ const pull = require('pull-stream') const IPLDResolver = require('../src') module.exports = (repo) => { - const bs = new BlockService(repo) - const resolver = new IPLDResolver(bs) - describe('IPLD Resolver with dag-pb (MerkleDAG Protobuf)', () => { + const bs = new BlockService(repo) + const resolver = new IPLDResolver(bs) + let node1 let node2 let node3 @@ -126,8 +126,64 @@ module.exports = (repo) => { }) describe('IPLD Path Resolver', () => { - it.skip('resolves path of a non nested value', () => {}) - it.skip('resolves path of a level 1 nested value', () => {}) - it.skip('resolves path of a level 2 nested value', () => {}) + let resolver + + let node1 + let node2 + let node3 + + before((done) => { + resolver = new IPLDResolver() + + node1 = new dagPB.DAGNode(new Buffer('I am 1')) + node2 = new dagPB.DAGNode(new Buffer('I am 2')) + node3 = new dagPB.DAGNode(new Buffer('I am 3')) + + node2.addNodeLink('1', node1) + + node3.addNodeLink('1', node1) + node3.addNodeLink('2', node2) + + pull( + pull.values([ + node1, + node2, + node3 + ]), + resolver.putStream(done) + ) + }) + + it('root path (same as get)', (done) => { + resolver.resolve(node1.cid(), '/', (err, result) => { + expect(err).to.not.exist + expect(result.cid()).to.eql(node1.cid()) + done() + }) + }) + + it('value within 1st node scope', (done) => { + resolver.resolve(node1.cid(), 'data', (err, result) => { + expect(err).to.not.exist + expect(result).to.eql(new Buffer('I am 1')) + done() + }) + }) + + it('value within nested scope (1 level)', (done) => { + resolver.resolve(node2.cid(), 'links/0/data', (err, result) => { + expect(err).to.not.exist + expect(result).to.eql(new Buffer('I am 1')) + done() + }) + }) + + it('value within nested scope (2 levels)', (done) => { + resolver.resolve(node3.cid(), 'links/1/links/0/data', (err, result) => { + expect(err).to.not.exist + expect(result).to.eql(new Buffer('I am 1')) + done() + }) + }) }) }