diff --git a/API.md b/API.md
deleted file mode 100644
index 60a7939..0000000
--- a/API.md
+++ /dev/null
@@ -1,67 +0,0 @@
-# API
-
-```js
-const BlockService = require('ipfs-block-service')
-```
-
-### `new BlockService(repo)`
-
-- `repo: Repo`
-
-Creates a new block service backed by [IPFS Repo][repo] `repo` for storage.
-
-### `goOnline(bitswap)`
-
-- `bitswap: Bitswap`
-
-Add a bitswap instance that communicates with the network to retreive blocks
-that are not in the local store.
-
-If the node is online all requests for blocks first check locally and
-afterwards ask the network for the blocks.
-
-### `goOffline()`
-
-Remove the bitswap instance and fall back to offline mode.
-
-### `isOnline()`
-
-Returns a `Boolean` indicating if the block service is online or not.
-
-### `put(block, callback)`
-
-- `block: Block`
-- `callback: Function`
-
-Asynchronously adds a block instance to the underlying repo.
-
-### `putStream()`
-
-Returns a through pull-stream, which `Block`s can be written to, and
-that emits the meta data about the written block.
-
-### `get(multihash [, extension], callback)`
-
-- `multihash: Multihash`
-- `extension: String`, defaults to 'data'
-- `callback: Function`
-
-Asynchronously returns the block whose content multihash matches `multihash`.
-
-### `getStream(multihash [, extension])`
-
-- `multihash: Multihash`
-- `extension: String`, defaults to 'data'
-
-Returns a source pull-stream, which emits the requested block.
-
-### `delete(multihashes, [, extension], callback)`
-
-- `multihashes: Multihash|[]Multihash`
-- `extension: String`, defaults to 'data'- `extension: String`, defaults to 'data'
-- `callback: Function`
-
-Deletes all blocks referenced by multihashes.
-
-[multihash]: https://github.com/multiformats/js-multihash
-[repo]: https://github.com/ipfs/specs/tree/master/repo
diff --git a/README.md b/README.md
index 98cff4a..6129403 100644
--- a/README.md
+++ b/README.md
@@ -72,14 +72,17 @@ var repo = new IPFSRepo('example', { stores: Store })
// create a block
const block = new Block('hello world')
console.log(block.data)
-console.log(block.key)
+console.log(block.key())
// create a service
const bs = new BlockService(repo)
// add the block, then retrieve it
-bs.put(block, function (err) {
- bs.get(block.key, function (err, b) {
+bs.put({
+ block: block,
+ cid: cid,
+}, function (err) {
+ bs.get(cid, function (err, b) {
console.log(block.data.toString() === b.data.toString())
})
})
@@ -118,10 +121,70 @@ the global namespace.
```
-You can find the [API documentation here](API.md)
+# API
-[ipfs]: https://ipfs.io
-[bitswap]: https://github.com/ipfs/specs/tree/master/bitswap
+```js
+const BlockService = require('ipfs-block-service')
+```
+
+### `new BlockService(repo)`
+
+- `repo: Repo`
+
+Creates a new block service backed by [IPFS Repo][repo] `repo` for storage.
+
+### `goOnline(bitswap)`
+
+- `bitswap: Bitswap`
+
+Add a bitswap instance that communicates with the network to retreive blocks
+that are not in the local store.
+
+If the node is online all requests for blocks first check locally and
+afterwards ask the network for the blocks.
+
+### `goOffline()`
+
+Remove the bitswap instance and fall back to offline mode.
+
+### `isOnline()`
+
+Returns a `Boolean` indicating if the block service is online or not.
+
+### `put(blockAndCID, callback)`
+
+- `blockAndCID: { block: block, cid: cid }`
+- `callback: Function`
+
+Asynchronously adds a block instance to the underlying repo.
+
+### `putStream()`
+
+Returns a through pull-stream, which `blockAndCID`s can be written to, and
+that emits the meta data about the written block.
+
+### `get(cid [, extension], callback)`
+
+- `cid: CID`
+- `extension: String`, defaults to 'data'
+- `callback: Function`
+
+Asynchronously returns the block whose content multihash matches `multihash`.
+
+### `getStream(cid [, extension])`
+
+- `cid: CID`
+- `extension: String`, defaults to 'data'
+
+Returns a source pull-stream, which emits the requested block.
+
+### `delete(cids, [, extension], callback)`
+
+- `cids: CID | []CID`
+- `extension: String`, defaults to 'data' - `extension: String`, defaults to 'data'
+- `callback: Function`
+
+Deletes all blocks referenced by multihashes.
## Contribute
@@ -134,3 +197,9 @@ This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/c
## License
[MIT](LICENSE)
+
+[ipfs]: https://ipfs.io
+[bitswap]: https://github.com/ipfs/specs/tree/master/bitswap
+[repo]: https://github.com/ipfs/specs/tree/master/repo
+
+
diff --git a/package.json b/package.json
index e603238..b41bf47 100644
--- a/package.json
+++ b/package.json
@@ -37,13 +37,13 @@
},
"homepage": "https://github.com/ipfs/js-ipfs-block-service#readme",
"devDependencies": {
- "aegir": "^8.0.0",
+ "aegir": "^8.1.2",
"buffer-loader": "0.0.1",
"chai": "^3.5.0",
"fs-pull-blob-store": "^0.3.0",
"idb-pull-blob-store": "^0.5.1",
- "ipfs-block": "^0.3.0",
- "ipfs-repo": "^0.9.0",
+ "ipfs-block": "^0.4.0",
+ "ipfs-repo": "^0.10.0",
"lodash": "^4.15.0",
"ncp": "^2.0.0",
"pre-commit": "^1.1.3",
@@ -51,6 +51,7 @@
"run-series": "^1.1.4"
},
"dependencies": {
+ "cids": "^0.2.0",
"pull-stream": "^3.4.5",
"run-parallel-limit": "^1.0.3"
},
@@ -60,4 +61,4 @@
"Richard Littauer ",
"Stephen Whitmore "
]
-}
\ No newline at end of file
+}
diff --git a/src/index.js b/src/index.js
index 5ee06b9..216121d 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,62 +24,73 @@ module.exports = class BlockService {
return this._bitswap != null
}
- put (block, callback) {
+ // Note: we have to pass the CID, so that bitswap can then use it for
+ // the smart selectors. For now, passing the CID is used so that we know
+ // the right multihash, this means that now we have multiple hashes official
+ // support \o/
+ put (blockAndCID, callback) {
callback = callback || (() => {})
- if (!block) {
- return callback(new Error('Missing block'))
+ if (!blockAndCID) {
+ return callback(new Error('Missing block and CID'))
}
pull(
- pull.values([block]),
+ pull.values([
+ blockAndCID
+ ]),
this.putStream(),
pull.onEnd(callback)
)
}
putStream () {
+ let ps
if (this.isOnline()) {
- return this._bitswap.putStream()
+ // NOTE: This will have to change in order for bitswap
+ // to understand CID
+ ps = this._bitswap.putStream()
+ } else {
+ ps = this._repo.blockstore.putStream()
}
- return this._repo.blockstore.putStream()
+ return pull(
+ pull.map((blockAndCID) => {
+ return {
+ data: blockAndCID.block.data,
+ key: blockAndCID.cid.multihash
+ }
+ }),
+ ps
+ )
}
- get (key, extension, callback) {
- if (typeof extension === 'function') {
- callback = extension
- extension = undefined
- }
-
+ get (cid, callback) {
pull(
- this.getStream(key, extension),
+ this.getStream(cid),
pull.collect((err, result) => {
- if (err) return callback(err)
+ if (err) {
+ return callback(err)
+ }
callback(null, result[0])
})
)
}
- getStream (key, extension) {
+ getStream (cid) {
if (this.isOnline()) {
- return this._bitswap.getStream(key)
+ return this._bitswap.getStream(cid.multihash)
}
- return this._repo.blockstore.getStream(key, extension)
+ return this._repo.blockstore.getStream(cid.multihash)
}
- delete (keys, extension, callback) {
- if (typeof extension === 'function') {
- callback = extension
- extension = undefined
- }
-
- if (!Array.isArray(keys)) {
- keys = [keys]
+ delete (cids, callback) {
+ if (!Array.isArray(cids)) {
+ cids = [cids]
}
- parallelLimit(keys.map((key) => (next) => {
- this._repo.blockstore.delete(key, extension, next)
+ parallelLimit(cids.map((cid) => (next) => {
+ this._repo.blockstore.delete(cid.multihash, next)
}), 100, callback)
}
}
diff --git a/test/block-service-test.js b/test/block-service-test.js
index 1b3f2f9..7e877a4 100644
--- a/test/block-service-test.js
+++ b/test/block-service-test.js
@@ -6,6 +6,7 @@ const Block = require('ipfs-block')
const pull = require('pull-stream')
const _ = require('lodash')
const series = require('run-series')
+const CID = require('cids')
const BlockService = require('../src')
@@ -20,25 +21,15 @@ module.exports = (repo) => {
describe('offline', () => {
it('store and get a block', (done) => {
const b = new Block('A random data block')
+ const cid = new CID(b.key())
series([
- (cb) => bs.put(b, cb),
- (cb) => bs.get(b.key, (err, block) => {
- if (err) return cb(err)
- expect(b).to.be.eql(block)
- cb()
- })
- ], done)
- })
-
- it('store and get a block, with custom extension', (done) => {
- const b = new Block('A random data block 2', 'ext')
-
- series([
- (cb) => bs.put(b, cb),
- (cb) => bs.get(b.key, 'ext', (err, block) => {
- if (err) return cb(err)
- expect(b).to.be.eql(block)
+ (cb) => bs.put({ block: b, cid: cid }, cb),
+ (cb) => bs.get(cid, (err, block) => {
+ if (err) {
+ return cb(err)
+ }
+ expect(b.key()).to.be.eql(block.key())
cb()
})
], done)
@@ -46,7 +37,9 @@ module.exports = (repo) => {
it('get a non existent block', (done) => {
const b = new Block('Not stored')
- bs.get(b.key, (err, block) => {
+ const cid = new CID(b.key())
+
+ bs.get(cid, (err, block) => {
expect(err).to.exist
done()
})
@@ -58,7 +51,11 @@ module.exports = (repo) => {
const b3 = new Block('3')
pull(
- pull.values([b1, b2, b3]),
+ pull.values([
+ { block: b1, cid: new CID(b1.key()) },
+ { block: b2, cid: new CID(b2.key()) },
+ { block: b3, cid: new CID(b3.key()) }
+ ]),
bs.putStream(),
pull.collect((err, meta) => {
expect(err).to.not.exist
@@ -68,20 +65,17 @@ module.exports = (repo) => {
)
})
- it('get: bad invocation', (done) => {
- bs.get(null, (err) => {
- expect(err).to.be.an('error')
- done()
- })
- })
-
it('get many blocks', (done) => {
const b1 = new Block('1')
const b2 = new Block('2')
const b3 = new Block('3')
pull(
- pull.values([b1, b2, b3]),
+ pull.values([
+ { block: b1, cid: new CID(b1.key()) },
+ { block: b2, cid: new CID(b2.key()) },
+ { block: b3, cid: new CID(b3.key()) }
+ ]),
bs.putStream(),
pull.onEnd((err) => {
expect(err).to.not.exist
@@ -91,13 +85,23 @@ module.exports = (repo) => {
function getAndAssert () {
pull(
- pull.values([b1.key, b2.key, b3.key]),
- pull.map((key) => bs.getStream(key)),
+ pull.values([
+ b1.key(),
+ b2.key(),
+ b3.key()
+ ]),
+ pull.map((key) => {
+ const cid = new CID(key)
+ return bs.getStream(cid)
+ }),
pull.flatten(),
pull.collect((err, blocks) => {
expect(err).to.not.exist
+ const bPutKeys = blocks.map((b) => {
+ return b.key()
+ })
- expect(blocks).to.be.eql([b1, b2, b3])
+ expect(bPutKeys).to.be.eql([b1.key(), b2.key(), b3.key()])
done()
})
)
@@ -106,32 +110,12 @@ module.exports = (repo) => {
it('delete a block', (done) => {
const b = new Block('Will not live that much')
- bs.put(b, (err) => {
+ bs.put({ block: b, cid: new CID(b.key()) }, (err) => {
expect(err).to.not.exist
- bs.delete(b.key, (err) => {
+ const cid = new CID(b.key())
+ bs.delete(cid, (err) => {
expect(err).to.not.exist
- bs.get(b.key, (err, block) => {
- expect(err).to.exist
- done()
- })
- })
- })
- })
-
- it('delete: bad invocation', (done) => {
- bs.delete(null, (err) => {
- expect(err).to.be.an('error')
- done()
- })
- })
-
- it('delete a block, with custom extension', (done) => {
- const b = new Block('Will not live that much', 'ext')
- bs.put(b, (err) => {
- expect(err).to.not.exist
- bs.delete(b.key, 'ext', (err) => {
- expect(err).to.not.exist
- bs.get(b.key, 'ext', (err, block) => {
+ bs.get(cid, (err, block) => {
expect(err).to.exist
done()
})
@@ -141,7 +125,8 @@ module.exports = (repo) => {
it('delete a non existent block', (done) => {
const b = new Block('I do not exist')
- bs.delete(b.key, (err) => {
+ const cid = new CID(b.key())
+ bs.delete(cid, (err) => {
expect(err).to.not.exist
done()
})
@@ -152,7 +137,11 @@ module.exports = (repo) => {
const b2 = new Block('2')
const b3 = new Block('3')
- bs.delete([b1, b2, b3], 'data', (err) => {
+ bs.delete([
+ new CID(b1.key()),
+ new CID(b2.key()),
+ new CID(b3.key())
+ ], (err) => {
expect(err).to.not.exist
done()
})
@@ -167,18 +156,26 @@ module.exports = (repo) => {
pull(
pull.values(blocks),
+ pull.map((block) => {
+ return { block: block, cid: new CID(block.key()) }
+ }),
bs.putStream(),
pull.onEnd((err) => {
expect(err).to.not.exist
pull(
pull.values(blocks),
- pull.map((b) => b.key),
- pull.map((key) => bs.getStream(key)),
+ pull.map((block) => {
+ return block.key()
+ }),
+ pull.map((key) => {
+ const cid = new CID(key)
+ return bs.getStream(cid)
+ }),
pull.flatten(),
- pull.collect((err, res) => {
+ pull.collect((err, retrievedBlocks) => {
expect(err).to.not.exist
- expect(res).to.be.eql(blocks)
+ expect(retrievedBlocks.length).to.be.eql(blocks.length)
done()
})
)
@@ -206,16 +203,23 @@ module.exports = (repo) => {
})
it('retrieves a block through bitswap', (done) => {
+ // returns a block with a value equal to its key
const bitswap = {
getStream (key) {
- return pull.values([new Block(key)])
+ return pull.values([
+ new Block('secret')
+ ])
}
}
+
bs.goOnline(bitswap)
- bs.get('secret', (err, res) => {
+ const block = new Block('secret')
+ const cid = new CID(block.key('sha2-256'))
+
+ bs.get(cid, (err, block) => {
expect(err).to.not.exist
- expect(res).to.be.eql(new Block('secret'))
+ expect(block.data).to.be.eql(new Block('secret').data)
done()
})
})
@@ -227,11 +231,18 @@ module.exports = (repo) => {
}
}
bs.goOnline(bitswap)
- bs.put(new Block('secret sauce'), done)
+
+ const block = new Block('secret sauce')
+
+ bs.put({
+ block: block,
+ cid: new CID(block.key('sha2-256'))
+ }, done)
})
it('getStream through bitswap', (done) => {
const b = new Block('secret sauce 1')
+ const cid = new CID(b.key('sha2-256'))
const bitswap = {
getStream () {
@@ -240,11 +251,13 @@ module.exports = (repo) => {
}
bs.goOnline(bitswap)
+
pull(
- bs.getStream(b.key),
- pull.collect((err, res) => {
+ bs.getStream(cid),
+ pull.collect((err, blocks) => {
expect(err).to.not.exist
- expect(res).to.be.eql([b])
+ expect(blocks[0].data).to.be.eql(b.data)
+ expect(blocks[0].key('sha2-256')).to.be.eql(cid.multihash)
done()
})
)