From 725e313b5bc6dff965ef0ccd2cebd9527914b95a Mon Sep 17 00:00:00 2001 From: Vincent Weevers Date: Sun, 29 Dec 2024 18:24:40 +0100 Subject: [PATCH] Improve snapshot documentation - Add `snapshot` to TypeScript option types - Remove redundant documentation from README - Don't mark explicit snapshots as experimental. I'm confident in this feature now (having finished the implementation in `classic-level`) and I'm happy with the API. Ref: https://github.com/Level/community/issues/118 Follow-Up-To: https://github.com/Level/abstract-level/pull/93 --- README.md | 18 +++++++----------- index.d.ts | 6 ++++++ types/abstract-iterator.d.ts | 4 ++-- types/abstract-level.d.ts | 30 ++++++++++++++++++++++-------- types/interfaces.d.ts | 14 ++++++++++++++ 5 files changed, 51 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1417466..5b6010e 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Get a value from the database by `key`. The optional `options` object may contai - `keyEncoding`: custom key encoding for this operation, used to encode the `key`. - `valueEncoding`: custom value encoding for this operation, used to decode the value. -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database will create its own internal snapshot for this operation. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. Returns a promise for the value. If the `key` was not found then the value will be `undefined`. @@ -164,7 +164,7 @@ Get multiple values from the database by an array of `keys`. The optional `optio - `keyEncoding`: custom key encoding for this operation, used to encode the `keys`. - `valueEncoding`: custom value encoding for this operation, used to decode values. -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database will create its own internal snapshot for this operation. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. Returns a promise for an array of values with the same order as `keys`. If a key was not found, the relevant value will be `undefined`. @@ -173,7 +173,7 @@ Returns a promise for an array of values with the same order as `keys`. If a key Check if the database has an entry with the given `key`. The optional `options` object may contain: - `keyEncoding`: custom key encoding for this operation, used to encode the `key`. -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database will create its own internal snapshot for this operation. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. Returns a promise for a boolean. For example: @@ -198,7 +198,7 @@ if (value !== undefined) { Check if the database has entries with the given keys. The `keys` argument must be an array. The optional `options` object may contain: - `keyEncoding`: custom key encoding for this operation, used to encode the `keys`. -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database will create its own internal snapshot for this operation. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. Returns a promise for an array of booleans with the same order as `keys`. For example: @@ -299,7 +299,7 @@ The `gte` and `lte` range options take precedence over `gt` and `lt` respectivel - `keyEncoding`: custom key encoding for this iterator, used to encode range options, to encode `seek()` targets and to decode keys. - `valueEncoding`: custom value encoding for this iterator, used to decode values. - `signal`: an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) to [abort read operations on the iterator](#aborting-iterators). -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) for the iterator to read from. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database will create its own internal snapshot before returning an iterator. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from. Lastly, an implementation is free to add its own options. @@ -342,7 +342,7 @@ Delete all entries or a range. Not guaranteed to be atomic. Returns a promise. A - `reverse` (boolean, default: `false`): delete entries in reverse order. Only effective in combination with `limit`, to delete the last N entries. - `limit` (number, default: `Infinity`): limit the number of entries to be deleted. This number represents a _maximum_ number of entries and will not be reached if the end of the range is reached first. A value of `Infinity` or `-1` means there is no limit. When `reverse` is true the entries with the highest keys will be deleted instead of the lowest keys. - `keyEncoding`: custom key encoding for this operation, used to encode range options. -- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from, such that entries not present in the snapshot will not be deleted. If no `snapshot` is provided and `db.supports.implicitSnapshots` is true, the database may create its own internal snapshot but (unlike on other methods) this is currently not a hard requirement for implementations. +- `snapshot`: explicit [snapshot](#snapshot--dbsnapshotoptions) to read from, such that entries not present in the snapshot will not be deleted. If no `snapshot` is provided, the database may create its own internal snapshot but (unlike on other methods) this is currently not a hard requirement for implementations. The `gte` and `lte` range options take precedence over `gt` and `lt` respectively. If no options are provided, all entries will be deleted. @@ -451,14 +451,10 @@ console.log(nested.prefixKey('a', 'utf8', true)) // '!nested!a' ### `snapshot = db.snapshot(options)` -**This is an experimental API ([Level/community#118](https://github.com/Level/community/issues/118)).** - -Create an explicit [snapshot](#snapshot). Throws a [`LEVEL_NOT_SUPPORTED`](#level_not_supported) error if `db.supports.explicitSnapshots` is false. For details, see [Reading From Snapshots](#reading-from-snapshots). +Create an explicit [snapshot](#snapshot). Throws a [`LEVEL_NOT_SUPPORTED`](#level_not_supported) error if `db.supports.explicitSnapshots` is false ([Level/community#118](https://github.com/Level/community/issues/118)). For details, see [Reading From Snapshots](#reading-from-snapshots). There are currently no options but specific implementations may add their own. -Don't forget to call `snapshot.close()` when done. - ### `db.supports` A [manifest](https://github.com/Level/supports) describing the features supported by this database. Might be used like so: diff --git a/index.d.ts b/index.d.ts index 1b308fb..ad07aa6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -4,6 +4,8 @@ export { AbstractOpenOptions, AbstractGetOptions, AbstractGetManyOptions, + AbstractHasOptions, + AbstractHasManyOptions, AbstractPutOptions, AbstractDelOptions, AbstractBatchOptions, @@ -42,4 +44,8 @@ export { AbstractSnapshot } from './types/abstract-snapshot' +export { + AbstractReadOptions +} from './types/interfaces' + export * as Transcoder from 'level-transcoder' diff --git a/types/abstract-iterator.d.ts b/types/abstract-iterator.d.ts index e8c5eb6..52acfa8 100644 --- a/types/abstract-iterator.d.ts +++ b/types/abstract-iterator.d.ts @@ -1,7 +1,7 @@ import * as Transcoder from 'level-transcoder' -import { RangeOptions } from './interfaces' +import { AbstractReadOptions, RangeOptions } from './interfaces' -declare interface CommonIteratorOptions { +declare interface CommonIteratorOptions extends AbstractReadOptions { /** * An [`AbortSignal`][1] to abort read operations on the iterator. * diff --git a/types/abstract-level.d.ts b/types/abstract-level.d.ts index 7805f50..597ec68 100644 --- a/types/abstract-level.d.ts +++ b/types/abstract-level.d.ts @@ -14,7 +14,7 @@ import { AbstractValueIteratorOptions } from './abstract-iterator' -import { RangeOptions } from './interfaces' +import { AbstractReadOptions, RangeOptions } from './interfaces' /** * Abstract class for a lexicographically sorted key-value database. @@ -272,12 +272,20 @@ declare class AbstractLevel /** * Create an explicit snapshot. Throws a `LEVEL_NOT_SUPPORTED` error if - * `db.supports.explicitSnapshots` is false. - * - * Don't forget to call `snapshot.close()` when done. + * `db.supports.explicitSnapshots` is false ([Level/community#118][1]). * * @param options There are currently no options but specific implementations * may add their own. + * + * @example + * ```ts + * await db.put('example', 'before') + * await using snapshot = db.snapshot() + * await db.put('example', 'after') + * await db.get('example', { snapshot })) // Returns 'before' + * ``` + * + * [1]: https://github.com/Level/community/issues/118 */ snapshot (options?: any | undefined): AbstractSnapshot @@ -351,7 +359,7 @@ export interface AbstractOpenOptions { /** * Options for the {@link AbstractLevel.get} method. */ -export interface AbstractGetOptions { +export interface AbstractGetOptions extends AbstractReadOptions { /** * Custom key encoding for this operation, used to encode the `key`. */ @@ -366,7 +374,7 @@ export interface AbstractGetOptions { /** * Options for the {@link AbstractLevel.getMany} method. */ -export interface AbstractGetManyOptions { +export interface AbstractGetManyOptions extends AbstractReadOptions { /** * Custom key encoding for this operation, used to encode the `keys`. */ @@ -381,7 +389,7 @@ export interface AbstractGetManyOptions { /** * Options for the {@link AbstractLevel.has} method. */ -export interface AbstractHasOptions { +export interface AbstractHasOptions extends AbstractReadOptions { /** * Custom key encoding for this operation, used to encode the `key`. */ @@ -391,7 +399,7 @@ export interface AbstractHasOptions { /** * Options for the {@link AbstractLevel.hasMany} method. */ -export interface AbstractHasManyOptions { +export interface AbstractHasManyOptions extends AbstractReadOptions { /** * Custom key encoding for this operation, used to encode the `keys`. */ @@ -515,6 +523,12 @@ export interface AbstractClearOptions extends RangeOptions { * Custom key encoding for this operation, used to encode range options. */ keyEncoding?: string | Transcoder.PartialEncoding | undefined + + /** + * Explicit snapshot to read from, such that entries not present in the snapshot will + * not be deleted. + */ + snapshot?: AbstractSnapshot | undefined } /** diff --git a/types/interfaces.d.ts b/types/interfaces.d.ts index 30b24f7..438b6a1 100644 --- a/types/interfaces.d.ts +++ b/types/interfaces.d.ts @@ -1,3 +1,6 @@ +import { AbstractLevel } from './abstract-level' +import { AbstractSnapshot } from './abstract-snapshot' + export interface RangeOptions { gt?: K gte?: K @@ -6,3 +9,14 @@ export interface RangeOptions { reverse?: boolean | undefined limit?: number | undefined } + +/** + * Common options for read methods like {@link AbstractLevel.get} and + * {@link AbstractLevel.iterator}. + */ +export interface AbstractReadOptions { + /** + * Explicit snapshot to read from. + */ + snapshot?: AbstractSnapshot | undefined +}