Skip to content

Commit

Permalink
Breaking: make iterator.seek() a mandatory feature
Browse files Browse the repository at this point in the history
All first-party implementations already support it (`classic-level`,
`memory-level`, `browser-level`, `many-level` and `rave-level`).

Category: change
  • Loading branch information
vweevers committed Dec 31, 2024
1 parent a05a8ea commit 48547a3
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 16 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -597,8 +597,6 @@ The optional `options` object may contain:

If range options like `gt` were passed to `db.iterator()` and `target` does not fall within that range, the iterator will reach its natural end.

**Note:** Not all implementations support `seek()`. Consult `db.supports.seek` or the [support matrix](https://github.com/Level/supports#seek-boolean).

#### `iterator.close()`

Free up underlying resources. Returns a promise. Closing the iterator is an idempotent operation, such that calling `close()` more than once is allowed and makes no difference.
Expand Down Expand Up @@ -1349,14 +1347,14 @@ When a sublevel prefix contains characters outside of the supported byte range.

#### `LEVEL_NOT_SUPPORTED`

When a module needs a certain feature, typically as indicated by `db.supports`, but that feature is not available on a database argument or other. For example, some kind of plugin may depend on `seek()`:
When a module needs a certain feature, typically as indicated by `db.supports`, but that feature is not available on a database argument or other. For example, some kind of plugin may depend on snapshots:

```js
const ModuleError = require('module-error')

module.exports = function plugin (db) {
if (!db.supports.seek) {
throw new ModuleError('Database must support seeking', {
if (!db.supports.explicitSnapshots) {
throw new ModuleError('Database must support snapshots', {
code: 'LEVEL_NOT_SUPPORTED'
})
}
Expand Down Expand Up @@ -1767,7 +1765,7 @@ The default `_all()` is a functional default that makes repeated calls to `_next

#### `iterator._seek(target, options)`

Seek to the key closest to `target`. The `options` object will always have the following properties: `keyEncoding`. This method is optional. The default will throw an error with code [`LEVEL_NOT_SUPPORTED`](#errors). If supported, set `db.supports.seek` to `true` (via the manifest passed to the database constructor) which also enables relevant tests in the [test suite](#test-suite).
Seek to the key closest to `target`. The `options` object will always have the following properties: `keyEncoding`. The default `_seek()` will throw an error with code [`LEVEL_NOT_SUPPORTED`](#errors) and must be overridden.

#### `iterator._close()`

Expand Down Expand Up @@ -1921,7 +1919,7 @@ test('custom test', function (t) {
// ..
})

testCommon.supports.seek && test('another test', function (t) {
testCommon.supports.explicitSnapshots && test('another test', function (t) {
const db = testCommon.factory()
// ..
})
Expand Down
2 changes: 1 addition & 1 deletion abstract-iterator.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class CommonIterator {
}

_seek (target, options) {
throw new ModuleError('Iterator does not support seek()', {
throw new ModuleError('Iterator does not implement seek()', {
code: 'LEVEL_NOT_SUPPORTED'
})
}
Expand Down
3 changes: 1 addition & 2 deletions abstract-level.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ class AbstractLevel extends EventEmitter {
this.hooks = new DatabaseHooks()
this.supports = supports(manifest, {
deferredOpen: true,

// TODO (next major): add seek
seek: true,
implicitSnapshots,
permanence: manifest.permanence !== false,

Expand Down
5 changes: 1 addition & 4 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function suite (options) {
require('./iterator-test').all(test, testCommon)
require('./iterator-range-test').all(test, testCommon)
require('./async-iterator-test').all(test, testCommon)
require('./iterator-seek-test').all(test, testCommon)

require('./deferred-open-test').all(test, testCommon)
require('./encoding-test').all(test, testCommon)
Expand All @@ -44,10 +45,6 @@ function suite (options) {
require('./encoding-buffer-test').all(test, testCommon)
require('./encoding-decode-error-test').all(test, testCommon)

if (testCommon.supports.seek) {
require('./iterator-seek-test').all(test, testCommon)
}

if (testCommon.supports.implicitSnapshots) {
require('./iterator-snapshot-test').all(test, testCommon)
} else {
Expand Down
4 changes: 2 additions & 2 deletions test/self/sublevel-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,12 +251,12 @@ test('sublevel manifest and parent db', function (t) {
t.test('sublevel inherits manifest from parent db', function (t) {
const parent = new AbstractLevel({
encodings: { utf8: true },
seek: true,
explicitSnapshots: true,
foo: true
})
const sub = parent.sublevel('')
t.is(sub.supports.foo, true, 'AbstractSublevel inherits from parent')
t.is(sub.supports.seek, true, 'AbstractSublevel inherits from parent')
t.is(sub.supports.explicitSnapshots, true, 'AbstractSublevel inherits from parent')
t.end()
})

Expand Down

0 comments on commit 48547a3

Please sign in to comment.