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

Commit

Permalink
Merge pull request #19 from ipfs/feat/bitswap
Browse files Browse the repository at this point in the history
Integration with bitswap
  • Loading branch information
daviddias committed May 7, 2016
2 parents 0c6c8b0 + 435381c commit f6c8dce
Show file tree
Hide file tree
Showing 5 changed files with 374 additions and 279 deletions.
76 changes: 76 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# API

```js
const BlockService = require('ipfs-block-service')
```

### `new BlockService(repo)`

Creates a new block service backed by [IPFS Repo][repo] `repo` for storage.

### `goOnline(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.

### `addBlock(block, callback(err))`

Asynchronously adds a block instance to the underlying repo.

### `addBlocks(blocks, callback(err))`

Asynchronously adds an array of block instances to the underlying repo.

*Does not guarantee atomicity.*

### `getBlock(multihash, callback(err, block))`

Asynchronously returns the block whose content multihash matches `multihash`.
Returns an error (`err.code === 'ENOENT'`) if the block does not exist.

If the block could not be found, expect `err.code` to be `'ENOENT'`.

### `getBlocks(multihashes, callback(err, blocks))`

Asynchronously returns the blocks whose content multihashes match the array
`multihashes`.

`blocks` is an object that maps each `multihash` to an object of the form

```js
{
err: Error
block: Block
}
```

Expect `blocks[multihash].err.code === 'ENOENT'` and `blocks[multihash].block
=== null` if a block did not exist.

*Does not guarantee atomicity.*

### `deleteBlock(multihash, callback(err))`

Asynchronously deletes the block from the store with content multihash matching
`multihash`, if it exists.

### `bs.deleteBlocks(multihashes, callback(err))`

Asynchronously deletes all blocks from the store with content multihashes matching
from the array `multihashes`.

*Does not guarantee atomicity.*

[multihash]: https://github.com/jbenet/js-multihash
[repo]: https://github.com/ipfs/specs/tree/master/repo
73 changes: 6 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ IPFS Block Service JavaScript Implementation

**BlockService** - A BlockService is a content-addressable store for blocks,
providing an API for adding, deleting, and retrieving blocks. A BlockService is
backed by an [IPFS Repo][repo] as its datastore for blocks, and uses an [IPFS
Exchange][bitswap] implementation to fetch blocks from the network.
backed by an [IPFS Repo][repo] as its datastore for blocks, and uses [Bitswap][bitswap] to fetch blocks from the network.

```markdown
┌────────────────────┐
Expand All @@ -27,9 +26,9 @@ Exchange][bitswap] implementation to fetch blocks from the network.
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌───────
│IPFS Repo│ │Exchange
└─────────┘ └───────
┌─────────┐ ┌───────┐
│IPFS Repo│ |Bitswap
└─────────┘ └───────┘
```

## Example
Expand Down Expand Up @@ -99,7 +98,7 @@ var BlockService = require('ipfs-block-service')

### Browser: `<script>` Tag

Loading this module through a script tag will make the `Unixfs` obj available in
Loading this module through a script tag will make the `IpfsBlockService` obj available in
the global namespace.

```html
Expand All @@ -108,71 +107,11 @@ the global namespace.
<script src="https://npmcdn.com/ipfs-block-service/dist/index.js"></script>
```

## API

```js
const BlockService = require('ipfs-block-service')
```

### var bs = new BlockService(repo[, exchange])

Creates a new block service backed by [IPFS Repo][repo] `repo` for storage, and
[IPFS Exchange][bitswap] for retrieving blocks from the network. Providing an
`exchange` is optional.

#### bs.addBlock(block, callback(err))

Asynchronously adds a block instance to the underlying repo.

#### bs.addBlocks(blocks, callback(err))

Asynchronously adds an array of block instances to the underlying repo.

*Does not guarantee atomicity.*

#### bs.getBlock(multihash, callback(err, block))

Asynchronously returns the block whose content multihash matches `multihash`.
Returns an error (`err.code === 'ENOENT'`) if the block does not exist.

If the block could not be found, expect `err.code` to be `'ENOENT'`.

#### bs.getBlocks(multihashes, callback(err, blocks))

Asynchronously returns the blocks whose content multihashes match the array
`multihashes`.

`blocks` is an object that maps each `multihash` to an object of the form

```js
{
err: Error
block: Block
}
```

Expect `blocks[multihash].err.code === 'ENOENT'` and `blocks[multihash].block
=== null` if a block did not exist.

*Does not guarantee atomicity.*

#### bs.deleteBlock(multihash, callback(err))

Asynchronously deletes the block from the store with content multihash matching
`multihash`, if it exists.

#### bs.deleteBlocks(multihashes, callback(err))

Asynchronously deletes all blocks from the store with content multihashes matching
from the array `multihashes`.

*Does not guarantee atomicity.*
You can find the [API documentation here](API.md)

## License

MIT

[ipfs]: https://ipfs.io
[repo]: https://github.com/ipfs/specs/tree/master/repo
[bitswap]: https://github.com/ipfs/specs/tree/master/bitswap
[multihash]: https://github.com/jbenet/js-multihash
68 changes: 0 additions & 68 deletions src/block-service.js

This file was deleted.

106 changes: 105 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
'use strict'

exports = module.exports = require('./block-service.js')
const async = require('async')

// BlockService is a hybrid block datastore. It stores data in a local
// datastore and may retrieve data from a remote Exchange.
// It uses an internal `datastore.Datastore` instance to store values.
module.exports = class BlockService {
constructor (ipfsRepo) {
this._repo = ipfsRepo
this._bitswap = null
}

goOnline (bitswap) {
this._bitswap = bitswap
}

goOffline () {
this._bitswap = null
}

isOnline () {
return this._bitswap != null
}

addBlock (block, extension, callback) {
if (this.isOnline()) {
if (typeof extension === 'function') {
callback = extension
extension = undefined
}

this._bitswap.hasBlock(block, callback)
} else {
this._repo.datastore.put(block, extension, callback)
}
}

addBlocks (blocks, callback) {
if (!Array.isArray(blocks)) {
return callback(new Error('expects an array of Blocks'))
}

async.eachLimit(blocks, 100, (block, next) => {
this.addBlock(block, next)
}, callback)
}

getBlock (key, extension, callback) {
if (this.isOnline()) {
if (typeof extension === 'function') {
callback = extension
extension = undefined
}

this._bitswap.getBlock(key, callback)
} else {
this._repo.datastore.get(key, extension, callback)
}
}

getBlocks (multihashes, extension, callback) {
if (typeof extension === 'function') {
callback = extension
extension = undefined
}

if (!Array.isArray(multihashes)) {
return callback(new Error('Invalid batch of multihashes'))
}

var results = {}

async.eachLimit(multihashes, 100, (multihash, next) => {
this.getBlock(multihash, extension, (err, block) => {
results[multihash] = {
err: err,
block: block
}
next()
})
}, (err) => {
callback(err, results)
})
}

deleteBlock (key, extension, callback) {
this._repo.datastore.delete(key, extension, callback)
}

deleteBlocks (multihashes, extension, callback) {
if (typeof extension === 'function') {
callback = extension
extension = undefined
}

if (!Array.isArray(multihashes)) {
return callback(new Error('Invalid batch of multihashes'))
}

async.eachLimit(multihashes, 100, (multihash, next) => {
this.deleteBlock(multihash, extension, next)
}, (err) => {
callback(err)
})
}
}
Loading

0 comments on commit f6c8dce

Please sign in to comment.