Skip to content

Commit ab37d40

Browse files
authored
feat: add in-memory blockstore implementation (#1)
A simple blockstore that's good for testing.
1 parent 67d1667 commit ab37d40

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

packages/interface-blockstore/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"url": "git+https://github.com/ipfs/js-ipfs-interfaces.git"
1818
},
1919
"dependencies": {
20+
"err-code": "^3.0.1",
2021
"interface-store": "^0.0.2",
2122
"it-all": "^1.0.5",
2223
"it-drain": "^1.0.4",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict'
2+
3+
const errCode = require('err-code')
4+
5+
/**
6+
* @param {Error} [err]
7+
*/
8+
function notFoundError (err) {
9+
err = err || new Error('Not Found')
10+
return errCode(err, 'ERR_NOT_FOUND')
11+
}
12+
13+
module.exports = {
14+
notFoundError
15+
}

packages/interface-blockstore/src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const BlockstoreAdapter = require('./adapter')
4+
const MemoryBlockstore = require('./memory')
45

56
/**
67
* @typedef {import('./types').Options} Options
@@ -16,5 +17,6 @@ const BlockstoreAdapter = require('./adapter')
1617
*/
1718

1819
module.exports = {
19-
BlockstoreAdapter
20+
BlockstoreAdapter,
21+
MemoryBlockstore
2022
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
'use strict'
2+
3+
const Adapter = require('./adapter')
4+
const { base32 } = require('multiformats/bases/base32')
5+
const raw = require('multiformats/codecs/raw')
6+
const { CID } = require('multiformats/cid')
7+
const Digest = require('multiformats/hashes/digest')
8+
const Errors = require('./errors')
9+
10+
/**
11+
* @typedef {import('./types').Pair} Pair
12+
* @typedef {import('./types').Blockstore} Blockstore
13+
* @typedef {import('interface-store').Options} Options
14+
*/
15+
16+
/**
17+
* @class MemoryBlockstore
18+
* @implements {Blockstore}
19+
*/
20+
class MemoryBlockstore extends Adapter {
21+
constructor () {
22+
super()
23+
24+
/** @type {Record<string, Uint8Array>} */
25+
this.data = {}
26+
}
27+
28+
open () {
29+
return Promise.resolve()
30+
}
31+
32+
close () {
33+
return Promise.resolve()
34+
}
35+
36+
/**
37+
* @param {CID} key
38+
* @param {Uint8Array} val
39+
*/
40+
async put (key, val) { // eslint-disable-line require-await
41+
this.data[base32.encode(key.multihash.bytes)] = val
42+
}
43+
44+
/**
45+
* @param {CID} key
46+
*/
47+
async get (key) {
48+
const exists = await this.has(key)
49+
if (!exists) throw Errors.notFoundError()
50+
return this.data[base32.encode(key.multihash.bytes)]
51+
}
52+
53+
/**
54+
* @param {CID} key
55+
*/
56+
async has (key) { // eslint-disable-line require-await
57+
return this.data[base32.encode(key.multihash.bytes)] !== undefined
58+
}
59+
60+
/**
61+
* @param {CID} key
62+
*/
63+
async delete (key) { // eslint-disable-line require-await
64+
delete this.data[base32.encode(key.multihash.bytes)]
65+
}
66+
67+
async * _all () {
68+
yield * Object.entries(this.data)
69+
.map(([key, value]) => ({ key: CID.createV1(raw.code, Digest.decode(base32.decode(key))), value }))
70+
}
71+
72+
async * _allKeys () {
73+
yield * Object.entries(this.data)
74+
.map(([key]) => CID.createV1(raw.code, Digest.decode(base32.decode(key))))
75+
}
76+
}
77+
78+
module.exports = MemoryBlockstore

0 commit comments

Comments
 (0)