From 2a989975a87f81d8fcfbd467a1bd5881023136b6 Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Mon, 30 Sep 2019 10:16:53 +0300 Subject: [PATCH] Add manifest (#678) * Add manifest * Add type property for reachdown (Level/community#82) --- README.md | 17 +++++++++++++++++ lib/levelup.js | 22 ++++++++++++++++++++++ package.json | 1 + test/index.js | 1 + test/manifest-test.js | 18 ++++++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 test/manifest-test.js diff --git a/README.md b/README.md index e76d009e..d744b4cc 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ db.put('name', 'levelup', function (err) { ## API - levelup() +- db.supports - db.open() - db.close() - db.put() @@ -137,6 +138,22 @@ db.get('foo', function (err, value) { }) ``` + + +### `db.supports` + +A read-only [manifest](https://github.com/Level/supports). Not [widely supported yet](https://github.com/Level/community/issues/83). Might be used like so: + +```js +if (!db.supports.permanence) { + throw new Error('Persistent storage is required') +} + +if (db.supports.bufferKeys && db.supports.promises) { + await db.put(Buffer.from('key'), 'value') +} +``` + ### `db.open([options][, callback])` diff --git a/lib/levelup.js b/lib/levelup.js index 462010d2..1fd876b7 100644 --- a/lib/levelup.js +++ b/lib/levelup.js @@ -5,6 +5,7 @@ var DeferredLevelDOWN = require('deferred-leveldown') var IteratorStream = require('level-iterator-stream') var Batch = require('./batch') var errors = require('level-errors') +var supports = require('level-supports') var assert = require('assert') var promisify = require('./promisify') var getCallback = require('./common').getCallback @@ -55,6 +56,25 @@ function LevelUP (db, options, callback) { this._db = db this.db = new DeferredLevelDOWN(db) this.open(callback) + + // Create manifest based on deferred-leveldown's + this.supports = supports(this.db.supports, { + status: false, + deferredOpen: true, + openCallback: true, + promises: true, + streams: true + }) + + // Experimental: enrich levelup interface + Object.keys(this.supports.additionalMethods).forEach(function (method) { + if (this[method] != null) return + + // Don't do this.db[method].bind() because this.db is dynamic. + this[method] = function () { + return this.db[method].apply(this.db, arguments) + } + }, this) } LevelUP.prototype.emit = EventEmitter.prototype.emit @@ -324,6 +344,8 @@ LevelUP.prototype.toString = function () { return 'LevelUP' } +LevelUP.prototype.type = 'levelup' + function maybeError (db, callback) { if (!db._isOpening() && !db.isOpen()) { process.nextTick(callback, new ReadError('Database is not open')) diff --git a/package.json b/package.json index c0997d8f..3886c0b9 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "deferred-leveldown": "~5.2.1", "level-errors": "~2.0.0", "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", "xtend": "~4.0.0" }, "devDependencies": { diff --git a/test/index.js b/test/index.js index 39b27f8e..726e0b7a 100644 --- a/test/index.js +++ b/test/index.js @@ -7,6 +7,7 @@ function suite (options) { var test = testCommon.test require('./argument-checking-test')(test, testCommon) + require('./manifest-test')(test, testCommon) require('./batch-test')(test, testCommon) if (testCommon.encodings) require('./binary-test')(test, testCommon) if (testCommon.clear) require('./clear-test')(test) diff --git a/test/manifest-test.js b/test/manifest-test.js new file mode 100644 index 00000000..fa3704ea --- /dev/null +++ b/test/manifest-test.js @@ -0,0 +1,18 @@ +var suite = require('level-supports/test') + +module.exports = function (test, testCommon) { + suite(test, testCommon) + + // TODO (once manifest lands in other modules): add integration tests. + test('manifest has expected properties', function (t) { + var db = testCommon.factory() + + t.is(db.supports.status, false) + t.is(db.supports.deferredOpen, true) + t.is(db.supports.openCallback, true) + t.is(db.supports.promises, true) + t.is(db.supports.streams, true) + + db.close(t.end.bind(t)) + }) +}