{"id":16290,"library":"abstract-level","title":"Abstract Key-Value Database Class","description":"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.","status":"active","version":"3.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/Level/abstract-level","tags":["javascript","abstract-level","level","leveldb","typescript"],"install":[{"cmd":"npm install abstract-level","lang":"bash","label":"npm"},{"cmd":"yarn add abstract-level","lang":"bash","label":"yarn"},{"cmd":"pnpm add abstract-level","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Primary class for extending. Prefer ESM `import` as the package targets Node.js >=18 and ships ES modules first.","wrong":"const AbstractLevel = require('abstract-level')","symbol":"AbstractLevel","correct":"import { AbstractLevel } from 'abstract-level'"},{"note":"Used for extending sublevel implementations. It's a named export from the main package.","wrong":"import AbstractSublevel from 'abstract-level/sublevel'","symbol":"AbstractSublevel","correct":"import { AbstractSublevel } from 'abstract-level'"},{"note":"When only using the type declaration, `import type` is recommended for clarity and build optimization in TypeScript.","symbol":"AbstractLevel","correct":"import type { AbstractLevel } from 'abstract-level'"}],"quickstart":{"code":"import { Level } from 'level';\nimport type { AbstractLevel, AbstractBatchOperation } from 'abstract-level';\n\ninterface MyValue { x: number; name: string; }\n\nasync function runDbExample() {\n  // In a real application, replace 'level' with your chosen LevelDB implementation.\n  // The generic types specify key and value types.\n  const db: AbstractLevel<string, MyValue> = new Level<string, MyValue>('./my-db-path', {\n    valueEncoding: 'json' // This will automatically JSON.stringify/parse values\n  });\n\n  try {\n    console.log('Opening database...');\n    await db.open();\n\n    await db.put('item1', { x: 1, name: 'First Item' });\n    await db.put('item2', { x: 2, name: 'Second Item' });\n\n    const value1 = await db.get('item1');\n    console.log(`Value for item1: ${JSON.stringify(value1)}`);\n\n    // Batch operations\n    const batchOperations: AbstractBatchOperation<string, MyValue>[] = [\n      { type: 'put', key: 'item3', value: { x: 3, name: 'Third Item' } },\n      { type: 'del', key: 'item1' }\n    ];\n    await db.batch(batchOperations);\n\n    const value3 = await db.get('item3');\n    console.log(`Value for item3: ${JSON.stringify(value3)}`);\n\n    const deletedValue = await db.get('item1');\n    console.log(`Value for item1 after delete (should be undefined): ${deletedValue}`);\n\n    console.log('Iterating through remaining items:');\n    for await (const [key, value] of db.iterator()) {\n      console.log(`Key: ${key}, Value: ${JSON.stringify(value)}`);\n    }\n\n  } catch (error) {\n    console.error('Database operation failed:', error);\n  } finally {\n    console.log('Closing database...');\n    await db.close();\n  }\n}\n\nrunDbExample();","lang":"typescript","description":"This quickstart demonstrates basic database operations (put, get, batch, iterate) using a `level` implementation conforming to `abstract-level`, highlighting type safety with generics and modern async/await patterns."},"warnings":[{"fix":"Ensure your `AbstractLevel` implementation fully supports `iterator.seek()`. If you are an implementer, add the `seek` method to your iterator. If you are a consumer, verify your chosen database implementation adheres to the v3 specification.","message":"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.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade your Node.js environment to version 18 or higher.","message":"Version 3.0.0 introduced new language features, requiring Node.js >=18. Older Node.js versions are no longer supported.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Update your code to use `await` or `.then()` syntax for all asynchronous database operations. For example, `db.get('key', callback)` becomes `await db.get('key')`.","message":"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.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Adjust error handling logic to check for `undefined` return values instead of catching specific 'not found' errors. For example, `try { await db.get('key') } catch (err)` becomes `const value = await db.get('key'); if (value === undefined) { /* not found */ }`.","message":"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.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Always use a concrete implementation that extends `AbstractLevel`, such as `level`, `classic-level`, or `memory-level`, for your database instances. `import { Level } from 'level'; const db = new Level('./db');`.","message":"`abstract-level` is an abstract class, not a concrete database implementation. Direct instantiation of `AbstractLevel` is not intended for end-user applications.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Explicitly define key and value types: `const db = new Level<string, MyValue>('./db', { valueEncoding: 'json' });`.","message":"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.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Change to promise-based API: `const value = await db.get('key');` or `db.get('key').then(value => ...);`.","cause":"Attempting to use callback-style `db.get('key', callback)` after upgrading to `abstract-level` v2.0.0 or later, which switched to Promises.","error":"TypeError: db.get is not a function"},{"fix":"Upgrade your concrete LevelDB implementation (e.g., `level`, `classic-level`) to a version that satisfies `abstract-level` v3.0.0 requirements, or downgrade `abstract-level` if you cannot upgrade the implementation.","cause":"Your chosen LevelDB implementation does not support the mandatory `iterator.seek()` method, which became required in `abstract-level` v3.0.0.","error":"Error: Iterator.seek() is not implemented"},{"fix":"Update your Node.js environment to version 18.x or later.","cause":"`abstract-level` v3.0.0 and above requires Node.js version 18 or higher due to new language features.","error":"RangeError: Invalid or unsupported Node.js version"},{"fix":"When creating your database instance, specify the generic types for keys and values, e.g., `const db = new Level<string, MyDataType>('./db', { valueEncoding: 'json' });`.","cause":"TypeScript error indicating that the generic type parameters for keys and values were not specified, leading to `unknown` types when interacting with the database.","error":"Property 'value' does not exist on type 'unknown'."}],"ecosystem":"npm"}