Abstract Key-Value Database Class
raw JSON →abstract-level provides an abstract interface for building lexicographically sorted key-value databases, serving as the foundation for the entire LevelDB ecosystem in JavaScript/TypeScript. It defines the core API, including operations like `put`, `get`, `del`, `batch`, and iterators, along with support for encodings, sublevels, events, and hooks. The current stable version is `3.1.1`, with active development reflected in regular minor and patch releases, and major versions introducing significant breaking changes (e.g., v2 to v3). Its key differentiator is being a specification rather than an implementation, allowing concrete database modules like `level` or `classic-level` to adhere to a common, well-defined API. It ships with comprehensive TypeScript types and leverages modern JavaScript features.
Common errors
error TypeError: db.get is not a function ↓
const value = await db.get('key'); or db.get('key').then(value => ...);. error Error: Iterator.seek() is not implemented ↓
level, classic-level) to a version that satisfies abstract-level v3.0.0 requirements, or downgrade abstract-level if you cannot upgrade the implementation. error RangeError: Invalid or unsupported Node.js version ↓
error Property 'value' does not exist on type 'unknown'. ↓
const db = new Level<string, MyDataType>('./db', { valueEncoding: 'json' });. Warnings
breaking Version 3.0.0 made `iterator.seek()` a mandatory feature. Implementations must now provide this method, and consumers relying on `abstract-level`'s interface will expect its presence. ↓
breaking Version 3.0.0 introduced new language features, requiring Node.js >=18. Older Node.js versions are no longer supported. ↓
breaking Version 2.0.0 removed callbacks in favor of Promises for all asynchronous operations. Methods like `put`, `get`, `del`, `batch`, and `close` now return Promises. ↓
breaking Version 2.0.0 changed the behavior for non-existent entries: `get()` now returns `undefined` instead of throwing a `NotFoundError` (or similar error) when a key is not found. ↓
gotcha `abstract-level` is an abstract class, not a concrete database implementation. Direct instantiation of `AbstractLevel` is not intended for end-user applications. ↓
gotcha TypeScript users must correctly specify generic type parameters for keys and values when instantiating `AbstractLevel` implementations and sublevels, e.g., `Level<string, MyDataType>`. Failing to do so can lead to `any` types or incorrect type inference. ↓
Install
npm install abstract-level yarn add abstract-level pnpm add abstract-level Imports
- AbstractLevel wrong
const AbstractLevel = require('abstract-level')correctimport { AbstractLevel } from 'abstract-level' - AbstractSublevel wrong
import AbstractSublevel from 'abstract-level/sublevel'correctimport { AbstractSublevel } from 'abstract-level' - AbstractLevel
import type { AbstractLevel } from 'abstract-level'
Quickstart
import { Level } from 'level';
import type { AbstractLevel, AbstractBatchOperation } from 'abstract-level';
interface MyValue { x: number; name: string; }
async function runDbExample() {
// In a real application, replace 'level' with your chosen LevelDB implementation.
// The generic types specify key and value types.
const db: AbstractLevel<string, MyValue> = new Level<string, MyValue>('./my-db-path', {
valueEncoding: 'json' // This will automatically JSON.stringify/parse values
});
try {
console.log('Opening database...');
await db.open();
await db.put('item1', { x: 1, name: 'First Item' });
await db.put('item2', { x: 2, name: 'Second Item' });
const value1 = await db.get('item1');
console.log(`Value for item1: ${JSON.stringify(value1)}`);
// Batch operations
const batchOperations: AbstractBatchOperation<string, MyValue>[] = [
{ type: 'put', key: 'item3', value: { x: 3, name: 'Third Item' } },
{ type: 'del', key: 'item1' }
];
await db.batch(batchOperations);
const value3 = await db.get('item3');
console.log(`Value for item3: ${JSON.stringify(value3)}`);
const deletedValue = await db.get('item1');
console.log(`Value for item1 after delete (should be undefined): ${deletedValue}`);
console.log('Iterating through remaining items:');
for await (const [key, value] of db.iterator()) {
console.log(`Key: ${key}, Value: ${JSON.stringify(value)}`);
}
} catch (error) {
console.error('Database operation failed:', error);
} finally {
console.log('Closing database...');
await db.close();
}
}
runDbExample();