API Reference
Complete reference for all Valkeyrie methods and classes.
Table of Contents
Valkeyrie Class
Main database class for all operations.
Static Methods
Valkeyrie.withSchema()
Register a schema for validation and type inference.
static withSchema<TPattern extends Key, TSchema extends StandardSchemaV1>(
pattern: TPattern,
schema: TSchema
): ValkeyrieBuilderParameters:
pattern- Key pattern with wildcards (e.g.,['users', '*'])schema- Standard Schema-compatible validator (Zod, Valibot, ArkType)
Returns: ValkeyrieBuilder for chaining
Example:
import { z } from 'zod';
const userSchema = z.object({
name: z.string(),
email: z.string().email()
});
const db = await Valkeyrie
.withSchema(['users', '*'], userSchema)
.open('./data.db');Valkeyrie.open()
Open or create a database.
static async open(
path?: string,
options?: {
serializer?: () => Serializer;
destroyOnClose?: boolean;
}
): Promise<Valkeyrie>Parameters:
path- Optional file path. Omit for in-memory databaseoptions- Configuration optionsserializer- Custom serializer (default: V8 serializer)destroyOnClose- Delete database file on close (default:false)
Returns: Promise<Valkeyrie>
Example:
// In-memory
const db1 = await Valkeyrie.open();
// File-based
const db2 = await Valkeyrie.open('./data.db');
// With options
const db3 = await Valkeyrie.open('./temp.db', {
serializer: jsonSerializer,
destroyOnClose: true
});Valkeyrie.from()
Create and populate a database from a synchronous iterable.
static async from<T>(
iterable: Iterable<T>,
options: FromOptions<T>
): Promise<Valkeyrie>Parameters:
iterable- Array, Set, Map, or any iterableoptions- Configuration options
FromOptions:
interface FromOptions<T> {
prefix: Key; // Required
keyProperty: keyof T | ((item: T) => KeyPart); // Required
path?: string;
serializer?: () => Serializer;
destroyOnClose?: boolean;
expireIn?: number;
onProgress?: (processed: number, total?: number) => void;
onError?: 'stop' | 'continue';
onErrorCallback?: (error: Error, item: T) => void;
}Returns: Promise<Valkeyrie>
Example:
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
const db = await Valkeyrie.from(users, {
prefix: ['users'],
keyProperty: 'id',
path: './users.db'
});Valkeyrie.fromAsync()
Create and populate a database from an asynchronous iterable.
static async fromAsync<T>(
iterable: AsyncIterable<T>,
options: FromOptions<T>
): Promise<Valkeyrie>Parameters: Same as from()
Returns: Promise<Valkeyrie>
Example:
async function* fetchUsers() {
for (let page = 1; page <= 10; page++) {
const response = await fetch(`/api/users?page=${page}`);
const users = await response.json();
for (const user of users) yield user;
}
}
const db = await Valkeyrie.fromAsync(fetchUsers(), {
prefix: ['users'],
keyProperty: 'id'
});Instance Methods
get()
Retrieve a single value by key.
async get<T>(key: Key): Promise<EntryMaybe<T>>Parameters:
key- Array of key parts
Returns:
type EntryMaybe<T> =
| { key: Key; value: T; versionstamp: string }
| { key: Key; value: null; versionstamp: null }Example:
const entry = await db.get(['users', 'alice']);
if (entry.value !== null) {
console.log(entry.value); // User data
console.log(entry.versionstamp); // Version identifier
}getMany()
Retrieve multiple values at once.
async getMany<T>(keys: Key[]): Promise<EntryMaybe<T>[]>Parameters:
keys- Array of keys
Returns: Array of EntryMaybe<T>
Example:
const entries = await db.getMany([
['users', 'alice'],
['users', 'bob'],
['users', 'charlie']
]);
for (const entry of entries) {
if (entry.value) {
console.log(entry.value);
}
}set()
Store a value with the given key.
async set<T>(
key: Key,
value: T,
options?: {
expireIn?: number;
}
): Promise<{ ok: true; versionstamp: string }>Parameters:
key- Array of key partsvalue- Value to storeoptions- Optional configurationexpireIn- Time-to-live in milliseconds
Returns: Object with ok: true and versionstamp
Example:
await db.set(['users', 'alice'], {
name: 'Alice',
email: 'alice@example.com'
});
// With expiration
await db.set(['session', 'token'], 'abc123', {
expireIn: 3600000 // 1 hour
});delete()
Delete a value by key.
async delete(key: Key): Promise<void>Parameters:
key- Array of key parts
Returns: Promise<void>
Example:
await db.delete(['users', 'alice']);list()
List entries matching a selector.
list<T>(
selector: ListSelector,
options?: ListOptions
): AsyncIterableIterator<Entry<T>> & { cursor: string }ListSelector:
type ListSelector =
| { prefix: Key }
| { prefix: Key; start: Key }
| { prefix: Key; end: Key }
| { start: Key; end: Key }ListOptions:
interface ListOptions {
limit?: number;
cursor?: string;
reverse?: boolean;
}Returns: Async iterator with cursor property
Example:
// List with prefix
for await (const entry of db.list({ prefix: ['users'] })) {
console.log(entry.key, entry.value);
}
// With pagination
const page1 = db.list({ prefix: ['users'] }, { limit: 10 });
for await (const entry of page1) {
console.log(entry.value);
}
const cursor = page1.cursor;
const page2 = db.list({ prefix: ['users'] }, { limit: 10, cursor });
// Range query
for await (const entry of db.list({
prefix: ['users'],
start: ['alice'],
end: ['charlie']
})) {
console.log(entry.value);
}
// Reverse order
for await (const entry of db.list(
{ prefix: ['users'] },
{ reverse: true }
)) {
console.log(entry.value);
}watch()
Watch keys for changes in real-time.
watch<T>(keys: Key[]): ReadableStream<EntryMaybe<T>[]>Parameters:
keys- Array of keys to watch
Returns: ReadableStream that emits entry arrays
Example:
const stream = db.watch([
['users', 'alice'],
['users', 'bob']
]);
for await (const [aliceEntry, bobEntry] of stream) {
console.log('Alice:', aliceEntry.value);
console.log('Bob:', bobEntry.value);
}
// With manual control
const reader = stream.getReader();
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log('Changes:', value);
}
} finally {
await reader.cancel();
}atomic()
Create an atomic operation.
atomic(): AtomicOperationReturns: AtomicOperation instance
Example:
const result = await db.atomic()
.set(['users', 'alice'], { name: 'Alice' })
.set(['users', 'bob'], { name: 'Bob' })
.delete(['users', 'charlie'])
.commit();
if (result.ok) {
console.log('All operations succeeded');
}clear()
Remove all data from the database.
async clear(): Promise<void>Example:
await db.clear(); // Database is now emptydestroy()
Destroy the database (deletes the file).
async destroy(): Promise<void>Example:
await db.destroy(); // Database file is deletedcleanup()
Manually remove expired entries.
async cleanup(): Promise<void>Example:
await db.cleanup(); // Remove all expired entriesclose()
Close the database connection.
async close(): Promise<void>Example:
await db.close();
// With explicit resource management
await using db = await Valkeyrie.open('./data.db');
// Automatically closed when scope exitsAtomicOperation Class
Represents an atomic transaction.
Methods
check()
Add a version check.
check(...checks: AtomicCheck[]): thisAtomicCheck:
interface AtomicCheck {
key: Key;
versionstamp: string | null;
}Example:
const entry = await db.get(['counter']);
await db.atomic()
.check({ key: ['counter'], versionstamp: entry.versionstamp })
.set(['counter'], entry.value + 1)
.commit();set()
Add a set operation.
set<T>(key: Key, value: T, options?: { expireIn?: number }): thisExample:
await db.atomic()
.set(['key1'], 'value1')
.set(['key2'], 'value2', { expireIn: 60000 })
.commit();delete()
Add a delete operation.
delete(key: Key): thisExample:
await db.atomic()
.delete(['key1'])
.delete(['key2'])
.commit();sum()
Add a numeric sum operation.
sum(key: Key, value: bigint | KvU64): thisExample:
await db.atomic()
.sum(['counter'], 1n)
.sum(['another'], new KvU64(5n))
.commit();max()
Set to maximum value.
max(key: Key, value: bigint | KvU64): thisExample:
await db.atomic()
.max(['high-score'], 1000n)
.commit();min()
Set to minimum value.
min(key: Key, value: bigint | KvU64): thisExample:
await db.atomic()
.min(['low-price'], 50n)
.commit();commit()
Execute the atomic operation.
async commit(): Promise<
| { ok: true; versionstamp: string }
| { ok: false }
>Returns:
{ ok: true, versionstamp }if successful{ ok: false }if checks failed
Example:
const result = await db.atomic()
.set(['key'], 'value')
.commit();
if (result.ok) {
console.log('Success:', result.versionstamp);
} else {
console.log('Failed: version conflict');
}KvU64 Class
64-bit unsigned integer for atomic numeric operations.
Constructor
constructor(value: bigint)Example:
import { KvU64 } from 'valkeyrie/KvU64';
const counter = new KvU64(1000n);
await db.set(['counter'], counter);Properties
value
Get the bigint value.
readonly value: bigintExample:
const entry = await db.get(['counter']);
console.log(entry.value.value); // bigintMethods
valueOf()
Convert to bigint (for numeric operations).
valueOf(): biginttoString()
Convert to string.
toString(): stringtoJSON()
Convert to JSON representation.
toJSON(): stringErrors
ValidationError
Thrown when schema validation fails.
class ValidationError extends Error {
key: Key;
issues: Array<{
message: string;
path: (string | number)[];
}>;
}Example:
import { ValidationError } from 'valkeyrie';
try {
await db.set(['users', 'alice'], invalidData);
} catch (error) {
if (error instanceof ValidationError) {
console.log('Failed for key:', error.key);
console.log('Issues:', error.issues);
}
}Type Definitions
See Types Reference for complete TypeScript type definitions.
Summary
This API reference covers:
- ✅ All static and instance methods
- ✅ Complete parameter and return types
- ✅ Practical examples for each method
- ✅ Atomic operation API
- ✅ KvU64 numeric type
- ✅ Error types
For more details:
- Getting Started - Learn the basics
- Types Reference - TypeScript type definitions
- Advanced Patterns - Real-world usage
