LevelDBStore — embedded ordered key-value store

Read this page in the documentation

LevelDBStore — embedded ordered key-value store Overview LevelDB is an embedded, in-process ordered key-value store (no server), accessed here through the level package — an abstract-level implementation. The database is opened directly against a filesystem path and lives inside your process. It exposes ordered KV primitives — put/get/del, atomic batch writes, and ordered iteration via db.iterator() — but no query language and no SQL-shaped surface (query(sql), identifier escaping, DDL). Because none of that fits the SQL-shaped Dialect interface, LevelDBStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes LevelDB's real KV surface directly. Identity: Property | Value | --------- | ------------ | name | 'leveldb' | library | 'level' | Lazy loading — not a hard dependency The level driver is not a hard dependency of this package. It is loaded lazily via require('level') 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 LevelDB store is actually connected without an injected client. On load, connect() resolves the constructor as mod.Level ?? mod and opens new Level(path). Injected client LevelDBStoreOptions accepts a pre-built client (any object matching LevelDBClientLike). When provided, connect() uses it directly and skips require('level') 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 (LevelDBStoreOptions): Option | Type | Purpose | -------- | -------------------- | ------------------------------------------------------------------------------------------- | path | string | Filesystem path for the LevelDB database directory. Defaults to './data/leveldb'. | client | LevelDBClientLike | 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('level') and opens new Level(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 LevelDB <action> failed: … message. Lifecycle Method | Signature | Behavior | ------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------- | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires level and opens new Level(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(): LevelDBClientLike | 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: LevelDBBatchOp[]): 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' }. | LevelDBBatchOp is the entry type for a batch(): Example Verification status Unit / mock-verified only. The tests in tests/nosql/leveldb.test.ts are fully mock-driven: a fake client whose methods are jest spies (with an async-generator iterator) is injected via LevelDBStoreOptions.client. The real level 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('level'). 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/del failures wrapped in DatabaseError. What this does not prove: live execution against a real LevelDB 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