diff --git a/.aegir.js b/.aegir.js index 75cd7af..378889f 100644 --- a/.aegir.js +++ b/.aegir.js @@ -10,7 +10,7 @@ const esbuild = { /** @type {import('aegir').PartialOptions} */ module.exports = { build: { - bundlesizeMax: '65KB' + bundlesizeMax: '67KB' }, test: { browser: { diff --git a/package.json b/package.json index 3397a56..2908a76 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,11 @@ }, "homepage": "https://github.com/ipfs/js-datastore-level#readme", "dependencies": { - "datastore-core": "^3.0.0", - "interface-datastore": "^3.0.6", + "datastore-core": "^4.0.0", + "interface-datastore": "^4.0.0", + "it-filter": "^1.0.2", + "it-map": "^1.0.5", + "it-take": "^1.0.1", "level": "^6.0.1" }, "devDependencies": { diff --git a/src/index.js b/src/index.js index 8638c45..840c5f7 100644 --- a/src/index.js +++ b/src/index.js @@ -3,15 +3,19 @@ const { Key, Errors, Adapter, utils: { - filter, map, take, sortAll + sortAll } } = require('interface-datastore') +const filter = require('it-filter') +const map = require('it-map') +const take = require('it-take') /** * @typedef {import('interface-datastore').Datastore} Datastore * @typedef {import('interface-datastore').Pair} Pair * @typedef {import('interface-datastore').Batch} Batch * @typedef {import('interface-datastore').Query} Query + * @typedef {import('interface-datastore').KeyQuery} KeyQuery * @typedef {import('interface-datastore').Options} QueryOptions */ @@ -159,41 +163,42 @@ class LevelDatastore extends Adapter { /** * @param {Query} q - * @returns {AsyncIterable} */ query (q) { - let values = true - if (q.keysOnly != null) { - values = !q.keysOnly + let it = this._query({ + values: true, + prefix: q.prefix + }) + + if (Array.isArray(q.filters)) { + it = q.filters.reduce((it, f) => filter(it, f), it) } - const opts = { - keys: true, - values: values, - keyAsBuffer: true + if (Array.isArray(q.orders)) { + it = q.orders.reduce((it, f) => sortAll(it, f), it) } - // Let the db do the prefix matching - if (q.prefix != null) { - const prefix = q.prefix.toString() - // Match keys greater than or equal to `prefix` and - // @ts-ignore - opts.gte = prefix - // less than `prefix` + \xFF (hex escape sequence) - // @ts-ignore - opts.lt = prefix + '\xFF' + const { offset, limit } = q + if (offset) { + let i = 0 + it = filter(it, () => i++ >= offset) } - let it = levelIteratorToIterator( - this.db.iterator(opts) - ) + if (limit) { + it = take(it, limit) + } - it = map(it, ({ key, value }) => { - if (values) { - return { key, value } - } - return /** @type {Pair} */({ key }) - }) + return it + } + + /** + * @param {KeyQuery} q + */ + queryKeys (q) { + let it = map(this._query({ + values: false, + prefix: q.prefix + }), ({ key }) => key) if (Array.isArray(q.filters)) { it = q.filters.reduce((it, f) => filter(it, f), it) @@ -202,6 +207,7 @@ class LevelDatastore extends Adapter { if (Array.isArray(q.orders)) { it = q.orders.reduce((it, f) => sortAll(it, f), it) } + const { offset, limit } = q if (offset) { let i = 0 @@ -214,6 +220,33 @@ class LevelDatastore extends Adapter { return it } + + /** + * @param {object} opts + * @param {boolean} opts.values + * @param {string} [opts.prefix] + * @returns {AsyncIterable} + */ + _query (opts) { + const iteratorOpts = { + keys: true, + keyAsBuffer: true, + values: opts.values + } + + // Let the db do the prefix matching + if (opts.prefix != null) { + const prefix = opts.prefix.toString() + // Match keys greater than or equal to `prefix` and + // @ts-ignore + iteratorOpts.gte = prefix + // less than `prefix` + \xFF (hex escape sequence) + // @ts-ignore + iteratorOpts.lt = prefix + '\xFF' + } + + return levelIteratorToIterator(this.db.iterator(iteratorOpts)) + } } /** diff --git a/tsconfig.json b/tsconfig.json index e605b61..fe3cbd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { - "extends": "./node_modules/aegir/src/config/tsconfig.aegir.json", + "extends": "aegir/src/config/tsconfig.aegir.json", "compilerOptions": { "outDir": "dist" }, "include": [ - "test", // remove this line if you don't want to type-check tests + "test", "src" ] }