-
Notifications
You must be signed in to change notification settings - Fork 37
Awesome IPLD endeavour #60
Changes from 7 commits
edee5fa
90ff073
436f44c
00d5d46
0818945
91ecfa4
a186055
b7c2887
39db563
05d4e74
733876b
1bc5a87
4aa591c
cd6e9b1
7978fd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,168 @@ | ||
'use strict' | ||
|
||
exports.IPLDService = require('./ipld-service') | ||
exports.resolve = require('./resolve') | ||
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') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right! (I do remember fighting with this one and this was how I got it to reference to the right one, not sure what was the error without node_modules though). Could you also check ipfs-inactive/interface-pull-blob-store#6, this way we don't even have to point to a path inside. |
||
const BlockService = require('ipfs-block-service') | ||
|
||
const dagPB = require('ipld-dag-pb') | ||
const dagCBOR = require('ipld-dag-cbor') | ||
|
||
class IPLDResolver { | ||
constructor (blockService) { | ||
// nicola will love this! | ||
if (!blockService) { | ||
const repo = new IPFSRepo('in-memory', { stores: MemoryStore }) | ||
blockService = new BlockService(repo) | ||
} | ||
|
||
this.bs = blockService | ||
this.resolvers = {} | ||
|
||
// Support by default dag-pb and dag-cbor | ||
this.support(dagPB.resolver.multicodec, dagPB.resolver, dagPB.util) | ||
this.support(dagCBOR.resolver.multicodec, dagCBOR.resolver, dagCBOR.util) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should there be a way to disable these defaults? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about having functions to add and remove, so that:
|
||
} | ||
|
||
// Adds support for an IPLD format | ||
// default ones are dag-pb and dag-cbor | ||
support (multicodec, resolver, util) { | ||
this.resolvers[multicodec] = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe warn on overriding? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
resolver: resolver, | ||
util: util | ||
} | ||
} | ||
|
||
resolve (cid, path, callback) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why are There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nicola note that CID is a instance of class CID that has several utility methods https://github.com/ipfs/js-cid/tree/feat/complete What you are proposing is to use cids always as strings, which would assume that we have to be constantly parsing and mounting them again to get their props. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I see, perfect then. There must be up in the levels of abstraction a sort of resolver that takes a path and resolve that (by using this, I guess) |
||
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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there should be a check with a nice error message for |
||
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) | ||
|
||
put (nodeAndCID, callback) { | ||
callback = callback || noop | ||
pull( | ||
pull.values([nodeAndCID]), | ||
this.putStream(callback) | ||
) | ||
} | ||
|
||
putStream (callback) { | ||
callback = callback || noop | ||
|
||
return pull( | ||
pull.map((nodeAndCID) => { | ||
const cid = nodeAndCID.cid | ||
const r = this.resolvers[cid.codec] | ||
return { | ||
block: new Block(r.util.serialize(nodeAndCID.node)), | ||
cid: cid | ||
} | ||
}), | ||
this.bs.putStream(), | ||
pull.onEnd(callback) | ||
) | ||
} | ||
|
||
get (cid, callback) { | ||
pull( | ||
this.getStream(cid), | ||
pull.collect((err, res) => { | ||
if (err) { | ||
return callback(err) | ||
} | ||
callback(null, res[0]) | ||
}) | ||
) | ||
} | ||
|
||
getStream (cid) { | ||
return pull( | ||
this.bs.getStream(cid), | ||
pull.map((block) => { | ||
const r = this.resolvers[cid.codec] | ||
if (r) { | ||
return r.util.deserialize(block.data) | ||
} else { // multicodec unknown, send back raw data | ||
return block.data | ||
} | ||
}) | ||
) | ||
} | ||
|
||
// TODO: Consider if we still want this (fact: no one is using it | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets use this opportunity to drop the recursive methods There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 👍 |
||
// right now and this will be just an IPLD selector anyway | ||
getRecursive (cid, callback) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. During the Toronto's IPLD call, we mentioned that this should be a BFS and should have an optional parameter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What we talked was This What you make me think is that we should have a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ^ perfect |
||
pull( | ||
this.getRecursiveStream(cid), | ||
pull.collect(callback) | ||
) | ||
} | ||
|
||
getRecursiveStream (cid) { | ||
return pull( | ||
this.getStream(cid), | ||
pull.map((node) => { | ||
traverse.widthFirst(node, (node) => { | ||
return pull( | ||
pull.values(utils.getKeys(node)), | ||
pull.map((link) => this.getStream(link)), | ||
pull.flatten() | ||
) | ||
}) | ||
}), | ||
pull.flatten() | ||
) | ||
} | ||
|
||
remove (cids, callback) { | ||
this.bs.delete(cids, callback) | ||
} | ||
} | ||
|
||
function noop () {} | ||
|
||
module.exports = IPLDResolver |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's move this to the ipld organization as part of this effort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, it's already on the IPLD org, forgot to change the badges. Good catch :)