From 60bd660b70fc28187739ef507ac789b00ff892bb Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Sat, 25 Sep 2021 20:24:50 +0200 Subject: [PATCH] Breaking: bump abstract-leveldown, encoding-down, levelup - Removes legacy range options (Level/community#86) - Drops legacy runtime environments (Level/community#98) - In browsers, `process.nextTick()` has been replaced with `queue-microtask` --- UPGRADING.md | 31 ++++++++++++++++++++++++++++--- index.js | 12 +++++++++++- leveldown.js | 13 ++++++------- matchdown.js | 2 ++ package.json | 8 ++++---- test/index.js | 19 ++++++++++--------- 6 files changed, 61 insertions(+), 24 deletions(-) diff --git a/UPGRADING.md b/UPGRADING.md index 784391b..d1cf474 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -2,7 +2,32 @@ This document describes breaking changes and how to upgrade. For a complete list of changes including minor and patch releases, please refer to the [changelog](CHANGELOG.md). -## v5 +## Upcoming + +Legacy range options have been removed ([Level/community#86](https://github.com/Level/community/issues/86)). If you previously did: + +```js +db.createReadStream({ start: 'a', end: 'z' }) +``` + +An error would now be thrown and you must instead do: + +```js +db.createReadStream({ gte: 'a', lte: 'z' }) +``` + +The same applies to `db.iterator()`, `db.createKeyStream()` and `db.createValueStream()`. + +This release also drops support of legacy runtime environments ([Level/community#98](https://github.com/Level/community/issues/98)): + +- Node.js 6 and 8 +- Internet Explorer 11 +- Safari 9-11 +- Stock Android browser (AOSP). + +Lastly, in browsers, `process.nextTick()` has been replaced with [`queue-microtask`](https://github.com/feross/queue-microtask), except in streams. + +## 5.0.0 ### Fixes iterating buffer keys that contain bytes 196-255 ([#88](https://github.com/level/subleveldown/issues/88)) @@ -57,7 +82,7 @@ subdb(db, 'example').on('error', function (err) { db.close(function () {}) ``` -## v4 +## 4.0.0 Upgraded to `abstract-leveldown@6`, `encoding-down@6` and `levelup@4`. We recommend to pair `subleveldown@4` with `level` >= 5 or when using a custom store, one that is based on `abstract-leveldown` >= 6. For details please see: @@ -66,7 +91,7 @@ Upgraded to `abstract-leveldown@6`, `encoding-down@6` and `levelup@4`. We recomm A quick summary: range options are now serialized the same as keys, `db.iterator({ gt: undefined })` is not the same as `db.iterator({})`, nullish values are now rejected and streams are backed by [`readable-stream@3`](https://github.com/nodejs/readable-stream#version-3xx). -## v3 +## 3.0.0 Dropped support for node 4. diff --git a/index.js b/index.js index cfe8c68..fbfb94e 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,5 @@ +'use strict' + const subdown = require('./leveldown') const levelup = require('levelup') const encoding = require('encoding-down') @@ -6,5 +8,13 @@ module.exports = function (db, prefix, opts) { if (typeof prefix === 'object' && !opts) return module.exports(db, null, prefix) if (!opts) opts = {} - return levelup(encoding(subdown(db, prefix, opts), opts), opts) + const wrapped = levelup(encoding(subdown(db, prefix, opts), opts), opts) + + // Workaround for abstract-leveldown tests that expect db._nextTick + // TODO: fix tests or add _nextTick to levelup for API parity + if (!wrapped._nextTick) { + wrapped._nextTick = subdown.prototype._nextTick + } + + return wrapped } diff --git a/leveldown.js b/leveldown.js index a7964db..b4842cc 100644 --- a/leveldown.js +++ b/leveldown.js @@ -1,12 +1,15 @@ +'use strict' + const inherits = require('inherits') const abstract = require('abstract-leveldown') const wrap = require('level-option-wrap') const reachdown = require('reachdown') const matchdown = require('./matchdown') -const rangeOptions = 'start end gt gte lt lte'.split(' ') +const rangeOptions = ['gt', 'gte', 'lt', 'lte'] const defaultClear = abstract.AbstractLevelDOWN.prototype._clear const hasOwnProperty = Object.prototype.hasOwnProperty +const nextTick = abstract.AbstractLevelDOWN.prototype._nextTick function concat (prefix, key, force) { if (typeof key === 'string' && (force || key.length)) return prefix + key @@ -228,19 +231,15 @@ function maybeError (leveldown, callback) { if (leveldown.status !== 'open') { // Same error message as levelup // TODO: use require('level-errors').ReadError - process.nextTick(callback, new Error('Database is not open')) + nextTick(callback, new Error('Database is not open')) return true } return false } -function fixRange (opts) { - return (!opts.reverse || (!opts.end && !opts.start)) ? opts : { start: opts.end, end: opts.start } -} - SubDown.prototype._iterator = function (opts) { - const xopts = addRestOptions(wrap(fixRange(opts), this._wrap), opts) + const xopts = addRestOptions(wrap(opts, this._wrap), opts) return new SubIterator(this, this.leveldown.iterator(xopts), this.prefix) } diff --git a/matchdown.js b/matchdown.js index 45a0e10..52af4db 100644 --- a/matchdown.js +++ b/matchdown.js @@ -1,3 +1,5 @@ +'use strict' + module.exports = function matchdown (db, type) { // Skip layers that we handle ourselves if (type === 'levelup') return false diff --git a/package.json b/package.json index 0d02ba4..2939484 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,11 @@ "test": "test" }, "dependencies": { - "abstract-leveldown": "^6.3.0", - "encoding-down": "^6.2.0", + "abstract-leveldown": "^7.1.0", + "encoding-down": "^7.0.0", "inherits": "^2.0.3", "level-option-wrap": "^1.1.0", - "levelup": "^4.4.0", + "levelup": "^5.0.1", "reachdown": "^1.1.0" }, "devDependencies": { @@ -30,7 +30,7 @@ "hallmark": "^3.1.0", "level-community": "^3.0.0", "level-concat-iterator": "^3.0.0", - "memdown": "^5.0.0", + "memdown": "^6.0.0", "nyc": "^14.0.0", "standard": "^16.0.3", "tape": "^5.0.1" diff --git a/test/index.js b/test/index.js index d84a343..6bc0199 100644 --- a/test/index.js +++ b/test/index.js @@ -13,6 +13,7 @@ const reachdown = require('reachdown') const abstract = require('abstract-leveldown') const inherits = require('util').inherits const EventEmitter = require('events') +const nextTick = subdown.prototype._nextTick // Test abstract-leveldown compliance function runSuite (factory) { @@ -179,7 +180,7 @@ test('SubDb main function', function (t) { const mockdb = mock(abstract.AbstractLevelDOWN, { _open: function (opts, cb) { - process.nextTick(cb, new Error('error from underlying store')) + nextTick(cb, new Error('error from underlying store')) } }) @@ -337,17 +338,17 @@ test('SubDb main function', function (t) { db.close(function (err) { t.ifError(err, 'no close error') - t.is(reachdown(sub, 'subleveldown').status, 'opening') + t.is(reachdown(sub, 'subleveldown').status, 'new') t.is(reachdown(sub).status, 'closed') - - sub.on('error', (err) => { - t.is(err.message, 'Parent database is not open') - t.is(reachdown(sub, 'subleveldown').status, 'new') - }) }) const sub = subdb(db, 'test') + sub.on('error', (err) => { + t.is(err.message, 'Parent database is not open') + t.is(reachdown(sub, 'subleveldown').status, 'new') + }) + sub.on('open', function () { t.fail('should not open') }) @@ -486,10 +487,10 @@ test('SubDb main function', function (t) { _iterator: function () { return { next: function (cb) { - process.nextTick(cb, new Error('next() error from underlying store')) + nextTick(cb, new Error('next() error from underlying store')) }, end: function (cb) { - process.nextTick(cb, new Error('end() error from underlying store')) + nextTick(cb, new Error('end() error from underlying store')) } } }