deferred-leveldown
Advanced tools
Comparing version 6.0.0 to 7.0.0
# Changelog | ||
_**If you are upgrading:** please see [`UPGRADING.md`](UPGRADING.md)._ | ||
## [7.0.0] - 2021-09-30 | ||
_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._ | ||
### Changed | ||
- **Breaking:** only defer operations while db is opening ([`0e8475f`](https://github.com/Level/deferred-leveldown/commit/0e8475f)) ([#89](https://github.com/Level/deferred-leveldown/issues/89)) (Vincent Weevers) | ||
### Added | ||
- Add `db.getMany(keys)` ([`df5f239`](https://github.com/Level/deferred-leveldown/commit/df5f239)) ([#89](https://github.com/Level/deferred-leveldown/issues/89)) (Vincent Weevers) | ||
## [6.0.0] - 2021-04-17 | ||
_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._ | ||
### Changed | ||
@@ -69,2 +81,4 @@ | ||
_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._ | ||
### Changed | ||
@@ -99,2 +113,4 @@ | ||
_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._ | ||
### Added | ||
@@ -114,2 +130,4 @@ | ||
_If you are upgrading: please see [`UPGRADING.md`](UPGRADING.md)._ | ||
### Added | ||
@@ -132,6 +150,6 @@ | ||
**Historical Note** `abstract-leveldown@4.0.0` dropped `approximateSize()` so we needed to defer this method separately for stores that support it. | ||
## [2.0.3] - 2017-11-04 | ||
_Note: `abstract-leveldown@3.0.0` dropped support for node `0.12` and didn't have any breaking changes to api or behavior, hence a new patch version._ | ||
### Added | ||
@@ -146,4 +164,2 @@ | ||
**Historical Note** `abstract-leveldown@3.0.0` dropped support for node `0.12` and didn't have any breaking changes to api or behavior, hence a new patch version. | ||
## [2.0.2] - 2017-10-06 | ||
@@ -294,58 +310,62 @@ | ||
## 0.0.0 - 2013-09-17 | ||
## [0.0.0] - 2013-09-17 | ||
:seedling: First release. ([**@rvagg**](https://github.com/rvagg)) | ||
[6.0.0]: https://github.com/Level/deferred-leveldown/compare/v5.3.0...v6.0.0 | ||
[7.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v7.0.0 | ||
[5.3.0]: https://github.com/Level/deferred-leveldown/compare/v5.2.1...v5.3.0 | ||
[6.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v6.0.0 | ||
[5.2.1]: https://github.com/Level/deferred-leveldown/compare/v5.2.0...v5.2.1 | ||
[5.3.0]: https://github.com/Level/deferred-leveldown/releases/tag/v5.3.0 | ||
[5.2.0]: https://github.com/Level/deferred-leveldown/compare/v5.1.0...v5.2.0 | ||
[5.2.1]: https://github.com/Level/deferred-leveldown/releases/tag/v5.2.1 | ||
[5.1.0]: https://github.com/Level/deferred-leveldown/compare/v5.0.1...v5.1.0 | ||
[5.2.0]: https://github.com/Level/deferred-leveldown/releases/tag/v5.2.0 | ||
[5.0.1]: https://github.com/Level/deferred-leveldown/compare/v5.0.0...v5.0.1 | ||
[5.1.0]: https://github.com/Level/deferred-leveldown/releases/tag/v5.1.0 | ||
[5.0.0]: https://github.com/Level/deferred-leveldown/compare/v4.0.2...v5.0.0 | ||
[5.0.1]: https://github.com/Level/deferred-leveldown/releases/tag/v5.0.1 | ||
[4.0.2]: https://github.com/Level/deferred-leveldown/compare/v4.0.1...v4.0.2 | ||
[5.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v5.0.0 | ||
[4.0.1]: https://github.com/Level/deferred-leveldown/compare/v4.0.0...v4.0.1 | ||
[4.0.2]: https://github.com/Level/deferred-leveldown/releases/tag/v4.0.2 | ||
[4.0.0]: https://github.com/Level/deferred-leveldown/compare/v3.0.0...v4.0.0 | ||
[4.0.1]: https://github.com/Level/deferred-leveldown/releases/tag/v4.0.1 | ||
[3.0.0]: https://github.com/Level/deferred-leveldown/compare/v2.0.3...v3.0.0 | ||
[4.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v4.0.0 | ||
[2.0.3]: https://github.com/Level/deferred-leveldown/compare/v2.0.2...v2.0.3 | ||
[3.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v3.0.0 | ||
[2.0.2]: https://github.com/Level/deferred-leveldown/compare/v2.0.1...v2.0.2 | ||
[2.0.3]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.3 | ||
[2.0.1]: https://github.com/Level/deferred-leveldown/compare/v2.0.0...v2.0.1 | ||
[2.0.2]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.2 | ||
[2.0.0]: https://github.com/Level/deferred-leveldown/compare/v2.0.0-2...v2.0.0 | ||
[2.0.1]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.1 | ||
[2.0.0-2]: https://github.com/Level/deferred-leveldown/compare/v2.0.0-1...v2.0.0-2 | ||
[2.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.0 | ||
[2.0.0-1]: https://github.com/Level/deferred-leveldown/compare/v2.0.0-0...v2.0.0-1 | ||
[2.0.0-2]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.0-2 | ||
[2.0.0-0]: https://github.com/Level/deferred-leveldown/compare/v1.2.2...v2.0.0-0 | ||
[2.0.0-1]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.0-1 | ||
[1.2.2]: https://github.com/Level/deferred-leveldown/compare/v1.2.1...v1.2.2 | ||
[2.0.0-0]: https://github.com/Level/deferred-leveldown/releases/tag/v2.0.0-0 | ||
[1.2.1]: https://github.com/Level/deferred-leveldown/compare/v1.2.0...v1.2.1 | ||
[1.2.2]: https://github.com/Level/deferred-leveldown/releases/tag/v1.2.2 | ||
[1.2.0]: https://github.com/Level/deferred-leveldown/compare/v1.1.0...v1.2.0 | ||
[1.2.1]: https://github.com/Level/deferred-leveldown/releases/tag/v1.2.1 | ||
[1.1.0]: https://github.com/Level/deferred-leveldown/compare/v1.0.0...v1.1.0 | ||
[1.2.0]: https://github.com/Level/deferred-leveldown/releases/tag/v1.2.0 | ||
[1.0.0]: https://github.com/Level/deferred-leveldown/compare/v0.3.0...v1.0.0 | ||
[1.1.0]: https://github.com/Level/deferred-leveldown/releases/tag/v1.1.0 | ||
[0.3.0]: https://github.com/Level/deferred-leveldown/compare/v0.2.0...v0.3.0 | ||
[1.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/v1.0.0 | ||
[0.2.0]: https://github.com/Level/deferred-leveldown/compare/0.1.0...v0.2.0 | ||
[0.3.0]: https://github.com/Level/deferred-leveldown/releases/tag/v0.3.0 | ||
[0.1.0]: https://github.com/Level/deferred-leveldown/compare/0.0.1...0.1.0 | ||
[0.2.0]: https://github.com/Level/deferred-leveldown/releases/tag/v0.2.0 | ||
[0.0.1]: https://github.com/Level/deferred-leveldown/compare/0.0.0...0.0.1 | ||
[0.1.0]: https://github.com/Level/deferred-leveldown/releases/tag/0.1.0 | ||
[0.0.1]: https://github.com/Level/deferred-leveldown/releases/tag/0.0.1 | ||
[0.0.0]: https://github.com/Level/deferred-leveldown/releases/tag/0.0.0 |
'use strict' | ||
const AbstractIterator = require('abstract-leveldown').AbstractIterator | ||
const { AbstractIterator } = require('abstract-leveldown') | ||
const inherits = require('inherits') | ||
const getCallback = require('./util').getCallback | ||
const kOptions = Symbol('options') | ||
const kIterator = Symbol('iterator') | ||
const kOperations = Symbol('operations') | ||
const kPromise = Symbol('promise') | ||
function DeferredIterator (db, options) { | ||
AbstractIterator.call(this, db) | ||
this._options = options | ||
this._iterator = null | ||
this._operations = [] | ||
this[kOptions] = options | ||
this[kIterator] = null | ||
this[kOperations] = [] | ||
} | ||
@@ -17,25 +23,64 @@ | ||
DeferredIterator.prototype.setDb = function (db) { | ||
const it = this._iterator = db.iterator(this._options) | ||
this[kIterator] = db.iterator(this[kOptions]) | ||
for (const op of this._operations) { | ||
it[op.method](...op.args) | ||
for (const op of this[kOperations].splice(0, this[kOperations].length)) { | ||
this[kIterator][op.method](...op.args) | ||
} | ||
} | ||
DeferredIterator.prototype._operation = function (method, args) { | ||
if (this._iterator) return this._iterator[method](...args) | ||
this._operations.push({ method, args }) | ||
} | ||
DeferredIterator.prototype.next = function (...args) { | ||
if (this.db.status === 'open') { | ||
return this[kIterator].next(...args) | ||
} | ||
for (const m of ['next', 'end']) { | ||
DeferredIterator.prototype['_' + m] = function (...args) { | ||
this._operation(m, args) | ||
const callback = getCallback(args, kPromise, function map (key, value) { | ||
if (key === undefined && value === undefined) { | ||
return undefined | ||
} else { | ||
return [key, value] | ||
} | ||
}) | ||
if (this.db.status === 'opening') { | ||
this[kOperations].push({ method: 'next', args }) | ||
} else { | ||
this._nextTick(callback, new Error('Database is not open')) | ||
} | ||
return callback[kPromise] || this | ||
} | ||
// Must defer seek() rather than _seek() because it requires db._serializeKey to be available | ||
DeferredIterator.prototype.seek = function (...args) { | ||
this._operation('seek', args) | ||
if (this.db.status === 'open') { | ||
this[kIterator].seek(...args) | ||
} else if (this.db.status === 'opening') { | ||
this[kOperations].push({ method: 'seek', args }) | ||
} else { | ||
throw new Error('Database is not open') | ||
} | ||
} | ||
DeferredIterator.prototype.end = function (...args) { | ||
if (this.db.status === 'open') { | ||
return this[kIterator].end(...args) | ||
} | ||
const callback = getCallback(args, kPromise) | ||
if (this.db.status === 'opening') { | ||
this[kOperations].push({ method: 'end', args }) | ||
} else { | ||
this._nextTick(callback, new Error('Database is not open')) | ||
} | ||
return callback[kPromise] || this | ||
} | ||
for (const method of ['next', 'seek', 'end']) { | ||
DeferredIterator.prototype['_' + method] = function () { | ||
/* istanbul ignore next: assertion */ | ||
throw new Error('Did not expect private method to be called: ' + method) | ||
} | ||
} | ||
module.exports = DeferredIterator |
'use strict' | ||
const AbstractLevelDOWN = require('abstract-leveldown').AbstractLevelDOWN | ||
const { AbstractLevelDOWN } = require('abstract-leveldown') | ||
const inherits = require('inherits') | ||
const DeferredIterator = require('./deferred-iterator') | ||
const deferrables = 'put get del batch clear'.split(' ') | ||
const optionalDeferrables = 'approximateSize compactRange'.split(' ') | ||
const DeferredChainedBatch = require('./deferred-chained-batch') | ||
const getCallback = require('./util').getCallback | ||
const deferrables = ['put', 'get', 'getMany', 'del', 'batch', 'clear'] | ||
const optionalDeferrables = ['approximateSize', 'compactRange'] | ||
const kInnerDb = Symbol('innerDb') | ||
const kOperations = Symbol('operations') | ||
const kPromise = Symbol('promise') | ||
function DeferredLevelDOWN (db) { | ||
@@ -20,6 +27,6 @@ AbstractLevelDOWN.call(this, db.supports || {}) | ||
this._db = db | ||
this._operations = [] | ||
this[kInnerDb] = db | ||
this[kOperations] = [] | ||
closed(this) | ||
implement(this) | ||
} | ||
@@ -31,72 +38,97 @@ | ||
// Backwards compatibility for reachdown and subleveldown | ||
Object.defineProperty(DeferredLevelDOWN.prototype, '_db', { | ||
enumerable: true, | ||
get () { | ||
return this[kInnerDb] | ||
} | ||
}) | ||
DeferredLevelDOWN.prototype._open = function (options, callback) { | ||
this._db.open(options, (err) => { | ||
if (err) return callback(err) | ||
const onopen = (err) => { | ||
if (err || this[kInnerDb].status !== 'open') { | ||
// TODO: reject scheduled operations | ||
return callback(err || new Error('Database is not open')) | ||
} | ||
for (const op of this._operations) { | ||
const operations = this[kOperations] | ||
this[kOperations] = [] | ||
for (const op of operations) { | ||
if (op.iterator) { | ||
op.iterator.setDb(this._db) | ||
op.iterator.setDb(this[kInnerDb]) | ||
} else { | ||
this._db[op.method](...op.args) | ||
this[kInnerDb][op.method](...op.args) | ||
} | ||
} | ||
this._operations = [] | ||
/* istanbul ignore if: assertion */ | ||
if (this[kOperations].length > 0) { | ||
throw new Error('Did not expect further operations') | ||
} | ||
open(this) | ||
callback() | ||
}) | ||
} | ||
if (this[kInnerDb].status === 'new' || this[kInnerDb].status === 'closed') { | ||
this[kInnerDb].open(options, onopen) | ||
} else { | ||
this._nextTick(onopen) | ||
} | ||
} | ||
DeferredLevelDOWN.prototype._close = function (callback) { | ||
this._db.close((err) => { | ||
if (err) return callback(err) | ||
closed(this) | ||
callback() | ||
}) | ||
this[kInnerDb].close(callback) | ||
} | ||
function open (self) { | ||
for (const m of deferrables.concat('iterator')) { | ||
self['_' + m] = function (...args) { | ||
return this._db[m](...args) | ||
} | ||
} | ||
DeferredLevelDOWN.prototype._isOperational = function () { | ||
return this.status === 'opening' | ||
} | ||
for (const m of Object.keys(self.supports.additionalMethods)) { | ||
self[m] = function (...args) { | ||
return this._db[m](...args) | ||
function implement (self) { | ||
const additionalMethods = Object.keys(self.supports.additionalMethods) | ||
for (const method of deferrables.concat(additionalMethods)) { | ||
// Override the public rather than private methods to cover cases where abstract-leveldown | ||
// has a fast-path like on db.batch([]) which bypasses _batch() because the array is empty. | ||
self[method] = function (...args) { | ||
if (method === 'batch' && args.length === 0) { | ||
return new DeferredChainedBatch(this) | ||
} else if (this.status === 'open') { | ||
return this[kInnerDb][method](...args) | ||
} | ||
const callback = getCallback(args, kPromise) | ||
if (this.status === 'opening') { | ||
this[kOperations].push({ method, args }) | ||
} else { | ||
this._nextTick(callback, new Error('Database is not open')) | ||
} | ||
return callback[kPromise] | ||
} | ||
} | ||
} | ||
function closed (self) { | ||
for (const m of deferrables) { | ||
self['_' + m] = function (...args) { | ||
this._operations.push({ method: m, args }) | ||
self.iterator = function (options) { | ||
if (this.status === 'open') { | ||
return this[kInnerDb].iterator(options) | ||
} else if (this.status === 'opening') { | ||
const iterator = new DeferredIterator(this, options) | ||
this[kOperations].push({ iterator }) | ||
return iterator | ||
} else { | ||
throw new Error('Database is not open') | ||
} | ||
} | ||
for (const m of Object.keys(self.supports.additionalMethods)) { | ||
self[m] = function (...args) { | ||
this._operations.push({ method: m, args }) | ||
for (const method of deferrables.concat(['iterator'])) { | ||
self['_' + method] = function () { | ||
/* istanbul ignore next: assertion */ | ||
throw new Error('Did not expect private method to be called: ' + method) | ||
} | ||
} | ||
self._iterator = function (options) { | ||
const it = new DeferredIterator(self, options) | ||
this._operations.push({ iterator: it }) | ||
return it | ||
} | ||
} | ||
DeferredLevelDOWN.prototype._serializeKey = function (key) { | ||
return key | ||
} | ||
DeferredLevelDOWN.prototype._serializeValue = function (value) { | ||
return value | ||
} | ||
module.exports = DeferredLevelDOWN | ||
module.exports.DeferredIterator = DeferredIterator |
{ | ||
"name": "deferred-leveldown", | ||
"version": "6.0.0", | ||
"version": "7.0.0", | ||
"description": "A mock abstract-leveldown implementation that queues operations while a real abstract-leveldown instance is being opened", | ||
@@ -10,3 +10,3 @@ "license": "MIT", | ||
"test-browsers-local": "airtap --coverage test.js", | ||
"coverage": "nyc report --reporter=text-lcov | coveralls", | ||
"coverage": "nyc report -r lcovonly", | ||
"hallmark": "hallmark --fix", | ||
@@ -17,10 +17,11 @@ "dependency-check": "dependency-check . test.js", | ||
"files": [ | ||
"deferred-chained-batch.js", | ||
"deferred-iterator.js", | ||
"deferred-leveldown.js", | ||
"util.js", | ||
"CHANGELOG.md", | ||
"LICENSE.md", | ||
"UPGRADING.md" | ||
], | ||
"dependencies": { | ||
"abstract-leveldown": "^7.0.0", | ||
"abstract-leveldown": "^7.2.0", | ||
"inherits": "^2.0.3" | ||
@@ -31,6 +32,5 @@ }, | ||
"airtap-playwright": "^1.0.1", | ||
"coveralls": "^3.0.2", | ||
"dependency-check": "^3.3.0", | ||
"hallmark": "^3.1.0", | ||
"memdown": "^6.0.0", | ||
"memdown": "^6.1.0", | ||
"nyc": "^15.1.0", | ||
@@ -37,0 +37,0 @@ "reachdown": "^1.0.0", |
@@ -6,15 +6,18 @@ # deferred-leveldown | ||
[![level badge][level-badge]](https://github.com/Level/awesome) | ||
[![npm](https://img.shields.io/npm/v/deferred-leveldown.svg?label=&logo=npm)](https://www.npmjs.com/package/deferred-leveldown) | ||
[![npm](https://img.shields.io/npm/v/deferred-leveldown.svg)](https://www.npmjs.com/package/deferred-leveldown) | ||
[![Node version](https://img.shields.io/node/v/deferred-leveldown.svg)](https://www.npmjs.com/package/deferred-leveldown) | ||
[![Travis](https://img.shields.io/travis/com/Level/deferred-leveldown.svg?logo=travis&label=)](https://travis-ci.com/Level/deferred-leveldown) | ||
[![Coverage Status](https://coveralls.io/repos/github/Level/deferred-leveldown/badge.svg)](https://coveralls.io/github/Level/deferred-leveldown) | ||
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) | ||
[![npm](https://img.shields.io/npm/dm/deferred-leveldown.svg?label=dl)](https://www.npmjs.com/package/deferred-leveldown) | ||
[![Backers on Open Collective](https://opencollective.com/level/backers/badge.svg?color=orange)](#backers) | ||
[![Sponsors on Open Collective](https://opencollective.com/level/sponsors/badge.svg?color=orange)](#sponsors) | ||
[![Test](https://img.shields.io/github/workflow/status/Level/deferred-leveldown/Test?label=test)](https://github.com/Level/deferred-leveldown/actions/workflows/test.yml) | ||
[![Coverage](https://img.shields.io/codecov/c/github/Level/deferred-leveldown?label=&logo=codecov&logoColor=fff)](https://codecov.io/gh/Level/deferred-leveldown) | ||
[![Standard](https://img.shields.io/badge/standard-informational?logo=javascript&logoColor=fff)](https://standardjs.com) | ||
[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org) | ||
[![Donate](https://img.shields.io/badge/donate-orange?logo=open-collective&logoColor=fff)](https://opencollective.com/level) | ||
`deferred-leveldown` implements the basic [abstract-leveldown](https://github.com/Level/abstract-leveldown) API so it can be used as a drop-in replacement where `leveldown` is needed. | ||
## Usage | ||
`put()`, `get()`, `del()`, `batch()` and `clear()` operations are all queued and kept in memory until the `abstract-leveldown`-compatible object has been opened through `deferred-leveldown`'s `open()` method. | ||
_If you are upgrading: please see [UPGRADING.md](UPGRADING.md)._ | ||
`deferred-leveldown` implements the [`abstract-leveldown`](https://github.com/Level/abstract-leveldown) API so it can be used as a drop-in replacement where `leveldown` is needed. | ||
`put()`, `get()`, `getMany()`, `del()`, `batch()` and `clear()` operations are all queued and kept in memory until the `abstract-leveldown`-compatible object has been opened through `deferred-leveldown`'s `open()` method. | ||
`batch()` operations will all be replayed as the array form. Chained-batch operations are converted before being stored. | ||
@@ -28,7 +31,9 @@ | ||
db.put('foo', 'bar', function (err) { | ||
// Must always call open() first | ||
db.open(function (err) { | ||
// ... | ||
}) | ||
db.open(function (err) { | ||
// But can operate before open() has finished | ||
db.put('foo', 'bar', function (err) { | ||
// ... | ||
@@ -38,4 +43,2 @@ }) | ||
**If you are upgrading:** please see [UPGRADING.md](UPGRADING.md). | ||
## Contributing | ||
@@ -51,16 +54,8 @@ | ||
To sustain [`Level`](https://github.com/Level) and its activities, become a backer or sponsor on [Open Collective](https://opencollective.com/level). Your logo or avatar will be displayed on our 28+ [GitHub repositories](https://github.com/Level) and [npm](https://www.npmjs.com/) packages. 💖 | ||
Support us with a monthly donation on [Open Collective](https://opencollective.com/level) and help us continue our work. | ||
### Backers | ||
[![Open Collective backers](https://opencollective.com/level/backers.svg?width=890)](https://opencollective.com/level) | ||
### Sponsors | ||
[![Open Collective sponsors](https://opencollective.com/level/sponsors.svg?width=890)](https://opencollective.com/level) | ||
## License | ||
[MIT](LICENSE.md) © 2013-present Rod Vagg and contributors. | ||
[MIT](LICENSE) | ||
[level-badge]: https://leveljs.org/img/badge.svg |
@@ -5,2 +5,6 @@ # Upgrade Guide | ||
## 7.0.0 | ||
Previously `deferred-leveldown` would accept operations regardless of the `status` of the inner db. It now only accepts operations while `db.status` is 'opening'. | ||
## 6.0.0 | ||
@@ -7,0 +11,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
26500
9
9
209
58
Updatedabstract-leveldown@^7.2.0