or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cursor-navigation.mddatabase-operations.mdenhanced-database.mdindex-operations.mdindex.mdobject-store-operations.mdpromise-wrapping.mdtransaction-management.md
tile.json

tessl/npm-idb

A small wrapper that makes IndexedDB usable with promises and enhanced TypeScript support

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/idb@8.0.x

To install, run

npx @tessl/cli install tessl/npm-idb@8.0.0

index.mddocs/

IDB

IDB is a lightweight TypeScript wrapper around the browser's IndexedDB API that significantly improves usability while maintaining the core functionality. It transforms callback-based IDBRequest objects into promises, adds convenient shortcut methods for common database operations, provides enhanced transaction handling with automatic lifetime management, and includes TypeScript support with strongly-typed database schemas.

Package Information

  • Package Name: idb
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install idb

Core Imports

import { openDB, deleteDB, wrap, unwrap } from "idb";

For CommonJS:

const { openDB, deleteDB, wrap, unwrap } = require("idb");

Basic Usage

import { openDB } from "idb";

// Define database schema
interface MyDB {
  people: {
    key: number;
    value: {
      name: string;
      age: number;
    };
    indexes: { name: string };
  };
}

// Open database with schema
const db = await openDB<MyDB>("my-database", 1, {
  upgrade(db) {
    const peopleStore = db.createObjectStore("people", {
      keyPath: "id",
      autoIncrement: true,
    });
    peopleStore.createIndex("name", "name");
  },
});

// Use database with shortcut methods
await db.add("people", { name: "Alice", age: 30 });
const person = await db.get("people", 1);
const allPeople = await db.getAll("people");

// Iterate over all records using async iteration
const tx = db.transaction("people");
for await (const cursor of tx.store) {
  console.log(cursor.key, cursor.value);
}

Architecture

IDB is built around several key components:

  • Database Management: openDB and deleteDB functions for database lifecycle management
  • Promise Wrapping: Core wrap/unwrap system converting IDB objects to promise-based equivalents
  • Enhanced Interfaces: TypeScript interfaces (IDBPDatabase, IDBPTransaction, etc.) with promise-based methods
  • Shortcut Methods: Direct database operations without explicit transaction management
  • Async Iteration: Support for for await loops over cursors, stores, and indexes
  • Type Safety: Full TypeScript integration with strongly-typed database schemas

Capabilities

Database Operations

Core database lifecycle management including opening databases with upgrade callbacks, deleting databases, and handling database events.

function openDB<DBTypes extends DBSchema | unknown = unknown>(
  name: string,
  version?: number,
  { blocked, upgrade, blocking, terminated }: OpenDBCallbacks<DBTypes> = {}
): Promise<IDBPDatabase<DBTypes>>;

function deleteDB(
  name: string,
  { blocked }: DeleteDBCallbacks = {}
): Promise<void>;

Database Operations

Promise Wrapping

Low-level utilities for converting native IndexedDB objects to promise-based equivalents and vice versa.

function wrap(value: IDBDatabase): IDBPDatabase;
function wrap(value: IDBRequest<T>): Promise<T>;

function unwrap(value: IDBPDatabase): IDBDatabase;
function unwrap<T>(value: Promise<T>): IDBRequest<T>;

function replaceTraps(
  callback: (currentTraps: ProxyHandler<any>) => ProxyHandler<any>
): void;

Promise Wrapping

Enhanced Database Interface

Promise-based database interface with shortcut methods for common operations, eliminating the need for explicit transaction management in simple cases.

interface IDBPDatabase<DBTypes extends DBSchema | unknown = unknown> {
  // Transaction methods
  transaction<Name extends StoreNames<DBTypes>, Mode extends IDBTransactionMode = 'readonly'>(
    storeNames: Name,
    mode?: Mode,
    options?: IDBTransactionOptions
  ): IDBPTransaction<DBTypes, [Name], Mode>;

  // Shortcut methods
  add<Name extends StoreNames<DBTypes>>(
    storeName: Name,
    value: StoreValue<DBTypes, Name>,
    key?: StoreKey<DBTypes, Name> | IDBKeyRange
  ): Promise<StoreKey<DBTypes, Name>>;

  get<Name extends StoreNames<DBTypes>>(
    storeName: Name,
    query: StoreKey<DBTypes, Name> | IDBKeyRange
  ): Promise<StoreValue<DBTypes, Name> | undefined>;

  put<Name extends StoreNames<DBTypes>>(
    storeName: Name,
    value: StoreValue<DBTypes, Name>,
    key?: StoreKey<DBTypes, Name> | IDBKeyRange
  ): Promise<StoreKey<DBTypes, Name>>;
}

Enhanced Database Interface

Transaction Management

Enhanced transaction interface with automatic completion handling and convenient store access.

interface IDBPTransaction<
  DBTypes extends DBSchema | unknown = unknown,
  TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
  Mode extends IDBTransactionMode = 'readonly'
> {
  readonly mode: Mode;
  readonly objectStoreNames: TypedDOMStringList<TxStores[number]>;
  readonly db: IDBPDatabase<DBTypes>;
  readonly done: Promise<void>;
  readonly store: TxStores[1] extends undefined
    ? IDBPObjectStore<DBTypes, TxStores, TxStores[0], Mode>
    : undefined;

  objectStore<StoreName extends TxStores[number]>(
    name: StoreName
  ): IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;
}

Transaction Management

Object Store Operations

Enhanced object store interface with promise-based operations and async iteration support.

interface IDBPObjectStore<
  DBTypes extends DBSchema | unknown = unknown,
  TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
  StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
  Mode extends IDBTransactionMode = 'readonly'
> {
  // Core operations
  add: Mode extends 'readonly' ? undefined : (
    value: StoreValue<DBTypes, StoreName>,
    key?: StoreKey<DBTypes, StoreName> | IDBKeyRange
  ) => Promise<StoreKey<DBTypes, StoreName>>;

  get(
    query: StoreKey<DBTypes, StoreName> | IDBKeyRange
  ): Promise<StoreValue<DBTypes, StoreName> | undefined>;

  // Iteration support
  [Symbol.asyncIterator](): AsyncIterableIterator<
    IDBPCursorWithValueIteratorValue<DBTypes, TxStores, StoreName, unknown, Mode>
  >;
}

Object Store Operations

Index Operations

Enhanced index interface for querying data by secondary keys with full async iteration support.

interface IDBPIndex<
  DBTypes extends DBSchema | unknown = unknown,
  TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
  StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
  IndexName extends IndexNames<DBTypes, StoreName> = IndexNames<DBTypes, StoreName>,
  Mode extends IDBTransactionMode = 'readonly'
> {
  readonly objectStore: IDBPObjectStore<DBTypes, TxStores, StoreName, Mode>;

  get(
    query: IndexKey<DBTypes, StoreName, IndexName> | IDBKeyRange
  ): Promise<StoreValue<DBTypes, StoreName> | undefined>;

  openCursor(
    query?: IndexKey<DBTypes, StoreName, IndexName> | IDBKeyRange | null,
    direction?: IDBCursorDirection
  ): Promise<IDBPCursorWithValue<DBTypes, TxStores, StoreName, IndexName, Mode> | null>;
}

Index Operations

Cursor Navigation

Enhanced cursor interfaces with promise-based navigation and async iteration support for efficient data traversal.

interface IDBPCursor<
  DBTypes extends DBSchema | unknown = unknown,
  TxStores extends ArrayLike<StoreNames<DBTypes>> = ArrayLike<StoreNames<DBTypes>>,
  StoreName extends StoreNames<DBTypes> = StoreNames<DBTypes>,
  IndexName extends IndexNames<DBTypes, StoreName> | unknown = unknown,
  Mode extends IDBTransactionMode = 'readonly'
> {
  readonly key: IndexName extends IndexNames<DBTypes, StoreName>
    ? IndexKey<DBTypes, StoreName, IndexName>
    : StoreKey<DBTypes, StoreName>;
  readonly primaryKey: StoreKey<DBTypes, StoreName>;

  advance<T>(this: T, count: number): Promise<T | null>;
  continue<T>(this: T, key?: IndexName extends IndexNames<DBTypes, StoreName>
    ? IndexKey<DBTypes, StoreName, IndexName>
    : StoreKey<DBTypes, StoreName>): Promise<T | null>;

  [Symbol.asyncIterator](): AsyncIterableIterator<
    IDBPCursorIteratorValue<DBTypes, TxStores, StoreName, IndexName, Mode>
  >;
}

interface IDBPCursorWithValue<...> extends IDBPCursor<...> {
  readonly value: StoreValue<DBTypes, StoreName>;
}

Cursor Navigation

Types

interface DBSchema {
  [s: string]: DBSchemaValue;
}

interface DBSchemaValue {
  key: IDBValidKey;
  value: any;
  indexes?: IndexKeys;
}

interface IndexKeys {
  [s: string]: IDBValidKey;
}

interface OpenDBCallbacks<DBTypes extends DBSchema | unknown> {
  upgrade?(
    database: IDBPDatabase<DBTypes>,
    oldVersion: number,
    newVersion: number | null,
    transaction: IDBPTransaction<DBTypes, StoreNames<DBTypes>[], 'versionchange'>,
    event: IDBVersionChangeEvent
  ): void;
  blocked?(currentVersion: number, blockedVersion: number | null, event: IDBVersionChangeEvent): void;
  blocking?(currentVersion: number, blockedVersion: number | null, event: IDBVersionChangeEvent): void;
  terminated?(): void;
}

interface DeleteDBCallbacks {
  blocked?(currentVersion: number, event: IDBVersionChangeEvent): void;
}

type StoreNames<DBTypes extends DBSchema | unknown> = 
  DBTypes extends DBSchema ? KnownKeys<DBTypes> : string;

type StoreValue<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = 
  DBTypes extends DBSchema ? DBTypes[StoreName]['value'] : any;

type StoreKey<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = 
  DBTypes extends DBSchema ? DBTypes[StoreName]['key'] : IDBValidKey;

type IndexNames<DBTypes extends DBSchema | unknown, StoreName extends StoreNames<DBTypes>> = 
  DBTypes extends DBSchema ? keyof DBTypes[StoreName]['indexes'] & string : string;

type IndexKey<
  DBTypes extends DBSchema | unknown,
  StoreName extends StoreNames<DBTypes>,
  IndexName extends IndexNames<DBTypes, StoreName>
> = DBTypes extends DBSchema
  ? IndexName extends keyof DBTypes[StoreName]['indexes']
    ? DBTypes[StoreName]['indexes'][IndexName]
    : IDBValidKey
  : IDBValidKey;

interface TypedDOMStringList<T extends string> extends DOMStringList {
  contains(string: T): boolean;
  item(index: number): T | null;
  [index: number]: T;
  [Symbol.iterator](): IterableIterator<T>;
}

interface IDBTransactionOptions {
  durability?: 'default' | 'strict' | 'relaxed';
}