Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.

Commit fc98c00

Browse files
authored
Merge pull request #60 from ipld/awesome-ipld
Awesome IPLD endeavour
2 parents e9155df + 7978fd6 commit fc98c00

14 files changed

+779
-672
lines changed

README.md

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,100 +1,82 @@
1-
# IPFS IPLD
1+
# IPLD Resolver
22

33
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io)
44
[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)
55
[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs)
6+
[![Coverage Status](https://coveralls.io/repos/github/ipld/js-ipld-resolver/badge.svg?branch=master)](https://coveralls.io/github/ipld/js-ipld-resolver?branch=master)
7+
[![Travis CI](https://travis-ci.org/ipld/js-ipld-resolver.svg?branch=master)](https://travis-ci.org/ipld/js-ipld-resolver)
8+
[![Circle CI](https://circleci.com/gh/ipld/js-ipld-resolver.svg?style=svg)](https://circleci.com/gh/ipld/js-ipld-resolver)
9+
[![Dependency Status](https://david-dm.org/ipld/js-ipld-resolver.svg?style=flat-square)](https://david-dm.org/ipld/js-ipld-resolver)
10+
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
611
[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)
7-
[![Coverage Status](https://coveralls.io/repos/github/ipfs/js-ipfs-ipld/badge.svg?branch=master)](https://coveralls.io/github/ipfs/js-ipfs-ipld?branch=master)
8-
[![Travis CI](https://travis-ci.org/ipfs/js-ipfs-ipld.svg?branch=master)](https://travis-ci.org/ipfs/js-ipfs-ipld)
9-
[![Circle CI](https://circleci.com/gh/ipfs/js-ipfs-ipld.svg?style=svg)](https://circleci.com/gh/ipfs/js-ipfs-ipld)
10-
[![Dependency Status](https://david-dm.org/ipfs/js-ipfs-ipld.svg?style=flat-square)](https://david-dm.org/ipfs/js-ipfs-ipld) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
1112

12-
> JavaScript implementation of the IPLDService
13+
> JavaScript implementation of the IPLD Resolver
1314
1415
## Table of Contents
1516

16-
* [Install](#install)
17-
* [Usage](#usage)
18-
* [API](#api)
19-
+ [`resolve`](#resolve)
20-
+ [IPLDService](#ipldservice)
17+
- [Install](#install)
18+
- [Usage](#usage)
19+
- [API](#api)
20+
- [IPLD Resolver](#ipldresolver)
2121
- [`.put(node, cb)`](#putnode-cb)
2222
- [`.putStream([cb])`](#putstreamcb)
23-
- [`.get(multihash, cb)`](#getmultihash-cb)
24-
- [`.getStream(multihash)`](#getstreammultihash)
25-
- [`.getRecursive(multihash, cb)`](#getrecursivemultihash-cb)
26-
- [`.getRecursiveStream(multihash)`](#getrecursivestreammultihash)
27-
- [`.remove(multihash, cb)`](#removemultihash-cb)
28-
* [Contribute](#contribute)
29-
* [License](#license)
23+
- [`.get(cid, cb)`](#getcid-cb)
24+
- [`.getStream(cid)`](#getstreamcid)
25+
- [`.remove(cid, cb)`](#removecid-cb)
26+
- [Contribute](#contribute)
27+
- [License](#license)
3028

3129
## Install
3230

3331
```bash
34-
npm install --save ipfs-ipld
32+
> npm install --save ipfs-ipld
3533
```
3634

3735
## Usage
3836

3937
```js
40-
const ipfsIPLD = require('ipfs-ipld')
38+
const IPLDResolver = require('ipld-resolver')
4139

42-
// available components
43-
ipfsIPLD.IPLDService
44-
ipfsIPLD.resolve
40+
// pass an optional blockService, if no blockService is passed,
41+
// one is created in memory.
42+
const ipldResolver = new IPLDResolver(blockService)
4543
```
4644

4745
## API
4846

49-
### `resolve`
47+
### IPLD Resolver
5048

51-
> Resolve IPLD paths against a given IPLDService
52-
53-
```js
54-
const node = {
55-
hello: {
56-
world: 11,
57-
some: 12
58-
}
59-
}
60-
const mh = ipld.multihash(ipld.marshal(node))
61-
ipldService.put(node, (err) => {
62-
resolve(ipldService, `${mh}/hello/world`, (err, res) => {
63-
console.log(res)
64-
// => 11
65-
})
66-
```
67-
68-
### IPLDService
69-
70-
#### `.put(node, cb)`
49+
#### `.put(node, callback)`
7150

7251
> Store the given node (any JavaScript object).
7352
74-
#### `.putStream([cb])`
53+
#### `.putStream([callback])`
7554

7655
Returns a sink pull-stream, to write IPLD objects to.
7756

78-
#### `.get(multihash, cb)`
57+
#### `.get(cid, callback)`
7958

8059
> Retrieve a node by the given `multihash`.
8160
82-
#### `.getStream(multihash)`
61+
#### `.getStream(cid)`
8362

8463
Returns a source pull-stream of the requested IPLD object.
8564

86-
#### `.getRecursive(multihash, cb)`
65+
#### `.remove(cid, callback)`
8766

88-
> Retrieve a node by the given `multihash` and all linked nodes.
67+
> Remove a node by the given `multihash`
8968
90-
#### `.getRecursiveStream(multihash)`
69+
#### `.resolve(cid, path, callback)`
9170

92-
Returns a source pull-stream, which emits the requested node, and
93-
all linked nodes.
71+
> Resolves an IPLD path
9472
95-
#### `.remove(multihash, cb)`
73+
#### `.support.add(multicodec, formatResolver, formatUtil)`
9674

97-
> Remove a node by the given `multihash`
75+
> Add support to another IPLD Format
76+
77+
#### `.support.rm(multicodec)`
78+
79+
> Removes support of an IPLD Format
9880
9981
## Contribute
10082

package.json

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "ipfs-ipld",
3-
"version": "3.0.0",
4-
"description": "IPLD implementation in JavaScript",
2+
"name": "ipld-resolver",
3+
"version": "0.0.0",
4+
"description": "IPLD Resolver Implementation in JavaScript",
55
"main": "lib/index.js",
66
"jsnext:main": "src/index.js",
77
"pre-commit": [
@@ -34,23 +34,27 @@
3434
"homepage": "https://github.com/ipfs/js-ipfs-ipld#readme",
3535
"license": "MIT",
3636
"devDependencies": {
37-
"aegir": "^8.0.1",
37+
"aegir": "^8.1.2",
3838
"async": "^2.0.1",
3939
"buffer-loader": "0.0.1",
4040
"chai": "^3.5.0",
4141
"fs-pull-blob-store": "^0.3.0",
42-
"idb-pull-blob-store": "^0.4.0",
43-
"ipfs-block-service": "^0.5.0",
44-
"ipfs-repo": "^0.9.0",
42+
"idb-pull-blob-store": "^0.5.1",
43+
"ipfs-block-service": "^0.6.0",
44+
"ipfs-repo": "^0.10.0",
4545
"lodash": "^4.15.0",
4646
"ncp": "^2.0.0",
4747
"pre-commit": "^1.1.3",
4848
"rimraf": "^2.5.4"
4949
},
5050
"dependencies": {
51+
"async": "^2.1.1",
5152
"babel-runtime": "^6.11.6",
52-
"ipfs-block": "^0.3.0",
53-
"ipld": "^0.6.0",
53+
"cids": "^0.2.0",
54+
"interface-pull-blob-store": "^0.5.0",
55+
"ipfs-block": "^0.4.0",
56+
"ipld-dag-cbor": "^0.7.0",
57+
"ipld-dag-pb": "^0.1.0",
5458
"is-ipfs": "^0.2.0",
5559
"lodash.flatten": "^4.4.0",
5660
"lodash.includes": "^4.3.0",
@@ -64,4 +68,4 @@
6468
"greenkeeperio-bot <[email protected]>",
6569
"nicola <[email protected]>"
6670
]
67-
}
71+
}

src/index.js

Lines changed: 166 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,168 @@
11
'use strict'
22

3-
exports.IPLDService = require('./ipld-service')
4-
exports.resolve = require('./resolve')
3+
const Block = require('ipfs-block')
4+
const pull = require('pull-stream')
5+
const CID = require('cids')
6+
const until = require('async/until')
7+
const IPFSRepo = require('ipfs-repo')
8+
const MemoryStore = require('../node_modules/interface-pull-blob-store/lib/reference.js')
9+
const BlockService = require('ipfs-block-service')
10+
11+
const dagPB = require('ipld-dag-pb')
12+
const dagCBOR = require('ipld-dag-cbor')
13+
14+
class IPLDResolver {
15+
constructor (blockService) {
16+
// nicola will love this!
17+
if (!blockService) {
18+
const repo = new IPFSRepo('in-memory', { stores: MemoryStore })
19+
blockService = new BlockService(repo)
20+
}
21+
22+
this.bs = blockService
23+
this.resolvers = {}
24+
25+
this.support = {}
26+
27+
// Adds support for an IPLD format
28+
this.support.add = (multicodec, resolver, util) => {
29+
if (this.resolvers[multicodec]) {
30+
throw new Error(multicodec + 'already supported')
31+
}
32+
33+
this.resolvers[multicodec] = {
34+
resolver: resolver,
35+
util: util
36+
}
37+
}
38+
39+
this.support.rm = (multicodec) => {
40+
if (this.resolvers[multicodec]) {
41+
delete this.resolvers[multicodec]
42+
}
43+
}
44+
45+
// Support by default dag-pb and dag-cbor
46+
this.support.add(dagPB.resolver.multicodec, dagPB.resolver, dagPB.util)
47+
this.support.add(dagCBOR.resolver.multicodec, dagCBOR.resolver, dagCBOR.util)
48+
}
49+
50+
resolve (cid, path, callback) {
51+
if (path === '/') {
52+
return this.get(cid, callback)
53+
}
54+
55+
let value
56+
57+
until(
58+
() => {
59+
if (!path || path === '' || path === '/') {
60+
return true
61+
} else {
62+
// continue traversing
63+
if (value) {
64+
cid = new CID(value['/'])
65+
}
66+
return false
67+
}
68+
},
69+
(cb) => {
70+
// get block
71+
// use local resolver
72+
// update path value
73+
this.bs.get(cid, (err, block) => {
74+
if (err) {
75+
return cb(err)
76+
}
77+
const r = this.resolvers[cid.codec]
78+
r.resolver.resolve(block, path, (err, result) => {
79+
if (err) {
80+
return cb(err)
81+
}
82+
value = result.value
83+
path = result.remainderPath
84+
cb()
85+
})
86+
})
87+
},
88+
(err, results) => {
89+
if (err) {
90+
return callback(err)
91+
}
92+
return callback(null, value)
93+
}
94+
)
95+
}
96+
97+
// Node operations (get and retrieve nodes, not values)
98+
99+
put (nodeAndCID, callback) {
100+
callback = callback || noop
101+
pull(
102+
pull.values([nodeAndCID]),
103+
this.putStream(callback)
104+
)
105+
}
106+
107+
putStream (callback) {
108+
callback = callback || noop
109+
110+
return pull(
111+
pull.asyncMap((nodeAndCID, cb) => {
112+
const cid = nodeAndCID.cid
113+
const r = this.resolvers[cid.codec]
114+
115+
r.util.serialize(nodeAndCID.node, (err, serialized) => {
116+
if (err) {
117+
return cb(err)
118+
}
119+
cb(null, {
120+
block: new Block(serialized),
121+
cid: cid
122+
})
123+
})
124+
}),
125+
this.bs.putStream(),
126+
pull.onEnd(callback)
127+
)
128+
}
129+
130+
get (cid, callback) {
131+
pull(
132+
this.getStream(cid),
133+
pull.collect((err, res) => {
134+
if (err) {
135+
return callback(err)
136+
}
137+
callback(null, res[0])
138+
})
139+
)
140+
}
141+
142+
getStream (cid) {
143+
return pull(
144+
this.bs.getStream(cid),
145+
pull.asyncMap((block, cb) => {
146+
const r = this.resolvers[cid.codec]
147+
if (r) {
148+
r.util.deserialize(block.data, (err, deserialized) => {
149+
if (err) {
150+
return cb(err)
151+
}
152+
cb(null, deserialized)
153+
})
154+
} else { // multicodec unknown, send back raw data
155+
cb(null, block.data)
156+
}
157+
})
158+
)
159+
}
160+
161+
remove (cids, callback) {
162+
this.bs.delete(cids, callback)
163+
}
164+
}
165+
166+
function noop () {}
167+
168+
module.exports = IPLDResolver

0 commit comments

Comments
 (0)