Skip to main content
Version: Next

KV

KV

A key-value store implementation using SQLite

This class provides a simple, persistent key-value storage solution with support for namespaces, automatic cleanup, iteration, and expiration.

Example

const kv = new KV('data.db');
kv.set('user:123', JSON.stringify({ name: 'John', age: 30 }));
const user = JSON.parse(kv.get('user:123') || '{}');

// Using namespaces
const userKv = kv.namespace('users');
userKv.set('123', JSON.stringify({ name: 'John' }));
Signature
class KV implements Disposable, AsyncDisposable {
constructor(path: string | Buffer | URL | DatabaseSync, options: KvOptions = {
enableWAL: true,
namespace: 'commandkit_kv',
})
isOpen() => boolean;
getDatabase() => DatabaseSync;
close() => void;
[Symbol.dispose]() => ;
[Symbol.asyncDispose]() => ;
get(key: string) => string | undefined;
set(key: string, value: string) => void;
setex(key: string, value: string, ttl: number) => void;
expire(key: string, ttl: number) => boolean;
ttl(key: string) => number;
delete(key: string) => void;
has(key: string) => boolean;
keys() => string[];
values() => string[];
count() => number;
clear() => void;
all() => Record<string, string>;
namespaces() => string[];
getCurrentNamespace() => string;
namespace(namespace: string) => KV;
[Symbol.iterator]() => Iterator<[string, string]>;
transaction(fn: () => T | Promise<T>) => Promise<T>;
}
  • Implements: Disposable, AsyncDisposable

constructor

method
(path: string | Buffer | URL | DatabaseSync, options: KvOptions = { enableWAL: true, namespace: 'commandkit_kv', }) => KV

Creates a new KV store instance

isOpen

method
() => boolean

Checks if the database connection is open

getDatabase

method
() => DatabaseSync

Gets the underlying SQLite database instance

close

method
() => void

Closes the database connection

[Symbol.dispose]

method
() =>

Disposable implementation - closes the database when disposed

[Symbol.asyncDispose]

method
() =>

AsyncDisposable implementation - closes the database when disposed

get

method
(key: string) => string | undefined

Retrieves a value by key

Example

const value = kv.get('my-key');
if (value) {
console.log('Found:', value);
}

set

method
(key: string, value: string) => void

Sets a key-value pair

Example

kv.set('user:123', JSON.stringify({ name: 'John' }));
kv.set('counter', '42');

setex

method
(key: string, value: string, ttl: number) => void

Sets a key-value pair with expiration

Example

// Set with 1 hour expiration
kv.setex('session:123', 'user_data', 60 * 60 * 1000);

// Set with 5 minutes expiration
kv.setex('temp:data', 'cached_value', 5 * 60 * 1000);

expire

method
(key: string, ttl: number) => boolean

Sets expiration for an existing key

Example

kv.set('user:123', 'user_data');

// Set 30 minute expiration
if (kv.expire('user:123', 30 * 60 * 1000)) {
console.log('Expiration set successfully');
}

ttl

method
(key: string) => number

Gets the time to live for a key

Example

const ttl = kv.ttl('user:123');
if (ttl > 0) {
console.log(`Key expires in ${ttl}ms`);
} else if (ttl === -2) {
console.log('Key has no expiration');
} else {
console.log('Key does not exist');
}

delete

method
(key: string) => void

Deletes a key-value pair

Example

kv.delete('user:123');

has

method
(key: string) => boolean

Checks if a key exists and is not expired

Example

if (kv.has('user:123')) {
console.log('User exists and is not expired');
}

keys

method
() => string[]

Gets all keys in the current namespace (excluding expired keys)

Example

const keys = kv.keys();
console.log('All keys:', keys);

values

method
() => string[]

Gets all values in the current namespace (excluding expired keys)

Example

const values = kv.values();
console.log('All values:', values);

count

method
() => number

Gets the total number of key-value pairs in the current namespace (excluding expired keys)

Example

const count = kv.count();
console.log(`Total entries: ${count}`);

clear

method
() => void

Removes all key-value pairs from the current namespace

Example

kv.clear(); // Removes all entries in current namespace

all

method
() => Record<string, string>

Gets all key-value pairs as an object (excluding expired keys)

Example

const all = kv.all();
console.log('All entries:', all);
// Output: { 'key1': 'value1', 'key2': 'value2' }

namespaces

method
() => string[]

Gets all available namespaces (tables) in the database

Example

const namespaces = kv.namespaces();
console.log('Available namespaces:', namespaces);

getCurrentNamespace

method
() => string

Gets the current namespace name

namespace

method
(namespace: string) => KV

Creates a new KV instance with a different namespace

Example

const userKv = kv.namespace('users');
const configKv = kv.namespace('config');

userKv.set('123', 'John Doe');
configKv.set('theme', 'dark');

[Symbol.iterator]

method
() => Iterator<[string, string]>

Iterator implementation for iterating over all non-expired key-value pairs

Example

for (const [key, value] of kv) {
console.log(`${key}: ${value}`);
}

// Or using spread operator
const entries = [...kv];

transaction

method
(fn: () => T | Promise<T>) => Promise<T>

Executes a function within a transaction

Example

// Synchronous transaction
kv.transaction(() => {
kv.set('user:123', JSON.stringify({ name: 'John' }));
kv.set('user:456', JSON.stringify({ name: 'Jane' }));
// If any operation fails, all changes are rolled back
});

// Async transaction
await kv.transaction(async () => {
kv.set('user:123', JSON.stringify({ name: 'John' }));
await someAsyncOperation();
kv.set('user:456', JSON.stringify({ name: 'Jane' }));
// If any operation fails, all changes are rolled back
});