@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 AsyncDisposable for 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

import { createDenoKvClient } from "@probitas/client-deno-kv";

const kv = await createDenoKvClient();

// 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();

await kv.close();

Using with using Statement

import { createDenoKvClient } from "@probitas/client-deno-kv";

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
PackageDescription
`@probitas/client`Core utilities and types
`@probitas/client-redis`Redis client

Installation

deno add jsr:@probitas/client-deno-kv

Classes

class

#DenoKvAtomicBuilderImpl

class DenoKvAtomicBuilderImpl implements DenoKvAtomicBuilder

Implementation of DenoKvAtomicBuilder.

NameDescription
check()
set()
delete()
sum()
min()
max()
commit()
Constructor
new DenoKvAtomicBuilderImpl(kv: Deno.Kv, options?: AtomicBuilderOptions)
Methods
check(): unknown
set(): unknown
delete(): unknown
sum(): unknown
min(): unknown
max(): unknown
commit(): unknown
class

#DenoKvConnectionError

class DenoKvConnectionError extends DenoKvError

Error thrown when a connection to Deno KV fails.

This typically occurs when:

  • Network errors prevent reaching Deno Deploy KV
  • Authentication/authorization fails
  • Service is unavailable
NameDescription
name
kind
Constructor
new DenoKvConnectionError(message: string, options?: ErrorOptions)
Properties
  • readonlynamestring
  • readonlykind"connection"
class

#DenoKvError

class DenoKvError extends ClientError

Base error class for Deno KV operations.

Use the kind property to distinguish between error types:

  • "kv": General KV operation error
  • "quota": Quota limit exceeded
  • "connection": Network/connection failure
NameDescription
name
Constructor
new DenoKvError(message: string, _: unknown, options?: ErrorOptions)
Properties
  • readonlynamestring

Interfaces

interface

#AtomicBuilderOptions

interface AtomicBuilderOptions

Options for atomic operations.

NameDescription
throwOnErrorWhether to throw errors instead of returning them in the result.
Properties
  • readonlythrowOnError?boolean

    Whether to throw errors instead of returning them in the result.

interface

#DenoKvAtomicBuilder

interface DenoKvAtomicBuilder

Builder for atomic KV operations.

NameDescription
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[]): this

Add version checks to the atomic operation. If any check fails, the entire operation will fail.

Parameters
  • _Deno.AtomicCheck[]
set<T = any>(key: Deno.KvKey, value: T, options?: { expireIn?: number }): this

Set a value in the KV store.

Parameters
  • keyDeno.KvKey
  • valueT
  • options?{ expireIn?: number }
delete(key: Deno.KvKey): this

Delete a key from the KV store.

Parameters
  • keyDeno.KvKey
sum(key: Deno.KvKey, n: bigint): this

Atomically add to a bigint value (Deno.KvU64).

Parameters
  • keyDeno.KvKey
  • nbigint
min(key: Deno.KvKey, n: bigint): this

Atomically set to minimum of current and provided value.

Parameters
  • keyDeno.KvKey
  • nbigint
max(key: Deno.KvKey, n: bigint): this

Atomically set to maximum of current and provided value.

Parameters
  • keyDeno.KvKey
  • nbigint
commit(): Promise<DenoKvAtomicResult>

Commit the atomic operation.

interface

#DenoKvAtomicOptions

interface DenoKvAtomicOptions extends DenoKvOptions

Options for atomic operations.

interface

#DenoKvAtomicResultCheckFailed

interface DenoKvAtomicResultCheckFailed extends DenoKvAtomicResultBase

Atomic operation check failed (version mismatch).

This is NOT an error - it's an expected outcome when using optimistic concurrency. Retry the operation with updated versionstamps.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrornull
  • readonlyversionstampnull
interface

#DenoKvAtomicResultCommitted

interface DenoKvAtomicResultCommitted extends DenoKvAtomicResultBase

Atomic operation successfully committed.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
  • readonlyversionstampstring
interface

#DenoKvAtomicResultError

interface DenoKvAtomicResultError extends DenoKvAtomicResultBase

Atomic operation failed with KV error.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrorDenoKvError
  • readonlyversionstampnull
interface

#DenoKvAtomicResultFailure

interface DenoKvAtomicResultFailure extends DenoKvAtomicResultBase

Atomic operation failed with connection error.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedfalse
  • readonlyokfalse
  • readonlyerrorDenoKvFailureError
  • readonlyversionstampnull
interface

#DenoKvClient

interface DenoKvClient extends AsyncDisposable

Deno KV client for Probitas scenario testing.

NameDescription
configClient 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
Methods
get<T = any>(
  key: Deno.KvKey,
  options?: DenoKvGetOptions,
): Promise<DenoKvGetResult<T>>

Get a single value by key.

Parameters
getMany<T extends readonly any[]>(
  keys: readonly [unknown],
  options?: DenoKvGetOptions,
): Promise<unknown>

Get multiple values by keys.

Parameters
set<T = any>(
  key: Deno.KvKey,
  value: T,
  options?: DenoKvSetOptions,
): Promise<DenoKvSetResult>

Set a value.

Parameters
delete(
  key: Deno.KvKey,
  options?: DenoKvDeleteOptions,
): Promise<DenoKvDeleteResult>

Delete a key.

Parameters
list<T = any>(
  selector: Deno.KvListSelector,
  options?: DenoKvListOptions,
): Promise<DenoKvListResult<T>>

List entries by selector.

Parameters
atomic(options?: DenoKvAtomicOptions): DenoKvAtomicBuilder

Create an atomic operation builder.

Parameters
close(): Promise<void>

Close the KV connection.

interface

#DenoKvClientConfig

interface DenoKvClientConfig extends DenoKvOptions

Configuration for DenoKvClient.

NameDescription
pathPath to the KV database file.
Properties
  • readonlypath?string

    Path to the KV database file. If not specified, uses in-memory storage or Deno Deploy's KV.

interface

#DenoKvDeleteOptions

interface DenoKvDeleteOptions extends DenoKvOptions

Options for delete operations.

interface

#DenoKvDeleteResultError

interface DenoKvDeleteResultError extends DenoKvDeleteResultBase

Delete operation result with KV error.

NameDescription
processed
ok
error
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrorDenoKvError
interface

#DenoKvDeleteResultFailure

interface DenoKvDeleteResultFailure extends DenoKvDeleteResultBase

Delete operation result with connection failure.

NameDescription
processed
ok
error
Properties
interface

#DenoKvDeleteResultSuccess

interface DenoKvDeleteResultSuccess extends DenoKvDeleteResultBase

Successful delete operation result.

NameDescription
processed
ok
error
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
interface

#DenoKvEntry

interface DenoKvEntry<T = any>

A single entry in the KV store.

NameDescription
key
value
versionstamp
Properties
  • readonlykeyDeno.KvKey
  • readonlyvalueT
  • readonlyversionstampstring
interface

#DenoKvGetOptions

interface DenoKvGetOptions extends DenoKvOptions

Options for get operations.

interface

#DenoKvGetResultError

interface DenoKvGetResultError<T = any> extends DenoKvGetResultBase<T>

Get operation result with KV error (quota exceeded, etc.).

NameDescription
processed
ok
error
key
value
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrorDenoKvError
  • readonlykeyDeno.KvKey
  • readonlyvaluenull
  • readonlyversionstampnull
interface

#DenoKvGetResultFailure

interface DenoKvGetResultFailure<T = any> extends DenoKvGetResultBase<T>

Get operation result with connection failure.

NameDescription
processed
ok
error
key
value
versionstamp
Properties
  • readonlyprocessedfalse
  • readonlyokfalse
  • readonlyerrorDenoKvFailureError
  • readonlykeynull
  • readonlyvaluenull
  • readonlyversionstampnull
interface

#DenoKvGetResultSuccess

interface DenoKvGetResultSuccess<T = any> extends DenoKvGetResultBase<T>

Successful get operation result.

NameDescription
processed
ok
error
key
value
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
  • readonlykeyDeno.KvKey
  • readonlyvalueT | null
  • readonlyversionstampstring | null
interface

#DenoKvListOptions

interface DenoKvListOptions extends DenoKvOptions

Options for list operations.

NameDescription
limitMaximum number of entries to return.
cursorCursor for pagination.
reverseWhether to iterate in reverse order.
Properties
  • readonlylimit?number

    Maximum number of entries to return.

  • readonlycursor?string

    Cursor for pagination.

  • readonlyreverse?boolean

    Whether to iterate in reverse order.

interface

#DenoKvListResultError

interface DenoKvListResultError<T = any> extends DenoKvListResultBase<T>

List operation result with KV error.

NameDescription
processed
ok
error
entries
Properties
interface

#DenoKvListResultFailure

interface DenoKvListResultFailure<T = any> extends DenoKvListResultBase<T>

List operation result with connection failure.

NameDescription
processed
ok
error
entries
Properties
interface

#DenoKvListResultSuccess

interface DenoKvListResultSuccess<T = any> extends DenoKvListResultBase<T>

Successful list operation result.

NameDescription
processed
ok
error
entries
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
  • readonlyentriesreadonly DenoKvEntry<T>[]
interface

#DenoKvOptions

interface DenoKvOptions extends CommonOptions

Options for Deno KV operations.

Extends CommonOptions with error handling behavior configuration.

NameDescription
throwOnErrorWhether to throw errors instead of returning them in the result.
Properties
  • readonlythrowOnError?boolean

    Whether to throw errors instead of returning them in the result.

    • false (default): Errors are returned in the result's error property
    • true: Errors are thrown as exceptions

    This applies to both KV errors (quota exceeded, etc.) and connection errors. Note: Atomic check failures are NOT errors and will never be thrown.

interface

#DenoKvSetOptions

interface DenoKvSetOptions extends DenoKvOptions

Options for set operations.

NameDescription
expireInTime-to-live in milliseconds.
Properties
  • readonlyexpireIn?number

    Time-to-live in milliseconds. The entry will automatically expire after this duration.

interface

#DenoKvSetResultError

interface DenoKvSetResultError extends DenoKvSetResultBase

Set operation result with KV error (quota exceeded, etc.).

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyokfalse
  • readonlyerrorDenoKvError
  • readonlyversionstampnull
interface

#DenoKvSetResultFailure

interface DenoKvSetResultFailure extends DenoKvSetResultBase

Set operation result with connection failure.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedfalse
  • readonlyokfalse
  • readonlyerrorDenoKvFailureError
  • readonlyversionstampnull
interface

#DenoKvSetResultSuccess

interface DenoKvSetResultSuccess extends DenoKvSetResultBase

Successful set operation result.

NameDescription
processed
ok
error
versionstamp
Properties
  • readonlyprocessedtrue
  • readonlyoktrue
  • readonlyerrornull
  • readonlyversionstampstring

Functions

function

#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
Returns

Promise<DenoKvClient> — A promise resolving to a new Deno KV client instance

Examples

Basic usage with in-memory database

import { createDenoKvClient } from "@probitas/client-deno-kv";

interface User {
  name: string;
  email: string;
}

const kv = await createDenoKvClient();

await kv.set(["users", "123"], { name: "Alice", email: "alice@example.com" });

const result = await kv.get<User>(["users", "123"]);
if (result.ok) {
  console.log(result.value);  // { name: "Alice", email: "alice@example.com" }
}

await kv.close();

Using persistent storage

import { createDenoKvClient } from "@probitas/client-deno-kv";

const kv = await createDenoKvClient({
  path: "./data.kv",
});

await kv.close();

Set with expiration (TTL)

import { createDenoKvClient } from "@probitas/client-deno-kv";

const kv = await createDenoKvClient();
const sessionId = "abc123";
const sessionData = { userId: "123", token: "xyz" };

await kv.set(["sessions", sessionId], sessionData, {
  expireIn: 3600_000,  // Expire in 1 hour
});

await kv.close();

List entries by prefix

import { createDenoKvClient } from "@probitas/client-deno-kv";

interface User {
  name: string;
  email: string;
}

const kv = await createDenoKvClient();

const result = await kv.list<User>({ prefix: ["users"] });
if (result.ok) {
  for (const entry of result.entries) {
    console.log(entry.key, entry.value);
  }
}

await kv.close();

Atomic transactions

import { createDenoKvClient } from "@probitas/client-deno-kv";

const kv = await createDenoKvClient();

const atomicResult = await kv.atomic()
  .check({ key: ["counter"], versionstamp: null })
  .set(["counter"], 1)
  .commit();

await kv.close();

Using await using for automatic cleanup

import { createDenoKvClient } from "@probitas/client-deno-kv";

await using kv = await createDenoKvClient();

await kv.set(["test"], "value");
// Client automatically closed when scope exits

Error handling with Failure pattern

import { createDenoKvClient } from "@probitas/client-deno-kv";

async function example() {
  const kv = await createDenoKvClient();

  const result = await kv.get<string>(["key"]);

  if (!result.ok) {
    if (!result.processed) {
      // Connection failure
      console.error("Connection failed:", result.error.message);
    } else {
      // KV error (quota exceeded, etc.)
      console.error("KV error:", result.error.message);
    }
    await kv.close();
    return;
  }

  console.log("Value:", result.value);
  await kv.close();
}

Using throwOnError for traditional exception handling

import { createDenoKvClient, DenoKvError } from "@probitas/client-deno-kv";

const kv = await createDenoKvClient({ throwOnError: true });

try {
  const result = await kv.get<string>(["key"]);
  console.log("Value:", result.value);
} catch (error) {
  if (error instanceof DenoKvError) {
    console.error("KV error:", error.message);
  }
}

await kv.close();

Types

type

#DenoKvAtomicResult

type DenoKvAtomicResult = DenoKvAtomicResultCommitted
  | DenoKvAtomicResultCheckFailed
  | DenoKvAtomicResultError
  | DenoKvAtomicResultFailure

Result of an atomic operation.

Use ok and error to distinguish between outcomes:

  • ok === true: Committed successfully
  • ok === false && error === null: Check failed (retry with new versionstamp)
  • ok === false && error !== null: KV error or connection failure
type

#DenoKvDeleteResult

type DenoKvDeleteResult = DenoKvDeleteResultSuccess | DenoKvDeleteResultError | DenoKvDeleteResultFailure

Result of a delete operation.

type

#DenoKvFailureError

type DenoKvFailureError = DenoKvConnectionError | AbortError | TimeoutError

Error types that indicate the operation was not processed. These are errors that occur before the operation reaches the Deno KV server.

type

#DenoKvGetResult

type DenoKvGetResult<T = any> = DenoKvGetResultSuccess<T> | DenoKvGetResultError<T> | DenoKvGetResultFailure<T>

Result of a get operation.

Use ok to check for success, then narrow the type:

  • ok === true: Success - value may be present
  • ok === false && processed === true: KV error (quota, etc.)
  • ok === false && processed === false: Connection failure
type

#DenoKvListResult

type DenoKvListResult<T = any> = DenoKvListResultSuccess<T>
  | DenoKvListResultError<T>
  | DenoKvListResultFailure<T>

Result of a list operation.

type

#DenoKvResult

type DenoKvResult<T = any> = DenoKvGetResult<T>
  | DenoKvSetResult
  | DenoKvDeleteResult
  | DenoKvListResult<T>
  | DenoKvAtomicResult

Union of all Deno KV result types.

type

#DenoKvSetResult

type DenoKvSetResult = DenoKvSetResultSuccess | DenoKvSetResultError | DenoKvSetResultFailure

Result of a set operation.

Search Documentation