Skip to content
This repository has been archived by the owner on Mar 23, 2023. It is now read-only.

feat: types #62

Merged
merged 11 commits into from
Jan 22, 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
49 changes: 49 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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
- uses: gozala/typescript-error-reporter-action@v1.0.8
- run: npx aegir build --no-bundle
- run: npx aegir dep-check
test-node:
needs: check
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
node: [12, 14]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
node: [12, 14]
node: [14, 15]

This should be 14 & 15 as that's LTS/Current. Going through and updating all of these repos every time there's a new node version is going to be an enormous pain, can it be automated?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That issue looks like it's stalled and the linked PR is stale and also contains a bunch of irrelevant changes which will harm its chances of being merged.

I think we'll need to do something ourselves for the time being.

fail-fast: true
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: npm install
- run: npx nyc --reporter=lcov aegir test -t node -- --bail
- uses: codecov/codecov-action@v1
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
41 changes: 0 additions & 41 deletions .npmignore

This file was deleted.

29 changes: 0 additions & 29 deletions .travis.yml

This file was deleted.

19 changes: 14 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
"description": "Datastore implementation with file system backend",
"leadMaintainer": "Alex Potsides <alex.potsides@protocol.ai>",
"main": "src/index.js",
"types": "dist/src/index.d.ts",
"files": [
"src",
"dist"
],
"scripts": {
"prepare": "aegir build --no-bundle",
"test": "aegir test -t node",
"build": "aegir build",
"lint": "aegir lint",
Expand Down Expand Up @@ -32,21 +38,24 @@
},
"homepage": "https://github.com/ipfs/js-datastore-fs#readme",
"dependencies": {
"datastore-core": "^2.0.0",
"datastore-core": "^3.0.0",
"fast-write-atomic": "^0.2.0",
"interface-datastore": "^2.0.0",
"interface-datastore": "^3.0.3",
"it-glob": "0.0.10",
"mkdirp": "^1.0.4"
},
"devDependencies": {
"aegir": "^28.1.0",
"aegir": "^30.3.0",
"async-iterator-all": "^1.0.0",
"cids": "^1.0.0",
"cids": "^1.1.5",
"detect-node": "^2.0.4",
"ipfs-utils": "^4.0.1",
"ipfs-utils": "^6.0.0",
"memdown": "^5.1.0",
"rimraf": "^3.0.2"
},
"eslintConfig": {
"extends": "ipfs"
},
"contributors": [
"achingbrain <alex@achingbrain.net>",
"David Dias <daviddias.p@gmail.com>",
Expand Down
40 changes: 35 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

const fs = require('fs')
const glob = require('it-glob')
// @ts-ignore
const mkdirp = require('mkdirp')
const promisify = require('util').promisify
// @ts-ignore
const writeAtomic = promisify(require('fast-write-atomic'))
const path = require('path')
const {
Expand All @@ -17,6 +19,18 @@ const fsAccess = promisify(fs.access || noop)
const fsReadFile = promisify(fs.readFile || noop)
const fsUnlink = promisify(fs.unlink || noop)

/**
* @typedef {import('interface-datastore').Datastore} Datastore
* @typedef {import('interface-datastore').Pair} Pair
* @typedef {import('interface-datastore').Query} Query
*/

/**
* Write a file atomically
*
* @param {string} path
* @param {Uint8Array} contents
*/
async function writeFile (path, contents) {
try {
await writeAtomic(path, contents)
Expand All @@ -42,8 +56,14 @@ async function writeFile (path, contents) {
*
* Keys need to be sanitized before use, as they are written
* to the file system as is.
*
* @implements {Datastore}
*/
class FsDatastore extends Adapter {
/**
* @param {string} location
* @param {{ createIfMissing?: boolean; errorIfExists?: boolean; extension?: string; } | undefined} [opts]
*/
constructor (location, opts) {
super()

Expand All @@ -64,22 +84,27 @@ class FsDatastore extends Adapter {
if (this.opts.errorIfExists) {
throw Errors.dbOpenFailedError(new Error(`Datastore directory: ${this.path} already exists`))
}
return Promise.resolve()
} catch (err) {
if (err.code === 'ERR_NOT_FOUND' && this.opts.createIfMissing) {
mkdirp.sync(this.path, { fs: fs })
return
return Promise.resolve()
}

throw err
}
}

close () {
return Promise.resolve()
}

/**
* Calculate the directory and file name for a given key.
*
* @private
* @param {Key} key
* @returns {{string, string}}
* @returns {{dir:string, file:string}}
*/
_encode (key) {
const parent = key.parent().toString()
Expand Down Expand Up @@ -194,7 +219,7 @@ class FsDatastore extends Adapter {
* Check for the existence of the given key.
*
* @param {Key} key
* @returns {Promise<bool>}
* @returns {Promise<boolean>}
*/
async has (key) {
const parts = this._encode(key)
Expand Down Expand Up @@ -225,7 +250,12 @@ class FsDatastore extends Adapter {
}
}

async * _all (q) { // eslint-disable-line require-await
/**
*
* @param {Query} q
* @returns {AsyncIterable<Pair>}
*/
async * _all (q) {
let prefix = q.prefix || '**'

// strip leading slashes
Expand Down Expand Up @@ -256,7 +286,7 @@ class FsDatastore extends Adapter {
}
}
} else {
yield * map(files, f => ({ key: this._decode(f) }))
yield * map(files, f => /** @type {Pair} */({ key: this._decode(f) }))
}
}
}
Expand Down
16 changes: 11 additions & 5 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
const { expect } = require('aegir/utils/chai')
const path = require('path')
const promisify = require('util').promisify
const noop = () => {}
// @ts-ignore
const mkdirp = require('mkdirp')
// @ts-ignore
const rimraf = promisify(require('rimraf'))
const fs = require('fs')
const noop = () => {}
const fsReadFile = promisify(require('fs').readFile || noop)
const Key = require('interface-datastore').Key
const utils = require('interface-datastore').utils
const ShardingStore = require('datastore-core').ShardingDatastore
const sh = require('datastore-core').shard
const isNode = require('detect-node')
const TextEncoder = require('ipfs-utils/src/text-encoder')
const utf8Encoder = new TextEncoder('utf8')
const { isNode } = require('ipfs-utils/src/env')
const utf8Encoder = new TextEncoder()
// @ts-ignore
const tests = require('interface-datastore/src/tests')

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

Expand Down Expand Up @@ -69,13 +73,15 @@ describe('FsDatastore', () => {
const fs = new FsStore(dir)

expect(
// @ts-ignore
fs._encode(new Key('hello/world'))
).to.eql({
dir: path.join(dir, 'hello'),
file: path.join(dir, 'hello', 'world.data')
})

expect(
// @ts-ignore
fs._decode(fs._encode(new Key('hello/world/test:other')).file)
).to.eql(
new Key('hello/world/test:other')
Expand Down Expand Up @@ -153,7 +159,7 @@ describe('FsDatastore', () => {
describe('interface-datastore', () => {
const dir = utils.tmpdir()

require('interface-datastore/src/tests')({
tests({
setup: () => {
return new FsStore(dir)
},
Expand All @@ -166,7 +172,7 @@ describe('FsDatastore', () => {
describe('interface-datastore (sharding(fs))', () => {
const dir = utils.tmpdir()

require('interface-datastore/src/tests')({
tests({
setup: () => {
const shard = new sh.NextToLast(2)
return ShardingStore.createOrOpen(new FsStore(dir), shard)
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", // remove this line if you don't want to type-check tests
"src"
]
}