Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [16, 18, 20]
# TODO (next major): officially drop node 16
node: [18, 20, 22]
name: Node ${{ matrix.node }}
steps:
- name: Checkout
Expand All @@ -17,12 +18,12 @@ jobs:
- name: Install
run: npm install
- name: Install Playwright
if: matrix.node == 16
if: matrix.node == 18
run: npx playwright install --with-deps
- name: Test
run: npm test
- name: Test browsers
if: matrix.node == 16
if: matrix.node == 18
run: npm run test-browsers-local
- name: Coverage
run: npm run coverage
Expand Down
146 changes: 46 additions & 100 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![level badge][level-badge]](https://github.com/Level/awesome)
[![npm](https://img.shields.io/npm/v/level-supports.svg)](https://www.npmjs.com/package/level-supports)
[![Node version](https://img.shields.io/node/v/level-supports.svg)](https://www.npmjs.com/package/level-supports)
[![Test](https://img.shields.io/github/actions/workflow/status/Level/supports/test.yml?branch=main&label=test)](https://github.com/Level/level/actions/workflows/test.yml)
[![Test](https://img.shields.io/github/actions/workflow/status/Level/supports/test.yml?branch=main\&label=test)](https://github.com/Level/level/actions/workflows/test.yml)
[![Coverage](https://img.shields.io/codecov/c/github/Level/supports?label=\&logo=codecov\&logoColor=fff)](https://codecov.io/gh/Level/supports)
[![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)
Expand Down Expand Up @@ -41,66 +41,70 @@ Given zero or more manifest objects, returns a merged and enriched manifest obje
For future extensibility, the properties are truthy rather than strictly typed booleans. Falsy or absent properties are converted to `false`, other values are allowed:

```js
supports().snapshots // false
supports({ snapshots: true }).snapshots // true
supports({ snapshots: {} }).snapshots // {}
supports({ snapshots: 1 }, { snapshots: 2 }).snapshots // 2
supports().seek // false
supports({ seek: true }).seek // true
supports({ seek: {} }).seek // {}
supports({ seek: 1 }, { seek: 2 }).seek // 2
```

For consumers of the manifest this means they should check support like so:

```js
if (db.supports.snapshots)
if (db.supports.seek)
```

Rather than:

```js
if (db.supports.snapshots === true)
if (db.supports.seek === true)
```

**Note:** the manifest describes high-level features that typically encompass multiple methods of a db. It is currently not a goal to describe a full API, or versions of it.

## Features

### `snapshots` (boolean)
### `implicitSnapshots` (boolean)

Does the database have snapshot guarantees? Meaning that reads are unaffected by simultaneous writes. For example, an iterator should read from a snapshot of the database, created at the time `db.iterator()` was called. This means the iterator will not see the data of simultaneous write operations.

Must be `false` if any of the following is true:
Does the database read from a snapshot as described in [`abstract-level`](https://github.com/Level/abstract-level#reading-from-snapshots)? Must be `false` if any of the following is true:

- Reads don't operate on a snapshot
- Snapshots are created asynchronously.

Aliased as `snapshots` for backwards compatibility.

<details>
<summary>Support matrix</summary>

| Module | Implicit snapshots |
| :-------------- | :-------------------------- |
| `classic-level` | ✅ |
| `memory-level` | ✅ |
| `browser-level` | ❌ |
| `level` | ✅ |
| `many-level` | ✅ (unless `retry` is true) |
| `rave-level` | ❌ (unless `retry` is false) |

</details>

### `explicitSnapshots` (boolean)

Does the database implement `db.snapshot()` and do read methods accept a `snapshot` option as described in [`abstract-level`](https://github.com/Level/abstract-level#reading-from-snapshots)?

<details>
<summary>Support matrix</summary>

| Module | Snapshot guarantee |
| :------------------- | :-------------------------- |
| `classic-level` | ✅ |
| `memory-level` | ✅ |
| `browser-level` | ❌ |
| `rocks-level` | ✅ |
| `leveldown` | ✅ |
| `rocksdb` | ✅ |
| `memdown` | ✅ |
| `level-js` | ✅ (by buffering) |
| `encoding-down` | ✅ |
| `deferred-leveldown` | ✅ |
| `levelup` | ✅ |
| `level-packager` | ✅ |
| `level` | ✅ |
| `level-mem` | ✅ |
| `level-rocksdb` | ✅ |
| `subleveldown` | ✅ |
| `multileveldown` | ✅ (unless `retry` is true) |
| `level-party` | ❌ (unless `retry` is false) |
| Module | Explicit snapshots |
| :-------------- | :----------------- |
| `classic-level` | Not yet |
| `memory-level` | Not yet |
| `browser-level` | ❌ |
| `rave-level` | TBD |

</details>

### `permanence` (boolean)

Does data survive after process (or environment) exit? Typically true. False for [`memory-level`](https://github.com/Level/memory-level) and [`memdown`](https://github.com/Level/memdown).
Does data survive after process (or environment) exit? Typically true. False for [`memory-level`](https://github.com/Level/memory-level).

### `seek` (boolean)

Expand All @@ -109,28 +113,15 @@ Do iterators support [`seek(..)`](https://github.com/Level/abstract-level/#itera
<details>
<summary>Support matrix</summary>

| Module | Support |
| :------------------- | :------ |
| `abstract-level` | ✅ 1.0.0 |
| `classic-level` | ✅ 1.0.0 |
| `memory-level` | ✅ 1.0.0 |
| `browser-level` | ✅ 1.0.0 |
| `rocks-level` | ✅ 1.0.0 |
| `abstract-leveldown` | ✅ 6.0.0 |
| `leveldown` | ✅ 1.2.0 |
| `rocksdb` | ✅ 1.0.0 |
| `memdown` | ✅ 4.1.0 |
| `level-js` | ❌ |
| `encoding-down` | ✅ 6.1.0 |
| `deferred-leveldown` | ✅ 5.1.0 |
| `levelup` | ✅ n/a |
| `level-packager` | ✅ n/a |
| `level` | ✅ 8.0.0 |
| `level-mem` | ✅ 4.0.0 |
| `level-rocksdb` | ✅ 1.0.0 |
| `subleveldown` | ✅ 4.1.0 |
| `multileveldown` | ❌ |
| `level-party` | ❌ |
| Module | Support |
| :--------------- | :------ |
| `abstract-level` | ✅ 1.0.0 |
| `classic-level` | ✅ 1.0.0 |
| `memory-level` | ✅ 1.0.0 |
| `browser-level` | ✅ 1.0.0 |
| `level` | ✅ 8.0.0 |
| `many-level` | ✅ 1.0.0 |
| `rave-level` | ✅ 1.0.0 |

</details>

Expand All @@ -155,13 +146,8 @@ Does `db.open()` support these options?
| Module | Support |
| :-------------- | :------ |
| `classic-level` | ✅ |
| `rocks-level` | ✅ |
| `memory-level` | ❌ |
| `browser-level` | ❌ |
| `leveldown` | ✅ |
| `rocksdb` | ✅ |
| `memdown` | ❌ |
| `level-js` | ❌ |

</details>

Expand All @@ -177,25 +163,7 @@ if (db.supports.events.put) {

### `streams` (boolean)

Does database have the methods `createReadStream`, `createKeyStream` and `createValueStream`, following the API documented in `levelup`? For `abstract-level` databases, a standalone module called [`level-read-stream`](https://github.com/Level/read-stream) is available.

<details>
<summary>Support matrix</summary>

| Module | Support |
| :---------------------------------- | :------ |
| `abstract-level` and dependents | ❌ |
| `abstract-leveldown` and dependents | ❌ |
| `levelup` | ✅ |
| `level-packager` | ✅ |
| `level` | ✅ |
| `level-mem` | ✅ |
| `level-rocksdb` | ✅ |
| `subleveldown` | ✅ |
| `multileveldown` | ✅ |
| `level-party` | ✅ |

</details>
Does database have the methods `createReadStream`, `createKeyStream` and `createValueStream`, following the API documented in the legacy `levelup` module? Always false since the introduction of `abstract-level` which moved streams to a standalone module called [`level-read-stream`](https://github.com/Level/read-stream).

### `encodings` (object)

Expand All @@ -207,27 +175,6 @@ Which encodings (by name) does the database support, as indicated by nested prop

As the `encodings` property cannot be false (anymore, since `level-supports` v3.0.0) it implies that the database supports `keyEncoding` and `valueEncoding` options on all relevant methods, uses a default encoding of utf8 and that hence all of its read operations return strings rather than buffers by default.

<details>
<summary>Support matrix (general support)</summary>

_This matrix just indicates general support of encodings as a feature, not that the listed modules support the `encodings` property exactly as described above, which only works on `abstract-level` databases._

| Module | Support |
| :------------------------------------- | :------ |
| `abstract-level` (and dependents) | ✅ |
| `abstract-leveldown` (and dependents) | ❌ |
| `encoding-down` | ✅ |
| `levelup` | ✅ |
| `level-packager` | ✅ |
| `level` | ✅ |
| `level-mem` | ✅ |
| `level-rocksdb` | ✅ |
| `subleveldown` | ✅ |
| `multileveldown` | ✅ |
| `level-party` | ✅ |

</details>

<details>
<summary>Support matrix (specific encodings)</summary>

Expand All @@ -238,7 +185,6 @@ _This matrix lists which encodings are supported as indicated by e.g. `db.suppor
| `classic-level` | ✅ | ✅ | ✅ <sup>1<sup> |
| `memory-level` | ✅ <sup>2<sup> | ✅ <sup>2<sup> | ✅ <sup>2<sup> |
| `browser-level` | ✅ <sup>1<sup> | ✅ <sup>1<sup> | ✅ |
| `rocks-level` | ✅ | ✅ | ✅ <sup>1<sup> |
| `level@8` | ✅ <sup>3<sup> | ✅ <sup>3<sup> | ✅ <sup>3<sup> |

<small>
Expand Down
8 changes: 7 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
exports.supports = function supports (...manifests) {
const manifest = manifests.reduce((acc, m) => Object.assign(acc, m), {})

// Snapshots is an alias for backwards compatibility
const implicitSnapshots = manifest.implicitSnapshots || manifest.snapshots || false
const explicitSnapshots = manifest.explicitSnapshots || false

return Object.assign(manifest, {
snapshots: manifest.snapshots || false,
implicitSnapshots,
explicitSnapshots,
snapshots: implicitSnapshots,
permanence: manifest.permanence || false,
seek: manifest.seek || false,
createIfMissing: manifest.createIfMissing || false,
Expand Down
11 changes: 11 additions & 0 deletions test/self.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,14 @@ test('does not merge additionalMethods', function (t) {
t.same(manifest.additionalMethods, { bar: true })
t.end()
})

test('adds snapshots alias', function (t) {
for (const value of [true, false]) {
t.is(supports({ implicitSnapshots: value }).implicitSnapshots, value)
t.is(supports({ implicitSnapshots: value }).snapshots, value)
t.is(supports({ snapshots: value }).implicitSnapshots, value)
t.is(supports({ snapshots: value }).snapshots, value)
}

t.end()
})
Loading