@probitas/client-deno-kv
Deno KV client for Probitas scenario testing framework.
This package provides a Deno KV client designed for integration testing of applications using Deno KV storage.
Features
- Key-Value Operations: get, set, delete with structured keys
- Listing: Iterate over keys by prefix, start, end
- Atomic Transactions: Atomic operations with version checking
- Type Safety: Generic type parameters for stored values
- Resource Management: Implements
AsyncDisposablefor proper cleanup
Installation
deno add jsr:@probitas/client-deno-kv
Quick Start
import { createDenoKvClient } from "@probitas/client-deno-kv";
const kv = await createDenoKvClient();
// Set a value
const setResult = await kv.set(["users", "1"], { name: "Alice", age: 30 });
console.log("Versionstamp:", setResult.versionstamp);
// Get a value with type
const getResult = await kv.get<{ name: string; age: number }>(["users", "1"]);
console.log("User:", getResult.value);
// List entries by prefix
const listResult = await kv.list<{ name: string }>({ prefix: ["users"] });
console.log("Entries:", listResult.entries);
await kv.close();
Atomic Operations
// Atomic transaction with version check
const atomic = kv.atomic();
atomic.check({ key: ["counter"], versionstamp: null }); // Only if key doesn't exist
atomic.set(["counter"], 1n);
await atomic.commit();
// Atomic increment
const current = await kv.get<bigint>(["counter"]);
const atomic2 = kv.atomic();
atomic2.check({ key: ["counter"], versionstamp: current.versionstamp });
atomic2.set(["counter"], (current.value ?? 0n) + 1n);
await atomic2.commit();
Using with using Statement
await using kv = await createDenoKvClient();
await kv.set(["test"], "value");
const result = await kv.get(["test"]);
console.log(result.value);
// Client automatically closed when block exits
Related Packages
| Package | Description |
|---|---|
@probitas/client |
Core utilities and types |
@probitas/client-redis |
Redis client |
Links
Installation
deno add jsr:@probitas/client-deno-kvClasses
#DenoKvAtomicBuilderImpl
class DenoKvAtomicBuilderImpl implements DenoKvAtomicBuilderDenoKvAtomicBuilderImplementation of DenoKvAtomicBuilder.
Constructor
new DenoKvAtomicBuilderImpl(kv: Deno.Kv)Methods
check(): unknownset(): unknowndelete(): unknownsum(): unknownmin(): unknownmax(): unknowncommit(): unknown#DenoKvAtomicCheckError
class DenoKvAtomicCheckError extends DenoKvErrorDenoKvErrorError thrown when an atomic operation fails due to check failures.
| Name | Description |
|---|---|
name | — |
kind | — |
failedChecks | The keys whose checks failed. |
Constructor
new DenoKvAtomicCheckError(message: string, failedChecks: readonly Deno.KvKey[], options?: ErrorOptions)Properties
- readonly
namestring - readonly
kind"atomic_check" - readonly
failedChecksreadonly Deno.KvKey[]The keys whose checks failed.
#DenoKvError
class DenoKvError extends ClientErrorClientErrorBase error class for Deno KV operations.
| Name | Description |
|---|---|
name | — |
Constructor
new DenoKvError(message: string, _: unknown, options?: ErrorOptions)Properties
- readonly
namestring
#DenoKvQuotaError
class DenoKvQuotaError extends DenoKvErrorDenoKvErrorError thrown when a quota limit is exceeded.
Constructor
new DenoKvQuotaError(message: string, options?: ErrorOptions)Properties
- readonly
namestring - readonly
kind"quota"
Interfaces
#DenoKvAtomicBuilder
interface DenoKvAtomicBuilderBuilder for atomic KV operations.
| Name | Description |
|---|---|
check() | Add version checks to the atomic operation. |
set() | Set a value in the KV store. |
delete() | Delete a key from the KV store. |
sum() | Atomically add to a bigint value (Deno.KvU64). |
min() | Atomically set to minimum of current and provided value. |
max() | Atomically set to maximum of current and provided value. |
commit() | Commit the atomic operation. |
Methods
check(_: Deno.AtomicCheck[]): thisAdd version checks to the atomic operation. If any check fails, the entire operation will fail.
Parameters
_Deno.AtomicCheck[]
set<T>(key: Deno.KvKey, value: T, options?: { expireIn?: number }): thisSet a value in the KV store.
Parameters
keyDeno.KvKeyvalueToptions?{ expireIn?: number }
delete(key: Deno.KvKey): thisDelete a key from the KV store.
Parameters
keyDeno.KvKey
sum(key: Deno.KvKey, n: bigint): thisAtomically add to a bigint value (Deno.KvU64).
Parameters
keyDeno.KvKeynbigint
min(key: Deno.KvKey, n: bigint): thisAtomically set to minimum of current and provided value.
Parameters
keyDeno.KvKeynbigint
max(key: Deno.KvKey, n: bigint): thisAtomically set to maximum of current and provided value.
Parameters
keyDeno.KvKeynbigint
commit(): Promise<DenoKvAtomicResult>Commit the atomic operation.
#DenoKvAtomicResult
interface DenoKvAtomicResultResult of an atomic operation.
| Name | Description |
|---|---|
type | — |
ok | — |
versionstamp | — |
duration | — |
Properties
- readonly
type"deno-kv:atomic" - readonly
okboolean - readonly
versionstamp?string - readonly
durationnumber
#DenoKvClient
interface DenoKvClient extends AsyncDisposableDeno KV client for Probitas scenario testing.
| Name | Description |
|---|---|
config | Client configuration. |
get() | Get a single value by key. |
getMany() | Get multiple values by keys. |
set() | Set a value. |
delete() | Delete a key. |
list() | List entries by selector. |
atomic() | Create an atomic operation builder. |
close() | Close the KV connection. |
Properties
Client configuration.
Methods
get<T>(key: Deno.KvKey, options?: CommonOptions): Promise<DenoKvGetResult<T>>Get a single value by key.
Parameters
keyDeno.KvKeyoptions?CommonOptions
getMany<T extends readonly unknown[]>(keys: readonly [unknown], options?: CommonOptions): Promise<unknown>Get multiple values by keys.
Parameters
keysreadonly [unknown]options?CommonOptions
set<T>(key: Deno.KvKey, value: T, options?: DenoKvSetOptions): Promise<DenoKvSetResult>Set a value.
Parameters
keyDeno.KvKeyvalueToptions?DenoKvSetOptions
delete(key: Deno.KvKey, options?: CommonOptions): Promise<DenoKvDeleteResult>Delete a key.
Parameters
keyDeno.KvKeyoptions?CommonOptions
list<T>(selector: Deno.KvListSelector, options?: DenoKvListOptions): Promise<DenoKvListResult<T>>List entries by selector.
Parameters
selectorDeno.KvListSelectoroptions?DenoKvListOptions
atomic(): DenoKvAtomicBuilderCreate an atomic operation builder.
close(): Promise<void>Close the KV connection.
#DenoKvClientConfig
interface DenoKvClientConfig extends CommonOptionsConfiguration for DenoKvClient.
| Name | Description |
|---|---|
path | Path to the KV database file. |
Properties
- readonly
path?stringPath to the KV database file. If not specified, uses in-memory storage or Deno Deploy's KV.
#DenoKvDeleteResult
interface DenoKvDeleteResultResult of a delete operation.
Properties
- readonly
type"deno-kv:delete" - readonly
okboolean - readonly
durationnumber
#DenoKvEntries
interface DenoKvEntries<T> extends ReadonlyArray<DenoKvEntry<T>>Collection of KV entries with helper methods.
| Name | Description |
|---|---|
first() | Returns the first entry, or undefined if empty. |
firstOrThrow() | Returns the first entry, or throws if empty. |
last() | Returns the last entry, or undefined if empty. |
lastOrThrow() | Returns the last entry, or throws if empty. |
Methods
first(): DenoKvEntry<T> | undefinedReturns the first entry, or undefined if empty.
firstOrThrow(): DenoKvEntry<T>Returns the first entry, or throws if empty.
last(): DenoKvEntry<T> | undefinedReturns the last entry, or undefined if empty.
lastOrThrow(): DenoKvEntry<T>Returns the last entry, or throws if empty.
#DenoKvEntry
interface DenoKvEntry<T>A single entry in the KV store.
| Name | Description |
|---|---|
key | — |
value | — |
versionstamp | — |
Properties
- readonly
keyDeno.KvKey - readonly
valueT - readonly
versionstampstring
#DenoKvGetResult
interface DenoKvGetResult<T>Result of a get operation.
Properties
- readonly
type"deno-kv:get" - readonly
okboolean - readonly
keyDeno.KvKey - readonly
valueT | null - readonly
versionstampstring | null - readonly
durationnumber
#DenoKvListOptions
interface DenoKvListOptions extends CommonOptionsOptions for list operations.
| Name | Description |
|---|---|
limit | Maximum number of entries to return. |
cursor | Cursor for pagination. |
reverse | Whether to iterate in reverse order. |
Properties
- readonly
limit?numberMaximum number of entries to return.
- readonly
cursor?stringCursor for pagination.
- readonly
reverse?booleanWhether to iterate in reverse order.
#DenoKvListResult
interface DenoKvListResult<T>Result of a list operation.
Properties
- readonly
type"deno-kv:list" - readonly
okboolean - readonly
durationnumber
#DenoKvSetOptions
interface DenoKvSetOptions extends CommonOptionsOptions for set operations.
| Name | Description |
|---|---|
expireIn | Time-to-live in milliseconds. |
Properties
- readonly
expireIn?numberTime-to-live in milliseconds. The entry will automatically expire after this duration.
#DenoKvSetResult
interface DenoKvSetResultResult of a set operation.
| Name | Description |
|---|---|
type | — |
ok | — |
versionstamp | — |
duration | — |
Properties
- readonly
type"deno-kv:set" - readonly
okboolean - readonly
versionstampstring - readonly
durationnumber
Functions
#createDenoKvClient
async function createDenoKvClient(config?: DenoKvClientConfig): Promise<DenoKvClient>Create a new Deno KV client instance.
The client provides key-value operations with support for atomic transactions, time-to-live (TTL), and prefix-based listing.
Parameters
config?DenoKvClientConfig- Deno KV client configuration (optional)
Returns
Promise<DenoKvClient> — A promise resolving to a new Deno KV client instance
Examples
Basic usage with in-memory database
const kv = await createDenoKvClient();
await kv.set(["users", "123"], { name: "Alice", email: "alice@example.com" });
const result = await kv.get<User>(["users", "123"]);
console.log(result.value); // { name: "Alice", email: "alice@example.com" }
await kv.close();
Using persistent storage
const kv = await createDenoKvClient({
path: "./data.kv",
});
Set with expiration (TTL)
await kv.set(["sessions", sessionId], sessionData, {
expireIn: 3600_000, // Expire in 1 hour
});
List entries by prefix
const result = await kv.list<User>({ prefix: ["users"] });
for (const entry of result.entries) {
console.log(entry.key, entry.value);
}
Atomic transactions
const atomicResult = await kv.atomic()
.check({ key: ["counter"], versionstamp: null })
.set(["counter"], 1)
.commit();
Using await using for automatic cleanup
await using kv = await createDenoKvClient();
await kv.set(["test"], "value");
// Client automatically closed when scope exits
#createDenoKvEntries
function createDenoKvEntries<T>(entries: DenoKvEntry<T>[]): DenoKvEntries<T>Creates a DenoKvEntries instance from an array of entries.
Parameters
entriesDenoKvEntry<T>[]
Type Aliases
#DenoKvResult
type DenoKvResult<T = unknown> = DenoKvGetResult<T> | DenoKvSetResult | DenoKvDeleteResult | DenoKvListResult<T> | DenoKvAtomicResultUnion of all Deno KV result types.
