olmdb
Version:
Optimistic LMDB. A very fast embedded key/value store featuring ACID optimistic read/write-transactions, based on LMDB.
263 lines (262 loc) • 11.9 kB
TypeScript
export { DatabaseError } from "./lowlevel.js";
/**
* Union type representing the supported data formats for keys and values.
* Can be a Uint8Array, ArrayBuffer, or string.
*/
export type Data = Uint8Array | ArrayBuffer | string;
/**
* Attach some arbitrary user data to the current transaction context, which is
* attached to the currently running (async) task.
* @param key - A symbol key to store data in the current transaction context.
* @param value - The value to store.
* @throws {TypeError} If called outside of a transaction context.
* @example
* ```typescript
* const MY_SYMBOL = Symbol("myKey");
* await transact(async () => {
* setTransactionData(MY_SYMBOL, "myValue");
* await somethingAsync(); // Can be interleaved with other transactions
* const value = getTransactionData(MY_SYMBOL);
* console.log(value); // "myValue"
* });
* ```
*/
export declare function setTransactionData(key: symbol, value: any): void;
/**
* Retrieves data from the current transaction context.
* @param key - A symbol key to retrieve data from the current transaction context.
* @returns - The value associated with the key, or undefined if not set.
* @throws {TypeError} If called outside of a transaction context.
*/
export declare function getTransactionData(key: symbol): any;
/**
* Retrieves a value from the database by key within the current transaction.
*
* @param key - The key to look up as a Uint8Array, ArrayBuffer, or string.
* @returns The value associated with the key as a Uint8Array, or undefined if not found.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if key exceeds maximum allowed length.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
export declare function get(key: Data): Uint8Array | undefined;
/**
* Retrieves a value from the database by key within the current transaction.
*
* @param key - The key to look up as a Uint8Array, ArrayBuffer, or string.
* @returns The value associated with the key as an ArrayBuffer, or undefined if not found.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if key exceeds maximum allowed length.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
export declare function getBuffer(key: Data): ArrayBuffer | undefined;
/**
* Retrieves a value from the database by key within the current transaction and decodes it as a string.
*
* @param key - The key to look up as a Uint8Array, ArrayBuffer, or string.
* @returns The value associated with the key as a UTF-8 decoded string, or undefined if not found.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if key exceeds maximum allowed length.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
export declare function getString(key: Data): string | undefined;
/**
* Stores a key-value pair in the database within the current transaction.
*
* @param key - The key to store as a Uint8Array, ArrayBuffer, or string.
* @param val - The value to associate with the key as a Uint8Array, ArrayBuffer, or string.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if key exceeds maximum allowed length.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
export declare function put(key: Data, val: Data): void;
/**
* Deletes a key-value pair from the database within the current transaction.
*
* @param key - The key to delete as a Uint8Array, ArrayBuffer, or string.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if key exceeds maximum allowed length.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
export declare function del(key: Data): void;
/**
* Initialize the database with the specified directory path.
* This function may only be called once. If it is not called before the first transact(),
* the database will be automatically initialized with the default directory.
*
* @param dbDir - Optional directory path for the database (defaults to environment variable $OLMDB_DIR or "./.olmdb").
* @throws {DatabaseError} With code "DUP_INIT" if database is already initialized.
* @throws {DatabaseError} With code "CREATE_DIR_FAILED" if directory creation fails.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*
* @example
* ```typescript
* init("./my-database");
* ```
*/
export declare function init(dbDir?: string): void;
/**
* Registers a callback to be executed when the current transaction is reverted (aborted due to error).
* The callback will be executed outside of transaction context.
*
* @param callback - Function to execute when transaction is reverted
* @throws {TypeError} If called outside of a transaction context
*/
export declare function onRevert(callback: () => void): void;
/**
* Registers a callback to be executed when the current transaction commits successfully.
* The callback will be executed outside of transaction context.
*
* @param callback - Function to execute when transaction commits
* @throws {TypeError} If called outside of a transaction context
*/
export declare function onCommit(callback: () => void): void;
/**
* Executes a function within a database transaction context.
*
* All database operations (get, put, del) must be performed within a transaction.
* Transactions are automatically committed if the function completes successfully,
* or aborted if an error occurs. Failed transactions may be automatically retried
* up to 6 times in case of validation conflicts.
*
* @template T - The return type of the transaction function
* @param fn - The function to execute within the transaction context
* @returns A promise that resolves with the function's return value
* @throws {TypeError} If nested transactions are attempted
* @throws {DatabaseError} With code "RACING_TRANSACTION" if the transaction fails after retries due to conflicts
* @throws {DatabaseError} With code "TRANSACTION_FAILED" if the transaction fails for other reasons
* @throws {DatabaseError} With code "TXN_LIMIT" if maximum number of transactions is reached
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors
*
* @example
* ```typescript
* const result = await transact(() => {
* const value = get(keyBytes);
* if (value) {
* put(keyBytes, newValueBytes);
* }
* return value;
* });
* ```
*/
export declare function transact<T>(fn: () => T): Promise<T>;
/**
* Represents a key-value pair returned by the iterator
*/
export interface DbEntry<K, V> {
key: K;
value: V;
}
/**
* Database iterator that implements the standard TypeScript iterator protocol
*/
export declare class DbIterator<K, V> extends Iterator<DbEntry<K, V>, undefined> implements Iterator<DbEntry<K, V>, undefined> {
private iteratorId;
private convertKey;
private convertValue;
constructor(iteratorId: number, convertKey: (buffer: ArrayBuffer) => K, convertValue: (buffer: ArrayBuffer) => V);
[Symbol.iterator](): DbIterator<K, V>;
/**
* Advances the iterator to the next key-value pair.
*
* @returns An IteratorResult with the next DbEntry or done: true if no more entries.
* @throws {DatabaseError} With code "INVALID_ITERATOR" if iterator is invalid or already closed.
* @throws {DatabaseError} With code "LMDB-{code}" for LMDB-specific errors.
*/
next(): IteratorResult<DbEntry<K, V>>;
/**
* Closes the iterator and frees its resources.
* Should be called when done iterating to prevent resource leaks.
*
* @throws {DatabaseError} With code "INVALID_ITERATOR" if iterator is invalid or already closed.
*/
close(): void;
}
/**
* Creates an iterator to scan through database entries within the current transaction.
*
* The iterator implements the standard TypeScript iterator protocol and can be used with for...of loops.
* Supports both forward and reverse iteration with optional start and end boundaries.
*
* @template K - The type to convert keys to (defaults to Uint8Array).
* @template V - The type to convert values to (defaults to Uint8Array).
* @param opts - Configuration options for the scan operation.
* @param opts.start - Optional starting key for iteration. If not provided, starts from the beginning/end.
* @param opts.end - Optional ending key for iteration. Iteration stops before reaching this key.
* @param opts.reverse - Whether to iterate in reverse order (defaults to false).
* @param opts.keyConvert - Function to convert key ArrayBuffers to type K (defaults to asArray).
* @param opts.valueConvert - Function to convert value ArrayBuffers to type V (defaults to asArray).
* @returns A DbIterator instance.
* @throws {TypeError} If called outside of a transaction context.
* @throws {DatabaseError} With code "INVALID_TRANSACTION" if transaction is invalid or already closed.
* @throws {DatabaseError} With code "KEY_TOO_LONG" if start or end key exceeds maximum allowed length.
* @throws {DatabaseError} With code "ITERATOR_LIMIT" if maximum number of iterators is reached.
* @throws {DatabaseError} With code "OUT_OF_MEMORY" if memory allocation fails.
*
* @example
* ```typescript
* await transact(() => {
* // Iterate over all entries
* for (const { key, value } of scan()) {
* console.log('Key:', key, 'Value:', value);
* }
*
* // Iterate with string conversion
* for (const { key, value } of scan({
* keyConvert: asString,
* valueConvert: asString
* })) {
* console.log('Key:', key, 'Value:', value);
* }
*
* // Iterate with boundaries
* for (const { key, value } of scan({
* start: "prefix_",
* end: "prefix~"
* })) {
* console.log('Key:', key, 'Value:', value);
* }
*
* // Manual iteration control
* const iter = scan({ reverse: true });
* const first = iter.next();
* iter.close(); // Always close when done early
* });
* ```
*/
export declare function scan<K = Uint8Array, V = Uint8Array>(opts?: ScanOptions<K, V>): DbIterator<K, V>;
interface ScanOptions<K = Uint8Array, V = Uint8Array> {
start?: Data;
end?: Data;
reverse?: boolean;
keyConvert?: (buffer: ArrayBuffer) => K;
valueConvert?: (buffer: ArrayBuffer) => V;
}
/**
* Converts an ArrayBuffer to a Uint8Array.
* Helper function for use with scan() keyConvert and valueConvert options.
*
* @param buffer - The ArrayBuffer to convert.
* @returns A new Uint8Array view of the buffer.
*/
export declare function asArray(buffer: ArrayBuffer): Uint8Array;
/**
* Returns the ArrayBuffer as-is.
* Helper function for use with scan() keyConvert and valueConvert options.
*
* @param buffer - The ArrayBuffer to return.
* @returns The same ArrayBuffer.
*/
export declare function asBuffer(buffer: ArrayBuffer): ArrayBuffer;
/**
* Converts an ArrayBuffer to a UTF-8 decoded string.
* Helper function for use with scan() keyConvert and valueConvert options.
*
* @param buffer - The ArrayBuffer to decode.
* @returns A UTF-8 decoded string.
*/
export declare function asString(buffer: ArrayBuffer): string;