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

enhanced-database.mddocs/

Enhanced Database Interface

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

Capabilities

Transaction Creation

Create transactions with enhanced promise-based interfaces.

/**
 * Start a new transaction for a single store
 * @param storeNames - The object store this transaction needs
 * @param mode - Transaction mode (readonly, readwrite, versionchange)
 * @param options - Transaction options including durability
 * @returns Enhanced transaction interface
 */
transaction<Name extends StoreNames<DBTypes>, Mode extends IDBTransactionMode = 'readonly'>(
  storeNames: Name,
  mode?: Mode,
  options?: IDBTransactionOptions
): IDBPTransaction<DBTypes, [Name], Mode>;

/**
 * Start a new transaction for multiple stores
 * @param storeNames - Array of object stores this transaction needs
 * @param mode - Transaction mode (readonly, readwrite, versionchange)
 * @param options - Transaction options including durability
 * @returns Enhanced transaction interface
 */
transaction<Names extends ArrayLike<StoreNames<DBTypes>>, Mode extends IDBTransactionMode = 'readonly'>(
  storeNames: Names,
  mode?: Mode,
  options?: IDBTransactionOptions
): IDBPTransaction<DBTypes, Names, Mode>;

Usage Examples:

// Single store transaction
const tx = db.transaction("users", "readwrite");
const userStore = tx.objectStore("users");
await userStore.add({ id: "1", name: "Alice" });
await tx.done; // Wait for transaction completion

// Multiple store transaction
const tx2 = db.transaction(["users", "posts"], "readwrite");
const userStore2 = tx2.objectStore("users");
const postStore = tx2.objectStore("posts");
await userStore2.add({ id: "1", name: "Bob" });
await postStore.add({ id: 1, authorId: "1", title: "Hello World" });
await tx2.done;

// Transaction with durability options
const tx3 = db.transaction("users", "readwrite", {
  durability: "strict" // Ensure data is written to disk immediately
});

// Different durability options
const fastTx = db.transaction("cache", "readwrite", {
  durability: "relaxed" // Better performance, less durability guarantees
});

const defaultTx = db.transaction("users", "readwrite", {
  durability: "default" // Browser default behavior
});

Object Store Management

Create and delete object stores during database upgrades.

/**
 * Creates a new object store
 * Throws "InvalidStateError" if not called within an upgrade transaction
 * @param name - Name of the object store
 * @param optionalParameters - Store configuration options
 * @returns Enhanced object store interface
 */
createObjectStore<Name extends StoreNames<DBTypes>>(
  name: Name,
  optionalParameters?: IDBObjectStoreParameters
): IDBPObjectStore<DBTypes, ArrayLike<StoreNames<DBTypes>>, Name, 'versionchange'>;

/**
 * Deletes the object store with the given name
 * Throws "InvalidStateError" if not called within an upgrade transaction
 * @param name - Name of the object store to delete
 */
deleteObjectStore(name: StoreNames<DBTypes>): void;

Usage Examples:

// During database upgrade
const db = await openDB("my-database", 2, {
  upgrade(db, oldVersion) {
    if (oldVersion < 1) {
      // Create object store with auto-incrementing keys
      const userStore = db.createObjectStore("users", {
        keyPath: "id",
        autoIncrement: true
      });
      
      // Create indexes
      userStore.createIndex("email", "email", { unique: true });
      userStore.createIndex("name", "name");
    }
    
    if (oldVersion < 2) {
      // Create additional store
      const postStore = db.createObjectStore("posts", {
        keyPath: "id",
        autoIncrement: true
      });
      postStore.createIndex("author", "authorId");
      
      // Remove old store if needed
      if (db.objectStoreNames.contains("old_store")) {
        db.deleteObjectStore("old_store");
      }
    }
  }
});

Shortcut Methods

Direct database operations that automatically create and manage transactions.

Add Operations

/**
 * Add a value to a store
 * Rejects if an item of a given key already exists in the store
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param value - Value to add
 * @param key - Optional key (if not using keyPath)
 * @returns Promise resolving to the key of the added item
 */
add<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  value: StoreValue<DBTypes, Name>,
  key?: StoreKey<DBTypes, Name> | IDBKeyRange
): Promise<StoreKey<DBTypes, Name>>;

Put Operations

/**
 * Put an item in the database
 * Replaces any item with the same key
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param value - Value to put
 * @param key - Optional key (if not using keyPath)
 * @returns Promise resolving to the key of the stored item
 */
put<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  value: StoreValue<DBTypes, Name>,
  key?: StoreKey<DBTypes, Name> | IDBKeyRange
): Promise<StoreKey<DBTypes, Name>>;

Get Operations

/**
 * Retrieves the value of the first record in a store matching the query
 * Resolves with undefined if no match is found
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param query - Key or key range to match
 * @returns Promise resolving to the value or undefined
 */
get<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  query: StoreKey<DBTypes, Name> | IDBKeyRange
): Promise<StoreValue<DBTypes, Name> | undefined>;

/**
 * Retrieves the value of the first record in an index matching the query
 * Resolves with undefined if no match is found
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param indexName - Name of the index within the store
 * @param query - Index key or key range to match
 * @returns Promise resolving to the value or undefined
 */
getFromIndex<Name extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, Name>>(
  storeName: Name,
  indexName: IndexName,
  query: IndexKey<DBTypes, Name, IndexName> | IDBKeyRange
): Promise<StoreValue<DBTypes, Name> | undefined>;

/**
 * Retrieves all values in a store that match the query
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param query - Key or key range to match (optional)
 * @param count - Maximum number of values to return (optional)
 * @returns Promise resolving to array of matching values
 */
getAll<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  query?: StoreKey<DBTypes, Name> | IDBKeyRange | null,
  count?: number
): Promise<StoreValue<DBTypes, Name>[]>;

/**
 * Retrieves all values in an index that match the query
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param indexName - Name of the index within the store
 * @param query - Index key or key range to match (optional)
 * @param count - Maximum number of values to return (optional)
 * @returns Promise resolving to array of matching values
 */
getAllFromIndex<Name extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, Name>>(
  storeName: Name,
  indexName: IndexName,
  query?: IndexKey<DBTypes, Name, IndexName> | IDBKeyRange | null,
  count?: number
): Promise<StoreValue<DBTypes, Name>[]>;

Key Operations

/**
 * Retrieves the key of the first record in a store that matches the query
 * Resolves with undefined if no match is found
 * @param storeName - Name of the store
 * @param query - Key or key range to match
 * @returns Promise resolving to the key or undefined
 */
getKey<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  query: StoreKey<DBTypes, Name> | IDBKeyRange
): Promise<StoreKey<DBTypes, Name> | undefined>;

/**
 * Retrieves the keys of records in a store matching the query
 * @param storeName - Name of the store
 * @param query - Key or key range to match (optional)
 * @param count - Maximum number of keys to return (optional)
 * @returns Promise resolving to array of matching keys
 */
getAllKeys<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  query?: StoreKey<DBTypes, Name> | IDBKeyRange | null,
  count?: number
): Promise<StoreKey<DBTypes, Name>[]>;

Delete and Clear Operations

/**
 * Deletes records in a store matching the given query
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param key - Key or key range to delete
 * @returns Promise that resolves when deletion is complete
 */
delete<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  key: StoreKey<DBTypes, Name> | IDBKeyRange
): Promise<void>;

/**
 * Deletes all records in a store
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @returns Promise that resolves when clearing is complete
 */
clear(name: StoreNames<DBTypes>): Promise<void>;

Count Operations

/**
 * Retrieves the number of records matching the given query in a store
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param key - Key or key range to count (optional)
 * @returns Promise resolving to the count
 */
count<Name extends StoreNames<DBTypes>>(
  storeName: Name,
  key?: StoreKey<DBTypes, Name> | IDBKeyRange | null
): Promise<number>;

/**
 * Retrieves the number of records matching the given query in an index
 * This creates a transaction automatically
 * @param storeName - Name of the store
 * @param indexName - Name of the index within the store
 * @param key - Index key or key range to count (optional)
 * @returns Promise resolving to the count
 */
countFromIndex<Name extends StoreNames<DBTypes>, IndexName extends IndexNames<DBTypes, Name>>(
  storeName: Name,
  indexName: IndexName,
  key?: IndexKey<DBTypes, Name, IndexName> | IDBKeyRange | null
): Promise<number>;

Shortcut Method Usage Examples:

import { openDB } from "idb";

const db = await openDB("my-database");

// Simple operations with automatic transaction management
await db.add("users", { name: "Alice", email: "alice@example.com" });
await db.put("users", { id: 1, name: "Bob", email: "bob@example.com" });

// Get operations
const user = await db.get("users", 1);
const userByEmail = await db.getFromIndex("users", "email", "alice@example.com");
const allUsers = await db.getAll("users");
const activeUsers = await db.getAllFromIndex("users", "status", "active");

// Key operations
const userKey = await db.getKey("users", IDBKeyRange.bound(1, 10));
const allUserKeys = await db.getAllKeys("users");

// Count operations
const totalUsers = await db.count("users");
const activeUserCount = await db.countFromIndex("users", "status", "active");

// Delete operations
await db.delete("users", 1);
await db.clear("users"); // Delete all users

// Working with key ranges
const recentUsers = await db.getAll("users", IDBKeyRange.lowerBound(100));
const userRange = await db.getAll("users", IDBKeyRange.bound(1, 10));

Database Properties

Enhanced database interface properties and metadata.

/**
 * The names of stores in the database
 */
readonly objectStoreNames: TypedDOMStringList<StoreNames<DBTypes>>;

Property Usage:

const db = await openDB("my-database");

// Check available stores
console.log("Available stores:", [...db.objectStoreNames]);

// Check if specific store exists
if (db.objectStoreNames.contains("users")) {
  const users = await db.getAll("users");
}

// Iterate over store names
for (const storeName of db.objectStoreNames) {
  const count = await db.count(storeName);
  console.log(`${storeName}: ${count} records`);
}

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