diff --git a/.aegir.js b/.aegir.js
index bfbc3fde..a04eff0f 100644
--- a/.aegir.js
+++ b/.aegir.js
@@ -1,13 +1,32 @@
'use strict'
+const path = require('path')
-module.exports = {
- webpack: {
- node: {
- // this is needed until level stops using node buffers in browser code
- Buffer: true,
+/** @type {import('aegir').Options["build"]["config"]} */
+const esbuild = {
+ inject: [path.join(__dirname, 'scripts/node-globals.js')],
+ plugins: [
+ {
+ name: 'node built ins',
+ setup (build) {
+ build.onResolve({ filter: /^stream$/ }, () => {
+ return { path: require.resolve('readable-stream') }
+ })
+ }
+ }
+ ]
+}
- // needed by binary-parse-stream
- stream: true
+/** @type {import('aegir').PartialOptions} */
+module.exports = {
+ test: {
+ browser: {
+ config: {
+ buildConfig: esbuild
+ }
}
+ },
+ build: {
+ bundlesizeMax: '130kB',
+ config: esbuild
}
}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..8c9c0ed8
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,79 @@
+name: ci
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - run: npm install
+ - run: npx aegir lint
+ - run: npx aegir ts -p check
+ # or
+ # - uses: gozala/typescript-error-reporter-action@v1.0.8
+ - run: npx aegir build
+ - run: npx aegir dep-check
+ - uses: ipfs/aegir/actions/bundle-size@master
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ test-node:
+ needs: check
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [windows-latest, ubuntu-latest, macos-latest]
+ node: [14, 15]
+ fail-fast: true
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v1
+ with:
+ node-version: ${{ matrix.node }}
+ - run: npm install
+ - run: npx aegir test -t node --bail --cov
+ - uses: codecov/codecov-action@v1
+ test-chrome:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser -t webworker --bail # add --cov later when its fixed
+ - uses: codecov/codecov-action@v1
+ test-firefox:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser -t webworker --bail -- --browser firefox
+ test-webkit:
+ needs: check
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: microsoft/playwright-github-action@v1
+ - run: npm install
+ - run: npx aegir test -t browser -t webworker --bail --timeout 10000 -- --browser webkit
+ # test-electron-main:
+ # needs: check
+ # runs-on: ubuntu-latest
+ # steps:
+ # - uses: actions/checkout@v2
+ # - run: npm install
+ # - run: npx xvfb-maybe aegir test -t electron-main --bail
+ # test-electron-renderer:
+ # needs: check
+ # runs-on: ubuntu-latest
+ # steps:
+ # - uses: actions/checkout@v2
+ # - run: npm install
+ # - run: npx xvfb-maybe aegir test -t electron-renderer --bail
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index d7a46c52..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-language: node_js
-cache: npm
-stages:
- - check
- - test
- - cov
-
-branches:
- only:
- - master
- - /^release\/.*$/
-
-node_js:
- - 'lts/*'
- - 'node'
-
-os:
- - linux
- - osx
- - windows
-
-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 dep-check
- - npm run lint
-
- - stage: test
- name: chrome
- addons:
- chrome: stable
- script: npx aegir test -t browser
-
- - stage: test
- name: firefox
- addons:
- firefox: latest
- script: npx aegir test -t browser -- --browsers FirefoxHeadless
-
-notifications:
- email: false
-
diff --git a/README.md b/README.md
index 55f9d7ac..185a659d 100644
--- a/README.md
+++ b/README.md
@@ -7,8 +7,6 @@
[![Travis CI](https://flat.badgen.net/travis/ipfs/js-ipfs-repo)](https://travis-ci.com/ipfs/js-ipfs-repo)
[![codecov](https://codecov.io/gh/ipfs/js-ipfs-repo/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/js-ipfs-repo) [![Dependency Status](https://david-dm.org/ipfs/js-ipfs-repo.svg?style=flat-square)](https://david-dm.org/ipfs/js-ipfs-repo)
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/feross/standard)
-![](https://img.shields.io/badge/npm-%3E%3D6.0.0-orange.svg?style=flat-square)
-![](https://img.shields.io/badge/Node.js-%3E%3D10.0.0-orange.svg?style=flat-square)
> Implementation of the IPFS repo spec (https://github.com/ipfs/specs/blob/master/REPO.md) in JavaScript
@@ -137,8 +135,6 @@ Loading this module through a script tag will make the `IpfsRepo` obj available
```html
-
-
```
## Usage
diff --git a/example.js b/example.js
deleted file mode 100644
index b5e6d465..00000000
--- a/example.js
+++ /dev/null
@@ -1,11 +0,0 @@
-'use strict'
-
-const Repo = require('ipfs-repo');
-
-(async () => {
- const repo = new Repo('/Users/awesome/.jsipfs')
-
- await repo.init({ my: 'config' })
- await repo.open()
- console.log('repo is ready') // eslint-disable-line no-console
-})()
diff --git a/package.json b/package.json
index d8fb5f6e..3640905b 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"description": "IPFS Repo implementation",
"leadMaintainer": "Alex Potsides ",
"main": "src/index.js",
+ "types": "dist/src/index.d.ts",
"files": [
"src",
"dist"
@@ -15,16 +16,17 @@
"./src/default-options.js": "./src/default-options-browser.js"
},
"scripts": {
+ "prepare": "aegir build --no-bundle",
"test": "aegir test",
"test:node": "aegir test -t node",
"test:browser": "aegir test -t browser",
"test:webworker": "aegir test -t webworker",
"build": "aegir build",
"lint": "aegir lint",
- "release": "aegir release --docs",
- "release-minor": "aegir release --type minor --docs",
- "release-major": "aegir release --type major --docs",
- "coverage": "nyc -s npm run test:node && nyc report --reporter=html",
+ "release": "aegir release",
+ "release-minor": "aegir release --type minor",
+ "release-major": "aegir release --type major",
+ "coverage": "aegir test -t node --cov && nyc report --reporter=html",
"dep-check": "aegir dep-check",
"docs": "aegir docs"
},
@@ -39,43 +41,62 @@
],
"homepage": "https://github.com/ipfs/js-ipfs-repo",
"engines": {
- "node": ">=10.0.0",
- "npm": ">=3.0.0"
+ "node": ">=14.0.0",
+ "npm": ">=6.0.0"
},
"devDependencies": {
- "aegir": "^30.0.1",
+ "@types/bytes": "^3.1.0",
+ "@types/debug": "^4.1.5",
+ "@types/memdown": "^3.0.0",
+ "@types/ncp": "^2.0.4",
+ "@types/proper-lockfile": "^4.1.1",
+ "@types/rimraf": "^3.0.0",
+ "aegir": "^31.0.1",
+ "assert": "^2.0.0",
+ "events": "^3.3.0",
"it-all": "^1.0.2",
"it-drain": "^1.0.1",
"it-first": "^1.0.2",
"just-range": "^2.1.0",
"memdown": "^5.1.0",
- "multihashing-async": "^2.0.0",
+ "multihashing-async": "^2.1.0",
"ncp": "^2.0.0",
+ "process": "^0.11.10",
+ "readable-stream": "^3.6.0",
"rimraf": "^3.0.0",
- "sinon": "^9.0.2"
+ "sinon": "^9.0.2",
+ "url": "^0.11.0",
+ "util": "^0.12.3"
},
"dependencies": {
"bignumber.js": "^9.0.0",
"bytes": "^3.1.0",
- "cids": "^1.0.0",
+ "cids": "^1.1.6",
"datastore-core": "^3.0.0",
"datastore-fs": "^3.0.0",
"datastore-level": "^4.0.0",
"debug": "^4.1.0",
- "err-code": "^2.0.0",
+ "err-code": "^3.0.1",
"interface-datastore": "^3.0.3",
- "ipfs-repo-migrations": "^6.0.0",
+ "ipfs-repo-migrations": "^7.0.1",
"ipfs-utils": "^6.0.0",
"ipld-block": "^0.11.0",
"it-map": "^1.0.2",
"it-pushable": "^1.4.0",
"just-safe-get": "^2.0.0",
"just-safe-set": "^2.1.0",
- "multibase": "^3.0.0",
+ "merge-options": "^3.0.4",
+ "multibase": "^4.0.1",
"p-queue": "^6.0.0",
"proper-lockfile": "^4.0.0",
"sort-keys": "^4.0.0",
- "uint8arrays": "^2.0.5"
+ "uint8arrays": "^2.1.3"
+ },
+ "eslintConfig": {
+ "extends": "ipfs",
+ "ignorePatterns": [
+ "!.aegir.js"
+ ]
},
"license": "MIT",
"contributors": [
diff --git a/scripts/node-globals.js b/scripts/node-globals.js
new file mode 100644
index 00000000..d312b5a2
--- /dev/null
+++ b/scripts/node-globals.js
@@ -0,0 +1,3 @@
+// @ts-nocheck
+export const { Buffer } = require('buffer')
+export const process = require('process/browser')
\ No newline at end of file
diff --git a/src/api-addr.js b/src/api-addr.js
index 41df9d4c..db347aa9 100644
--- a/src/api-addr.js
+++ b/src/api-addr.js
@@ -5,6 +5,10 @@ const uint8ArrayFromString = require('uint8arrays/from-string')
const apiFile = new Key('api')
+/**
+ *
+ * @param {import("interface-datastore").Datastore} store
+ */
module.exports = (store) => {
return {
/**
@@ -18,19 +22,17 @@ module.exports = (store) => {
},
/**
* Set the current configuration for this repo.
+ * TODO: fix find the proper type or remove this API
*
- * @param {Object} value - the api address to be written
- * @returns {Promise>}
+ * @param {string} value - the api address to be written
*/
- async set (value) { // eslint-disable-line require-await
+ set (value) {
return store.put(apiFile, uint8ArrayFromString(value.toString()))
},
/**
* Deletes api file
- *
- * @returns {Promise}
*/
- async delete () { // eslint-disable-line require-await
+ delete () {
return store.delete(apiFile)
}
}
diff --git a/src/backends.js b/src/backends.js
index e607162a..26f6e77c 100644
--- a/src/backends.js
+++ b/src/backends.js
@@ -1,7 +1,25 @@
'use strict'
-exports.create = function createBackend (name, path, options) {
+/**
+ * @typedef {import("interface-datastore").Datastore} Datastore
+ * @typedef {import("./types").Backends} Backends
+ * @typedef {Required} Options
+ */
+
+/**
+ *
+ * @param {Backends} name
+ * @param {string} path
+ * @param {Options} options
+ * @returns {Datastore}
+ */
+function createBackend (name, path, options) {
const Ctor = options.storageBackends[name]
const backendOptions = Object.assign({}, options.storageBackendOptions[name] || {})
+ // @ts-ignore we don't have a signature for the constructor
return new Ctor(path, backendOptions)
}
+
+module.exports = {
+ create: createBackend
+}
diff --git a/src/blockstore.js b/src/blockstore.js
index 2d347cf0..3aad0952 100644
--- a/src/blockstore.js
+++ b/src/blockstore.js
@@ -1,37 +1,57 @@
'use strict'
-const core = require('datastore-core')
-const ShardingStore = core.ShardingDatastore
+const { shard, ShardingDatastore } = require('datastore-core')
const Block = require('ipld-block')
const { cidToKey, keyToCid } = require('./blockstore-utils')
const map = require('it-map')
const drain = require('it-drain')
const pushable = require('it-pushable')
-
-module.exports = async (filestore, options) => {
- const store = await maybeWithSharding(filestore, options)
+/**
+ * @typedef {import("interface-datastore").Query} Query
+ * @typedef {import("interface-datastore").Datastore} Datastore
+ * @typedef {import("interface-datastore").Options} DatastoreOptions
+ * @typedef {import("cids")} CID
+ */
+
+/**
+ *
+ * @param {Datastore} filestore
+ * @param {*} options
+ */
+module.exports = (filestore, options) => {
+ const store = maybeWithSharding(filestore, options)
return createBaseStore(store)
}
+/**
+ * @param {Datastore} filestore
+ * @param {{ sharding: any; }} options
+ */
function maybeWithSharding (filestore, options) {
if (options.sharding) {
- const shard = new core.shard.NextToLast(2)
- return ShardingStore.createOrOpen(filestore, shard)
+ return new ShardingDatastore(filestore, new shard.NextToLast(2))
}
return filestore
}
+/**
+ * @param {Datastore | ShardingDatastore} store
+ */
function createBaseStore (store) {
return {
+ open () {
+ return store.open()
+ },
/**
* Query the store
*
- * @param {Object} query
- * @param {Object} options
- * @returns {AsyncIterator}
+ * @param {Query} query
+ * @param {DatastoreOptions} [options]
+ * @returns {AsyncIterable}
*/
async * query (query, options) {
for await (const { key, value } of store.query(query, options)) {
+ // TODO: we should make this a different method
if (query.keysOnly) {
yield keyToCid(key)
continue
@@ -45,7 +65,7 @@ function createBaseStore (store) {
* Get a single block by CID
*
* @param {CID} cid
- * @param {Object} options
+ * @param {DatastoreOptions} [options]
* @returns {Promise}
*/
async get (cid, options) {
@@ -58,9 +78,9 @@ function createBaseStore (store) {
/**
* Like get, but for more
*
- * @param {AsyncIterator} cids
- * @param {Object} options
- * @returns {AsyncIterator}
+ * @param {Iterable | AsyncIterable} cids
+ * @param {DatastoreOptions} [options]
+ * @returns {AsyncIterable}
*/
async * getMany (cids, options) {
for await (const cid of cids) {
@@ -72,7 +92,7 @@ function createBaseStore (store) {
* Write a single block to the store
*
* @param {Block} block
- * @param {Object} options
+ * @param {DatastoreOptions} [options]
* @returns {Promise}
*/
async put (block, options) {
@@ -94,7 +114,7 @@ function createBaseStore (store) {
* Like put, but for more
*
* @param {AsyncIterable|Iterable} blocks
- * @param {Object} options
+ * @param {DatastoreOptions} [options]
* @returns {AsyncIterable}
*/
async * putMany (blocks, options) { // eslint-disable-line require-await
@@ -142,10 +162,9 @@ function createBaseStore (store) {
* Does the store contain block with this CID?
*
* @param {CID} cid
- * @param {Object} options
- * @returns {Promise}
+ * @param {DatastoreOptions} [options]
*/
- async has (cid, options) { // eslint-disable-line require-await
+ has (cid, options) {
return store.has(cidToKey(cid), options)
},
@@ -153,30 +172,28 @@ function createBaseStore (store) {
* Delete a block from the store
*
* @param {CID} cid
- * @param {Object} options
+ * @param {DatastoreOptions} [options]
* @returns {Promise}
*/
- async delete (cid, options) { // eslint-disable-line require-await
+ delete (cid, options) {
return store.delete(cidToKey(cid), options)
},
/**
* Delete a block from the store
*
- * @param {AsyncIterable} cids
- * @param {Object} options
- * @returns {Promise}
+ * @param {AsyncIterable | Iterable} cids
+ * @param {DatastoreOptions} [options]
*/
- async * deleteMany (cids, options) { // eslint-disable-line require-await
- yield * store.deleteMany(map(cids, cid => cidToKey(cid)), options)
+ deleteMany (cids, options) {
+ return store.deleteMany(map(cids, cid => cidToKey(cid)), options)
},
/**
* Close the store
*
- * @returns {Promise}
*/
- async close () { // eslint-disable-line require-await
+ close () {
return store.close()
}
}
diff --git a/src/config.js b/src/config.js
index 146972cd..3b1a9c38 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,8 +1,10 @@
'use strict'
-const Key = require('interface-datastore').Key
+const { Key } = require('interface-datastore')
const { default: Queue } = require('p-queue')
+// @ts-ignore
const _get = require('just-safe-get')
+// @ts-ignore
const _set = require('just-safe-set')
const errcode = require('err-code')
const errors = require('./errors')
@@ -11,10 +13,15 @@ const uint8ArrayFromString = require('uint8arrays/from-string')
const {
hasWithFallback,
getWithFallback
+// @ts-ignore
} = require('ipfs-repo-migrations/src/utils')
const configKey = new Key('config')
+/**
+ *
+ * @param {import("interface-datastore").Datastore} store
+ */
module.exports = (store) => {
const setQueue = new Queue({ concurrency: 1 })
@@ -22,21 +29,21 @@ module.exports = (store) => {
/**
* Get the current configuration from the repo.
*
- * @param {Object} options - options
- * @param {AbortSignal} options.signal - abort this config read
- * @returns {Promise