Skip to content
This repository was archived by the owner on Aug 11, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: add types
Adds types, fixes all tsc errors, updates all deps.

Depends on:

- [ ] ipld/js-ipld-block#58
  • Loading branch information
achingbrain committed Mar 5, 2021
commit 1c705f523ecf673d0f44b6914684d49fefabdb33
22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
"description": "JavaScript Implementation of BlockService",
"leadMaintainer": "Volker Mische <[email protected]>",
"main": "src/index.js",
"types": "dist/src/index.d.ts",
"scripts": {
"prepare": "aegir build --no-bundle",
"lint": "aegir lint",
"build": "aegir build",
"prepublishOnly": "aegir build",
"test": "aegir test",
"test:node": "aegir test --target node",
"test:browser": "aegir test --target browser",
"release": "aegir release --docs",
"release-minor": "aegir release --type minor --docs",
"release-major": "aegir release --type major --docs",
"coverage": "aegir coverage",
"coverage-publish": "aegir coverage --provider coveralls",
"coverage": "aegir test -t node --cov && nyc report --reporter=html",
"docs": "aegir docs"
},
"repository": {
Expand All @@ -30,14 +31,17 @@
},
"homepage": "https://github.com/ipfs/js-ipfs-block-service#readme",
"devDependencies": {
"@types/fs-extra": "^9.0.8",
"@types/lodash.range": "^3.2.6",
"abort-controller": "^3.0.0",
"aegir": "^22.0.0",
"aegir": "^31.0.4",
"cids": "^1.0.0",
"fs-extra": "^9.0.0",
"ipfs-repo": "^6.0.0",
"ipld-block": "^0.10.0",
"ipfs-repo": "^9.0.0",
"ipld-block": "ipld/js-ipld-block#fix/update-type-export",
"it-all": "^1.0.5",
"it-drain": "^1.0.1",
"lodash": "^4.17.11",
"lodash.range": "^3.2.0",
"multihashing-async": "^2.0.1",
"uint8arrays": "^2.1.2"
},
Expand All @@ -46,8 +50,8 @@
"npm": ">=3.0.0"
},
"dependencies": {
"err-code": "^2.0.0",
"streaming-iterables": "^5.0.2"
"err-code": "^3.0.1",
"it-map": "^1.0.5"
},
"contributors": [
"David Dias <[email protected]>",
Expand Down
44 changes: 21 additions & 23 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
'use strict'

const { map } = require('streaming-iterables')
const map = require('it-map')
const errcode = require('err-code')

/**
* @typedef {import('ipfs-repo')} IPFSRepo
* @typedef {import('ipld-block')} Block
* @typedef {import('cids')} CID
*/

/**
* BlockService is a hybrid block datastore. It stores data in a local
* datastore and may retrieve data from a remote Exchange.
Expand All @@ -26,26 +32,21 @@ class BlockService {
* If the node is online all requests for blocks first
* check locally and afterwards ask the network for the blocks.
*
* @param {Bitswap} bitswap
* @returns {void}
* @param {any} bitswap
*/
setExchange (bitswap) {
this._bitswap = bitswap
}

/**
* Go offline, i.e. drop the reference to bitswap.
*
* @returns {void}
*/
unsetExchange () {
this._bitswap = null
}

/**
* Is the blockservice online, i.e. is bitswap present.
*
* @returns {bool}
*/
hasExchange () {
return this._bitswap != null
Expand All @@ -55,9 +56,9 @@ class BlockService {
* Put a block to the underlying datastore.
*
* @param {Block} block
* @param {Object} [options] - Options is an object with the following properties
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
* @returns {Promise<Block>}
*/
put (block, options) {
if (this.hasExchange()) {
Expand All @@ -70,10 +71,10 @@ class BlockService {
/**
* Put a multiple blocks to the underlying datastore.
*
* @param {AsyncIterator<Block>} blocks
* @param {Object} [options] - Options is an object with the following properties
* @param {AsyncIterable<Block> | Iterable<Block>} blocks
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
* @returns {AsyncIterable<Block>}
*/
putMany (blocks, options) {
if (this.hasExchange()) {
Expand All @@ -87,7 +88,7 @@ class BlockService {
* Get a block by cid.
*
* @param {CID} cid
* @param {Object} [options] - Options is an object with the following properties
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise<Block>}
*/
Expand All @@ -102,10 +103,10 @@ class BlockService {
/**
* Get multiple blocks back from an array of cids.
*
* @param {AsyncIterator<CID>} cids
* @param {Object} [options] - Options is an object with the following properties
* @param {AsyncIterable<CID> | Iterable<CID>} cids
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {AsyncIterator<Block>}
* @returns {AsyncIterable<Block>}
*/
getMany (cids, options) {
if (!Array.isArray(cids)) {
Expand All @@ -115,18 +116,16 @@ class BlockService {
if (this.hasExchange()) {
return this._bitswap.getMany(cids, options)
} else {
const getRepoBlocks = map((cid) => this._repo.blocks.get(cid, options))
return getRepoBlocks(cids)
return map(cids, (cid) => this._repo.blocks.get(cid, options))
}
}

/**
* Delete a block from the blockstore.
*
* @param {CID} cid
* @param {Object} [options] - Options is an object with the following properties
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
*/
async delete (cid, options) {
if (!await this._repo.blocks.has(cid)) {
Expand All @@ -139,10 +138,9 @@ class BlockService {
/**
* Delete multiple blocks from the blockstore.
*
* @param {AsyncIterator<CID>} cids
* @param {Object} [options] - Options is an object with the following properties
* @param {AsyncIterable<CID> | Iterable<CID>} cids
* @param {object} [options] - Options is an object with the following properties
* @param {AbortSignal} [options.signal] - A signal that can be used to abort any long-lived operations that are started as a result of this operation
* @returns {Promise}
*/
deleteMany (cids, options) {
const repo = this._repo
Expand Down
25 changes: 21 additions & 4 deletions test/aborting-requests.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@

const { expect } = require('aegir/utils/chai')

const { collect } = require('streaming-iterables')
const AbortController = require('abort-controller')
const all = require('it-all')
const { AbortController } = require('abort-controller')

const BlockService = require('../src')

/**
* @typedef {import('ipfs-repo')} IPFSRepo
*/

describe('aborting requests', () => {
/** @type {Error} */
let abortedErr
/** @type {BlockService} */
let r

beforeEach(() => {
abortedErr = new Error('Aborted!')
/**
* @param {...any} args
*/
const abortOnSignal = (...args) => {
const { signal } = args[args.length - 1]

Expand All @@ -24,14 +33,17 @@ describe('aborting requests', () => {
})
}

/** @type {IPFSRepo} */
const repo = {
blocks: {
put: abortOnSignal,
// @ts-ignore should return async iterable
putMany: abortOnSignal,
get: abortOnSignal,
delete: abortOnSignal,
// @ts-ignore should return async iterable
deleteMany: abortOnSignal,
has: () => true
has: () => Promise.resolve(true)
}
}
r = new BlockService(repo)
Expand All @@ -41,6 +53,7 @@ describe('aborting requests', () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

// @ts-expect-error does not take string
await expect(r.put('block', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
Expand All @@ -50,6 +63,7 @@ describe('aborting requests', () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

// @ts-expect-error does not take string array
await expect(r.putMany(['block'], {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
Expand All @@ -59,6 +73,7 @@ describe('aborting requests', () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

// @ts-expect-error does not take string
await expect(r.get('cid', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
Expand All @@ -68,7 +83,8 @@ describe('aborting requests', () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

await expect(collect(r.getMany(['cid'], {
// @ts-expect-error does not take string array
await expect(all(r.getMany(['cid'], {
signal: controller.signal
}))).to.eventually.rejectedWith(abortedErr)
})
Expand All @@ -77,6 +93,7 @@ describe('aborting requests', () => {
const controller = new AbortController()
setTimeout(() => controller.abort(), 1)

// @ts-expect-error does not take string
await expect(r.delete('cid', {
signal: controller.signal
})).to.eventually.rejectedWith(abortedErr)
Expand Down
24 changes: 20 additions & 4 deletions test/block-service-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@
const { expect } = require('aegir/utils/chai')

const Block = require('ipld-block')
const _ = require('lodash')
const { collect } = require('streaming-iterables')
const range = require('lodash.range')
const all = require('it-all')
const CID = require('cids')
const multihashing = require('multihashing-async')
const uint8ArrayFromString = require('uint8arrays/from-string')
const drain = require('it-drain')

/**
* @typedef {import('ipfs-repo')} IPFSRepo
*/

const BlockService = require('../src')

/**
* @param {IPFSRepo} repo
*/
module.exports = (repo) => {
describe('block-service', () => {
/** @type {BlockService} */
let bs
/** @type {Block[]} */
let testBlocks

before(async () => {
Expand Down Expand Up @@ -72,7 +81,7 @@ module.exports = (repo) => {

it('get many blocks through .getMany', async () => {
const cids = testBlocks.map(b => b.cid)
const blocks = await collect(bs.getMany(cids))
const blocks = await all(bs.getMany(cids))
expect(blocks).to.eql(testBlocks)
})

Expand Down Expand Up @@ -121,7 +130,7 @@ module.exports = (repo) => {
it('stores and gets lots of blocks', async function () {
this.timeout(20 * 1000)

const data = _.range(1000).map((i) => {
const data = range(1000).map((i) => {
return uint8ArrayFromString(`hello-${i}-${Math.random()}`)
})

Expand Down Expand Up @@ -158,6 +167,9 @@ module.exports = (repo) => {
it('retrieves a block through bitswap', async () => {
// returns a block with a value equal to its key
const bitswap = {
/**
* @param {CID} cid
*/
get (cid) {
return new Block(uint8ArrayFromString('secret'), cid)
}
Expand All @@ -174,8 +186,12 @@ module.exports = (repo) => {
})

it('puts the block through bitswap', async () => {
/** @type {Block[]} */
const puts = []
const bitswap = {
/**
* @param {Block} block
*/
put (block) {
puts.push(block)
}
Expand Down
3 changes: 3 additions & 0 deletions test/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ const IPFSRepo = require('ipfs-repo')
const tests = require('./block-service-test')

const idb = self.indexedDB ||
// @ts-ignore
self.mozIndexedDB ||
// @ts-ignore
self.webkitIndexedDB ||
// @ts-ignore
self.msIndexedDB

idb.deleteDatabase('ipfs')
Expand Down
10 changes: 10 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./node_modules/aegir/src/config/tsconfig.aegir.json",
"compilerOptions": {
"outDir": "dist"
},
"include": [
"test",
"src"
]
}