Skip to content

Commit

Permalink
feat: add in-memory blockstore implementation (#1)
Browse files Browse the repository at this point in the history
A simple blockstore that's good for testing.
  • Loading branch information
achingbrain committed Jun 25, 2021
1 parent 67d1667 commit ab37d40
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
1 change: 1 addition & 0 deletions packages/interface-blockstore/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"url": "git+https://github.com/ipfs/js-ipfs-interfaces.git"
},
"dependencies": {
"err-code": "^3.0.1",
"interface-store": "^0.0.2",
"it-all": "^1.0.5",
"it-drain": "^1.0.4",
Expand Down
15 changes: 15 additions & 0 deletions packages/interface-blockstore/src/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict'

const errCode = require('err-code')

/**
* @param {Error} [err]
*/
function notFoundError (err) {
err = err || new Error('Not Found')
return errCode(err, 'ERR_NOT_FOUND')
}

module.exports = {
notFoundError
}
4 changes: 3 additions & 1 deletion packages/interface-blockstore/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict'

const BlockstoreAdapter = require('./adapter')
const MemoryBlockstore = require('./memory')

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

module.exports = {
BlockstoreAdapter
BlockstoreAdapter,
MemoryBlockstore
}
78 changes: 78 additions & 0 deletions packages/interface-blockstore/src/memory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict'

const Adapter = require('./adapter')
const { base32 } = require('multiformats/bases/base32')
const raw = require('multiformats/codecs/raw')
const { CID } = require('multiformats/cid')
const Digest = require('multiformats/hashes/digest')
const Errors = require('./errors')

/**
* @typedef {import('./types').Pair} Pair
* @typedef {import('./types').Blockstore} Blockstore
* @typedef {import('interface-store').Options} Options
*/

/**
* @class MemoryBlockstore
* @implements {Blockstore}
*/
class MemoryBlockstore extends Adapter {
constructor () {
super()

/** @type {Record<string, Uint8Array>} */
this.data = {}
}

open () {
return Promise.resolve()
}

close () {
return Promise.resolve()
}

/**
* @param {CID} key
* @param {Uint8Array} val
*/
async put (key, val) { // eslint-disable-line require-await
this.data[base32.encode(key.multihash.bytes)] = val
}

/**
* @param {CID} key
*/
async get (key) {
const exists = await this.has(key)
if (!exists) throw Errors.notFoundError()
return this.data[base32.encode(key.multihash.bytes)]
}

/**
* @param {CID} key
*/
async has (key) { // eslint-disable-line require-await
return this.data[base32.encode(key.multihash.bytes)] !== undefined
}

/**
* @param {CID} key
*/
async delete (key) { // eslint-disable-line require-await
delete this.data[base32.encode(key.multihash.bytes)]
}

async * _all () {
yield * Object.entries(this.data)
.map(([key, value]) => ({ key: CID.createV1(raw.code, Digest.decode(base32.decode(key))), value }))
}

async * _allKeys () {
yield * Object.entries(this.data)
.map(([key]) => CID.createV1(raw.code, Digest.decode(base32.decode(key))))
}
}

module.exports = MemoryBlockstore

0 comments on commit ab37d40

Please sign in to comment.