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

Commit f6c8dce

Browse files
committed
Merge pull request #19 from ipfs/feat/bitswap
Integration with bitswap
2 parents 0c6c8b0 + 435381c commit f6c8dce

File tree

5 files changed

+374
-279
lines changed

5 files changed

+374
-279
lines changed

API.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# API
2+
3+
```js
4+
const BlockService = require('ipfs-block-service')
5+
```
6+
7+
### `new BlockService(repo)`
8+
9+
Creates a new block service backed by [IPFS Repo][repo] `repo` for storage.
10+
11+
### `goOnline(bitswap)`
12+
13+
Add a bitswap instance that communicates with the network to retreive blocks
14+
that are not in the local store.
15+
16+
If the node is online all requests for blocks first check locally and
17+
afterwards ask the network for the blocks.
18+
19+
### `goOffline()`
20+
21+
Remove the bitswap instance and fall back to offline mode.
22+
23+
### `isOnline()`
24+
25+
Returns a `Boolean` indicating if the block service is online or not.
26+
27+
### `addBlock(block, callback(err))`
28+
29+
Asynchronously adds a block instance to the underlying repo.
30+
31+
### `addBlocks(blocks, callback(err))`
32+
33+
Asynchronously adds an array of block instances to the underlying repo.
34+
35+
*Does not guarantee atomicity.*
36+
37+
### `getBlock(multihash, callback(err, block))`
38+
39+
Asynchronously returns the block whose content multihash matches `multihash`.
40+
Returns an error (`err.code === 'ENOENT'`) if the block does not exist.
41+
42+
If the block could not be found, expect `err.code` to be `'ENOENT'`.
43+
44+
### `getBlocks(multihashes, callback(err, blocks))`
45+
46+
Asynchronously returns the blocks whose content multihashes match the array
47+
`multihashes`.
48+
49+
`blocks` is an object that maps each `multihash` to an object of the form
50+
51+
```js
52+
{
53+
err: Error
54+
block: Block
55+
}
56+
```
57+
58+
Expect `blocks[multihash].err.code === 'ENOENT'` and `blocks[multihash].block
59+
=== null` if a block did not exist.
60+
61+
*Does not guarantee atomicity.*
62+
63+
### `deleteBlock(multihash, callback(err))`
64+
65+
Asynchronously deletes the block from the store with content multihash matching
66+
`multihash`, if it exists.
67+
68+
### `bs.deleteBlocks(multihashes, callback(err))`
69+
70+
Asynchronously deletes all blocks from the store with content multihashes matching
71+
from the array `multihashes`.
72+
73+
*Does not guarantee atomicity.*
74+
75+
[multihash]: https://github.com/jbenet/js-multihash
76+
[repo]: https://github.com/ipfs/specs/tree/master/repo

README.md

+6-67
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ IPFS Block Service JavaScript Implementation
1717

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

2322
```markdown
2423
┌────────────────────┐
@@ -27,9 +26,9 @@ Exchange][bitswap] implementation to fetch blocks from the network.
2726
2827
┌─────┴─────┐
2928
▼ ▼
30-
┌─────────┐ ┌───────
31-
│IPFS Repo│ │Exchange
32-
└─────────┘ └───────
29+
┌─────────┐ ┌───────┐
30+
│IPFS Repo│ |Bitswap
31+
└─────────┘ └───────┘
3332
```
3433

3534
## Example
@@ -99,7 +98,7 @@ var BlockService = require('ipfs-block-service')
9998

10099
### Browser: `<script>` Tag
101100

102-
Loading this module through a script tag will make the `Unixfs` obj available in
101+
Loading this module through a script tag will make the `IpfsBlockService` obj available in
103102
the global namespace.
104103

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

111-
## API
112-
113-
```js
114-
const BlockService = require('ipfs-block-service')
115-
```
116-
117-
### var bs = new BlockService(repo[, exchange])
118-
119-
Creates a new block service backed by [IPFS Repo][repo] `repo` for storage, and
120-
[IPFS Exchange][bitswap] for retrieving blocks from the network. Providing an
121-
`exchange` is optional.
122-
123-
#### bs.addBlock(block, callback(err))
124-
125-
Asynchronously adds a block instance to the underlying repo.
126-
127-
#### bs.addBlocks(blocks, callback(err))
128-
129-
Asynchronously adds an array of block instances to the underlying repo.
130-
131-
*Does not guarantee atomicity.*
132-
133-
#### bs.getBlock(multihash, callback(err, block))
134-
135-
Asynchronously returns the block whose content multihash matches `multihash`.
136-
Returns an error (`err.code === 'ENOENT'`) if the block does not exist.
137-
138-
If the block could not be found, expect `err.code` to be `'ENOENT'`.
139-
140-
#### bs.getBlocks(multihashes, callback(err, blocks))
141-
142-
Asynchronously returns the blocks whose content multihashes match the array
143-
`multihashes`.
144-
145-
`blocks` is an object that maps each `multihash` to an object of the form
146-
147-
```js
148-
{
149-
err: Error
150-
block: Block
151-
}
152-
```
153-
154-
Expect `blocks[multihash].err.code === 'ENOENT'` and `blocks[multihash].block
155-
=== null` if a block did not exist.
156-
157-
*Does not guarantee atomicity.*
158-
159-
#### bs.deleteBlock(multihash, callback(err))
160-
161-
Asynchronously deletes the block from the store with content multihash matching
162-
`multihash`, if it exists.
163-
164-
#### bs.deleteBlocks(multihashes, callback(err))
165-
166-
Asynchronously deletes all blocks from the store with content multihashes matching
167-
from the array `multihashes`.
168-
169-
*Does not guarantee atomicity.*
110+
You can find the [API documentation here](API.md)
170111

171112
## License
172113

173114
MIT
174115

175116
[ipfs]: https://ipfs.io
176-
[repo]: https://github.com/ipfs/specs/tree/master/repo
177117
[bitswap]: https://github.com/ipfs/specs/tree/master/bitswap
178-
[multihash]: https://github.com/jbenet/js-multihash

src/block-service.js

-68
This file was deleted.

src/index.js

+105-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,107 @@
11
'use strict'
22

3-
exports = module.exports = require('./block-service.js')
3+
const async = require('async')
4+
5+
// BlockService is a hybrid block datastore. It stores data in a local
6+
// datastore and may retrieve data from a remote Exchange.
7+
// It uses an internal `datastore.Datastore` instance to store values.
8+
module.exports = class BlockService {
9+
constructor (ipfsRepo) {
10+
this._repo = ipfsRepo
11+
this._bitswap = null
12+
}
13+
14+
goOnline (bitswap) {
15+
this._bitswap = bitswap
16+
}
17+
18+
goOffline () {
19+
this._bitswap = null
20+
}
21+
22+
isOnline () {
23+
return this._bitswap != null
24+
}
25+
26+
addBlock (block, extension, callback) {
27+
if (this.isOnline()) {
28+
if (typeof extension === 'function') {
29+
callback = extension
30+
extension = undefined
31+
}
32+
33+
this._bitswap.hasBlock(block, callback)
34+
} else {
35+
this._repo.datastore.put(block, extension, callback)
36+
}
37+
}
38+
39+
addBlocks (blocks, callback) {
40+
if (!Array.isArray(blocks)) {
41+
return callback(new Error('expects an array of Blocks'))
42+
}
43+
44+
async.eachLimit(blocks, 100, (block, next) => {
45+
this.addBlock(block, next)
46+
}, callback)
47+
}
48+
49+
getBlock (key, extension, callback) {
50+
if (this.isOnline()) {
51+
if (typeof extension === 'function') {
52+
callback = extension
53+
extension = undefined
54+
}
55+
56+
this._bitswap.getBlock(key, callback)
57+
} else {
58+
this._repo.datastore.get(key, extension, callback)
59+
}
60+
}
61+
62+
getBlocks (multihashes, extension, callback) {
63+
if (typeof extension === 'function') {
64+
callback = extension
65+
extension = undefined
66+
}
67+
68+
if (!Array.isArray(multihashes)) {
69+
return callback(new Error('Invalid batch of multihashes'))
70+
}
71+
72+
var results = {}
73+
74+
async.eachLimit(multihashes, 100, (multihash, next) => {
75+
this.getBlock(multihash, extension, (err, block) => {
76+
results[multihash] = {
77+
err: err,
78+
block: block
79+
}
80+
next()
81+
})
82+
}, (err) => {
83+
callback(err, results)
84+
})
85+
}
86+
87+
deleteBlock (key, extension, callback) {
88+
this._repo.datastore.delete(key, extension, callback)
89+
}
90+
91+
deleteBlocks (multihashes, extension, callback) {
92+
if (typeof extension === 'function') {
93+
callback = extension
94+
extension = undefined
95+
}
96+
97+
if (!Array.isArray(multihashes)) {
98+
return callback(new Error('Invalid batch of multihashes'))
99+
}
100+
101+
async.eachLimit(multihashes, 100, (multihash, next) => {
102+
this.deleteBlock(multihash, extension, next)
103+
}, (err) => {
104+
callback(err)
105+
})
106+
}
107+
}

0 commit comments

Comments
 (0)