class Deno.Kv
implements Disposable
Unstable
A key-value database that can be used to store and retrieve data.
Data is stored as key-value pairs, where the key is a [`Deno.KvKey`](../././~/Deno.KvKey)
and the value is an arbitrary structured-serializable JavaScript value.
Keys are ordered lexicographically as described in the documentation for
[`Deno.KvKey`](../././~/Deno.KvKey). Keys are unique within a database, and the last
value set for a given key is the one that is returned when reading the
key. Keys can be deleted from the database, in which case they will no
longer be returned when reading keys.
Values can be any structured-serializable JavaScript value (objects,
arrays, strings, numbers, etc.). The special value [`Deno.KvU64`](../././~/Deno.KvU64)
can be used to store 64-bit unsigned integers in the database. This special
value can not be nested within other objects or arrays. In addition to the
regular database mutation operations, the unsigned 64-bit integer value
also supports `sum`, `max`, and `min` mutations.
Keys are versioned on write by assigning the key an ever-increasing
"versionstamp". The versionstamp represents the version of a key-value pair
in the database at some point in time, and can be used to perform
transactional operations on the database without requiring any locking.
This is enabled by atomic operations, which can have conditions that ensure
that the operation only succeeds if the versionstamp of the key-value pair
matches an expected versionstamp.
Keys have a maximum length of 2048 bytes after serialization. Values have a
maximum length of 64 KiB after serialization. Serialization of both keys
and values is somewhat opaque, but one can usually assume that the
serialization of any value is about the same length as the resulting string
of a JSON serialization of that same value. If theses limits are exceeded,
an exception will be thrown.
[Symbol.dispose](): void
Create a new [`Deno.AtomicOperation`](../././~/Deno.AtomicOperation) object which can be used to
perform an atomic transaction on the database. This does not perform any
operations on the database - the atomic transaction must be committed
explicitly using the `Deno.AtomicOperation.commit` method once
all checks and mutations have been added to the operation.
close(): void
Close the database connection. This will prevent any further operations
from being performed on the database, and interrupt any in-flight
operations immediately.
commitVersionstamp(): symbol
Get a symbol that represents the versionstamp of the current atomic
operation. This symbol can be used as the last part of a key in
`.set()`, both directly on the `Kv` object and on an `AtomicOperation`
object created from this `Kv` instance.
Delete the value for the given key from the database. If no value exists
for the key, this operation is a no-op.
```ts
const db = await Deno.openKv();
await db.delete(["foo"]);
```
enqueue(value: unknown,options?: { delay?: number; keysIfUndelivered?: KvKey[]; backoffSchedule?: number[]; },): Promise<KvCommitResult>
Add a value into the database queue to be delivered to the queue
listener via `Deno.Kv.listenQueue`.
```ts
const db = await Deno.openKv();
await db.enqueue("bar");
```
The `delay` option can be used to specify the delay (in milliseconds)
of the value delivery. The default delay is 0, which means immediate
delivery.
```ts
const db = await Deno.openKv();
await db.enqueue("bar", { delay: 60000 });
```
The `keysIfUndelivered` option can be used to specify the keys to
be set if the value is not successfully delivered to the queue
listener after several attempts. The values are set to the value of
the queued message.
The `backoffSchedule` option can be used to specify the retry policy for
failed message delivery. Each element in the array represents the number of
milliseconds to wait before retrying the delivery. For example,
`[1000, 5000, 10000]` means that a failed delivery will be retried
at most 3 times, with 1 second, 5 seconds, and 10 seconds delay
between each retry.
```ts
const db = await Deno.openKv();
await db.enqueue("bar", {
keysIfUndelivered: [["foo", "bar"]],
backoffSchedule: [1000, 5000, 10000],
});
```
get<T = unknown>(key: KvKey,options?: { consistency?: KvConsistencyLevel; },): Promise<KvEntryMaybe<T>>
Retrieve the value and versionstamp for the given key from the database
in the form of a [`Deno.KvEntryMaybe`](../././~/Deno.KvEntryMaybe). If no value exists for
the key, the returned entry will have a `null` value and versionstamp.
```ts
const db = await Deno.openKv();
const result = await db.get(["foo"]);
result.key; // ["foo"]
result.value; // "bar"
result.versionstamp; // "00000000000000010000"
```
The `consistency` option can be used to specify the consistency level
for the read operation. The default consistency level is "strong". Some
use cases can benefit from using a weaker consistency level. For more
information on consistency levels, see the documentation for
[`Deno.KvConsistencyLevel`](../././~/Deno.KvConsistencyLevel).
getMany<T extends readonly unknown[]>(keys: readonly [...[K in keyof T]: KvKey],options?: { consistency?: KvConsistencyLevel; },): Promise<[K in keyof T]: KvEntryMaybe<T[K]>>
Retrieve multiple values and versionstamps from the database in the form
of an array of [`Deno.KvEntryMaybe`](../././~/Deno.KvEntryMaybe) objects. The returned array
will have the same length as the `keys` array, and the entries will be in
the same order as the keys. If no value exists for a given key, the
returned entry will have a `null` value and versionstamp.
```ts
const db = await Deno.openKv();
const result = await db.getMany([["foo"], ["baz"]]);
result[0].key; // ["foo"]
result[0].value; // "bar"
result[0].versionstamp; // "00000000000000010000"
result[1].key; // ["baz"]
result[1].value; // null
result[1].versionstamp; // null
```
The `consistency` option can be used to specify the consistency level
for the read operation. The default consistency level is "strong". Some
use cases can benefit from using a weaker consistency level. For more
information on consistency levels, see the documentation for
[`Deno.KvConsistencyLevel`](../././~/Deno.KvConsistencyLevel).
list<T = unknown>(selector: KvListSelector,options?: KvListOptions,): KvListIterator<T>
Retrieve a list of keys in the database. The returned list is an
[`Deno.KvListIterator`](../././~/Deno.KvListIterator) which can be used to iterate over the
entries in the database.
Each list operation must specify a selector which is used to specify the
range of keys to return. The selector can either be a prefix selector, or
a range selector:
- A prefix selector selects all keys that start with the given prefix of
key parts. For example, the selector `["users"]` will select all keys
that start with the prefix `["users"]`, such as `["users", "alice"]`
and `["users", "bob"]`. Note that you can not partially match a key
part, so the selector `["users", "a"]` will not match the key
`["users", "alice"]`. A prefix selector may specify a `start` key that
is used to skip over keys that are lexicographically less than the
start key.
- A range selector selects all keys that are lexicographically between
the given start and end keys (including the start, and excluding the
end). For example, the selector `["users", "a"], ["users", "n"]` will
select all keys that start with the prefix `["users"]` and have a
second key part that is lexicographically between `a` and `n`, such as
`["users", "alice"]`, `["users", "bob"]`, and `["users", "mike"]`, but
not `["users", "noa"]` or `["users", "zoe"]`.
```ts
const db = await Deno.openKv();
const entries = db.list({ prefix: ["users"] });
for await (const entry of entries) {
entry.key; // ["users", "alice"]
entry.value; // { name: "Alice" }
entry.versionstamp; // "00000000000000010000"
}
```
The `options` argument can be used to specify additional options for the
list operation. See the documentation for [`Deno.KvListOptions`](../././~/Deno.KvListOptions)
for more information.
listenQueue(handler: (value: any) => Promise<void> | void): Promise<void>
Listen for queue values to be delivered from the database queue, which
were enqueued with `Deno.Kv.enqueue`. The provided handler
callback is invoked on every dequeued value. A failed callback
invocation is automatically retried multiple times until it succeeds
or until the maximum number of retries is reached.
```ts
const db = await Deno.openKv();
db.listenQueue(async (msg: unknown) => {
await db.set(["foo"], msg);
});
```
set(): Promise<KvCommitResult>
Set the value for the given key in the database. If a value already
exists for the key, it will be overwritten.
```ts
const db = await Deno.openKv();
await db.set(["foo"], "bar");
```
Optionally an `expireIn` option can be specified to set a time-to-live
(TTL) for the key. The TTL is specified in milliseconds, and the key will
be deleted from the database at earliest after the specified number of
milliseconds have elapsed. Once the specified duration has passed, the
key may still be visible for some additional time. If the `expireIn`
option is not specified, the key will not expire.
watch<T extends readonly unknown[]>(keys: readonly [...[K in keyof T]: KvKey],options?: { raw?: boolean; },): ReadableStream<[K in keyof T]: KvEntryMaybe<T[K]>>
Watch for changes to the given keys in the database. The returned stream
is a `ReadableStream` that emits a new value whenever any of
the watched keys change their versionstamp. The emitted value is an array
of [`Deno.KvEntryMaybe`](../././~/Deno.KvEntryMaybe) objects, with the same length and order
as the `keys` array. If no value exists for a given key, the returned
entry will have a `null` value and versionstamp.
The returned stream does not return every single intermediate state of
the watched keys, but rather only keeps you up to date with the latest
state of the keys. This means that if a key is modified multiple times
quickly, you may not receive a notification for every single change, but
rather only the latest state of the key.
```ts
const db = await Deno.openKv();
const stream = db.watch([["foo"], ["bar"]]);
for await (const entries of stream) {
entries[0].key; // ["foo"]
entries[0].value; // "bar"
entries[0].versionstamp; // "00000000000000010000"
entries[1].key; // ["bar"]
entries[1].value; // null
entries[1].versionstamp; // null
}
```
The `options` argument can be used to specify additional options for the
watch operation. The `raw` option can be used to specify whether a new
value should be emitted whenever a mutation occurs on any of the watched
keys (even if the value of the key does not change, such as deleting a
deleted key), or only when entries have observably changed in some way.
When `raw: true` is used, it is possible for the stream to occasionally
emit values even if no mutations have occurred on any of the watched
keys. The default value for this option is `false`.