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

feat: add types #136

Merged
merged 4 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 15 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,40 +1,51 @@
language: node_js
dist: bionic
cache: npm
stages:
- check
- test
- cov

branches:
only:
- master
- /^release\/.*$/

node_js:
- '10'
- 'lts/*'
- 'node'

os:
- linux
- osx
- windows

before_install:
# modules with pre-built binaries may not have deployed versions for bleeding-edge node so this lets us fall back to building from source
- npm install -g @mapbox/node-pre-gyp

script: npx nyc -s npm run test:node -- --bail
after_success: npx nyc report --reporter=text-lcov > coverage.lcov && npx codecov

jobs:
include:
- stage: check
script:
- npx aegir commitlint --travis
- npx aegir dep-check
- npm run lint

- stage: test
name: chrome
addons:
chrome: stable
script: npx aegir test -t browser -t webworker
script:
- npx aegir test -t browser -t webworker

- stage: test
name: firefox
addons:
firefox: latest
script: npx aegir test -t browser -t webworker -- --browsers FirefoxHeadless
script: npx aegir test -t browser -t webworker -- --browser firefox

notifications:
email: false
28 changes: 18 additions & 10 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 <volker.mische@gmail.com>",
"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,24 +31,31 @@
},
"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",
"assert": "^2.0.0",
"cids": "^1.0.0",
"events": "^3.3.0",
"fs-extra": "^9.0.0",
"ipfs-repo": "^6.0.0",
"ipld-block": "^0.10.0",
"ipfs-repo": "^9.0.0",
"ipld-block": "^0.11.1",
"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"
"native-abort-controller": "^1.0.3",
"uint8arrays": "^2.1.2",
"util": "^0.12.3"
},
"engines": {
"node": ">=12.0.0",
"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 <daviddias.p@gmail.com>",
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('native-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
Loading