RocksDBStore — embedded LSM-tree key-value store

Read this page in the documentation

RocksDBStore — embedded LSM-tree key-value store Overview RocksDB is an embedded, in-process key-value store built on an LSM (log-structured merge) tree. There is no server: the database is opened directly against a filesystem path and lives inside your process. It exposes ordered key-value primitives — put/get/del, atomic batch writes, and ordered iteration — but no query language and no SQL-shaped surface (query(sql), identifier escaping, DDL). Because none of that fits the SQL-shaped Dialect interface, RocksDBStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes RocksDB's real KV surface directly. Identity: Property | Value | --------- | ----------- | name | 'rocksdb' | library | 'rocksdb' | The store is built on the rocksdb npm driver, an abstract-level implementation. Lazy loading — not a hard dependency The rocksdb driver is not a hard dependency of this package. It is loaded lazily via require('rocksdb') inside connect(), rather than a top-level import. Importing this module therefore does not require the driver to be installed — it is only needed when a RocksDB store is actually connected without an injected client. Injected client RocksDBStoreOptions accepts a pre-built client (any object matching RocksDBClientLike). When provided, connect() uses it directly and skips require('rocksdb') entirely. This is how the test suite injects a mock client (no driver, no filesystem), and how callers can supply a custom-configured client. Connection Build a store from connection options and call connect(): Connection options (RocksDBStoreOptions): Option | Type | Purpose | -------- | -------------------- | ------------------------------------------------------------------------------------------- | path | string | Filesystem path for the RocksDB database directory. Defaults to './data/rocksdb'. | client | RocksDBClientLike | A pre-built client to use directly (mock or custom). When set, the driver is not required. | When no client is provided, connect() calls require('rocksdb') and opens RocksDB(path). Injected-client form Supply your own client (or a mock) to bypass driver-based construction: Methods Every operation resolves the client via a private guard: using any method before connect() (or after disconnect()) throws a ConnectionError. Driver failures are wrapped in a DatabaseError (preserving the original error) with a RocksDB <action> failed: … message. Lifecycle Method | Signature | Behavior | ------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires rocksdb and opens RocksDB(path). Idempotent when already connected. Wraps failures in ConnectionError. | disconnect | disconnect(): Promise<void> | Best-effort client.close(), then clears connection state. | isConnected| isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): RocksDBClientLike | Returns the underlying client for operations not wrapped here. Throws ConnectionError if not connected. | Key-value operations Method | Signature | Behavior | ------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | put | put(key: string, value: unknown): Promise<void> | Writes (or overwrites) the value at key. Routes to client.put(key, value). | get | get(key: string): Promise<unknown> | Reads the value at key. Routes to client.get(key). | del | del(key: string): Promise<void> | Deletes the value at key. Routes to client.del(key). | batch | batch(ops: RocksDBBatchOp[]): Promise<void> | Applies a list of put/del operations as a single atomic batch, passed straight through to client.batch(ops). | list | list(prefix?: string): Promise<string[]> | Lists keys in order via client.iterator(). With no prefix, iterates with {}. With prefix, restricts to the range { gte: prefix, lt: prefix + '\xff' }. | RocksDBBatchOp is the entry type for a batch(): Example Verification status Unit / mock-verified only. The tests in tests/nosql/rocksdb.test.ts are fully mock-driven: a fake client whose methods are jest spies (with an async-generator iterator) is injected via RocksDBStoreOptions.client. The real rocksdb driver is not installed, and there is no filesystem and no network in the test run — because a client is injected, connect() never reaches require('rocksdb'). What this proves: Each method routes to the correct client call with the expected arguments (put(key, value), get(key), del(key), batch(ops)). list() collects keys from the iterator, and list(prefix) builds the { gte, lt } prefix-scan range. Lifecycle: connecting via an injected client without loading the driver, disconnect() closing the client, idempotent re-connect, and ConnectionError before connect() / via getClient() when not connected. Error handling: put/get failures wrapped in DatabaseError. What this does not prove: live execution against a real RocksDB database on disk. The call/response shapes are verified against the driver's documented contract, but end-to-end execution against the native engine has not been exercised here. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories