CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-idb

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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';
}

docs

cursor-navigation.md

database-operations.md

enhanced-database.md

index-operations.md

index.md

object-store-operations.md

promise-wrapping.md

transaction-management.md

tile.json