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, expiration, and JSON serialization.
Example
const kv = new KV('data.db');
// Store any JSON-serializable data
kv.set('user:123', { name: 'John', age: 30 });
kv.set('counter', 42);
kv.set('active', true);
kv.set('dates', [new Date(), new Date()]);
// Use dot notation for nested properties
kv.set('user:123.name', 'John');
kv.set('user:123.settings.theme', 'dark');
// Retrieve data
const user = kv.get('user:123'); // { name: 'John', age: 30, settings: { theme: 'dark' } }
const name = kv.get('user:123.name'); // 'John'
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) => T | undefined;
set(key: string, value: any) => void;
setex(key: string, value: any, ttl: number) => void;
expire(key: string, ttl: number) => boolean;
ttl(key: string) => number;
delete(key: string) => void;
has(key: string) => boolean;
keys() => string[];
values() => any[];
count() => number;
clear() => void;
all() => Record<string, any>;
namespaces() => string[];
getCurrentNamespace() => string;
namespace(namespace: string) => KV;
[Symbol.iterator]() => Iterator<[string, any]>;
transaction(fn: () => T | Promise<T>) => Promise<T>;
}
- Implements:
Disposable
,AsyncDisposable
constructor
(path: string | Buffer | URL | DatabaseSync, options: KvOptions = {
enableWAL: true,
namespace: 'commandkit_kv',
}) => KV
Creates a new KV store instance
isOpen
() => boolean
Checks if the database connection is open
getDatabase
() => DatabaseSync
Gets the underlying SQLite database instance
close
() => void
Closes the database connection
[Symbol.dispose]
() =>
Disposable implementation - closes the database when disposed
[Symbol.asyncDispose]
() =>
AsyncDisposable implementation - closes the database when disposed
get
(key: string) => T | undefined
Retrieves a value by key
Example
// Store an object
kv.set('user:123', { name: 'John', age: 30, settings: { theme: 'dark' } });
// Get the entire object
const user = kv.get('user:123');
// { name: 'John', age: 30, settings: { theme: 'dark' } }
// Get nested properties using dot notation
const name = kv.get('user:123.name'); // 'John'
const theme = kv.get('user:123.settings.theme'); // 'dark'
set
(key: string, value: any) => void
Sets a key-value pair
Example
// Store primitive values
kv.set('counter', 42);
kv.set('active', true);
kv.set('name', 'John');
// Store objects
kv.set('user:123', { name: 'John', age: 30 });
// Store arrays
kv.set('tags', ['javascript', 'typescript', 'sqlite']);
// Store dates
kv.set('created', new Date());
// Store maps and sets
kv.set('permissions', new Map([['admin', true], ['user', false]]));
kv.set('unique_ids', new Set([1, 2, 3, 4, 5]));
// Use dot notation for nested properties
kv.set('user:123.settings.theme', 'dark');
kv.set('user:123.settings.notifications', true);
setex
(key: string, value: any, ttl: number) => void
Sets a key-value pair with expiration
Example
// Set with 1 hour expiration
kv.setex('session:123', { userId: 123, token: 'abc123' }, 60 * 60 * 1000);
// Set with 5 minutes expiration
kv.setex('temp:data', { cached: true, timestamp: Date.now() }, 5 * 60 * 1000);
// Use dot notation with expiration
kv.setex('user:123.temp_settings', { theme: 'light' }, 30 * 60 * 1000);
expire
(key: string, ttl: number) => boolean
Sets expiration for an existing key
Example
kv.set('user:123', { name: 'John', age: 30 });
// Set 30 minute expiration
if (kv.expire('user:123', 30 * 60 * 1000)) {
console.log('Expiration set successfully');
}
ttl
(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
(key: string) => void
Deletes a key-value pair
Example
kv.delete('user:123');
kv.delete('user:123.settings.theme'); // Delete nested property
has
(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');
}
if (kv.has('user:123.settings.theme')) {
console.log('Theme setting exists');
}
keys
() => string[]
Gets all keys in the current namespace (excluding expired keys)
Example
const keys = kv.keys();
console.log('All keys:', keys);
values
() => any[]
Gets all values in the current namespace (excluding expired keys)
Example
const values = kv.values();
console.log('All values:', values);
count
() => 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
() => void
Removes all key-value pairs from the current namespace
Example
kv.clear(); // Removes all entries in current namespace
all
() => Record<string, any>
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
() => string[]
Gets all available namespaces (tables) in the database
Example
const namespaces = kv.namespaces();
console.log('Available namespaces:', namespaces);
getCurrentNamespace
() => string
Gets the current namespace name
namespace
(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', { name: 'John', age: 30 });
configKv.set('theme', 'dark');
[Symbol.iterator]
() => Iterator<[string, any]>
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
(fn: () => T | Promise<T>) => Promise<T>
Executes a function within a transaction
Example
// Synchronous transaction
kv.transaction(() => {
kv.set('user:123', { name: 'John', age: 30 });
kv.set('user:456', { name: 'Jane', age: 25 });
// If any operation fails, all changes are rolled back
});
// Async transaction
await kv.transaction(async () => {
kv.set('user:123', { name: 'John', age: 30 });
await someAsyncOperation();
kv.set('user:456', { name: 'Jane', age: 25 });
// If any operation fails, all changes are rolled back
});