A small wrapper that makes IndexedDB usable with promises and enhanced TypeScript support
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Low-level utilities for converting native IndexedDB objects to promise-based equivalents and vice versa. These functions provide the core transformation that enables IDB's promise-based API.
Enhances native IDB objects with promise-based helpers and typed interfaces.
/**
* Enhance an IDB database with helpers
* @param value - Native IDBDatabase to enhance
* @returns Enhanced database with promise-based methods
*/
function wrap(value: IDBDatabase): IDBPDatabase;
/**
* Enhance an IDB index with helpers
* @param value - Native IDBIndex to enhance
* @returns Enhanced index with promise-based methods
*/
function wrap(value: IDBIndex): IDBPIndex;
/**
* Enhance an IDB object store with helpers
* @param value - Native IDBObjectStore to enhance
* @returns Enhanced object store with promise-based methods
*/
function wrap(value: IDBObjectStore): IDBPObjectStore;
/**
* Enhance an IDB transaction with helpers
* @param value - Native IDBTransaction to enhance
* @returns Enhanced transaction with promise-based methods
*/
function wrap(value: IDBTransaction): IDBPTransaction;
/**
* Convert an IDB open database request to a promise
* @param value - Native IDBOpenDBRequest
* @returns Promise resolving to enhanced database
*/
function wrap(value: IDBOpenDBRequest): Promise<IDBPDatabase | undefined>;
/**
* Convert any IDB request to a promise
* @param value - Native IDBRequest
* @returns Promise resolving to the request result
*/
function wrap<T>(value: IDBRequest<T>): Promise<T>;Usage Examples:
import { wrap } from "idb";
// Wrap a native database (rarely needed - use openDB instead)
const nativeDB = await new Promise((resolve, reject) => {
const request = indexedDB.open("my-database");
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
const enhancedDB = wrap(nativeDB);
// Wrap individual components (useful for migration from native code)
const nativeTransaction = nativeDB.transaction(["users"], "readwrite");
const enhancedTransaction = wrap(nativeTransaction);
const nativeStore = nativeTransaction.objectStore("users");
const enhancedStore = wrap(nativeStore);
// Convert requests to promises
const nativeRequest = nativeStore.add({ name: "Alice" });
const result = await wrap(nativeRequest);Reverts enhanced IDB objects back to their native equivalents.
/**
* Revert an enhanced cursor with value to native IDBCursorWithValue
* @param value - Enhanced cursor to revert
* @returns Native IDBCursorWithValue
*/
function unwrap(value: IDBPCursorWithValue<any, any, any, any, any>): IDBCursorWithValue;
/**
* Revert an enhanced cursor to native IDBCursor
* @param value - Enhanced cursor to revert
* @returns Native IDBCursor
*/
function unwrap(value: IDBPCursor<any, any, any, any, any>): IDBCursor;
/**
* Revert an enhanced database to native IDBDatabase
* @param value - Enhanced database to revert
* @returns Native IDBDatabase
*/
function unwrap(value: IDBPDatabase<any>): IDBDatabase;
/**
* Revert an enhanced index to native IDBIndex
* @param value - Enhanced index to revert
* @returns Native IDBIndex
*/
function unwrap(value: IDBPIndex<any, any, any, any, any>): IDBIndex;
/**
* Revert an enhanced object store to native IDBObjectStore
* @param value - Enhanced object store to revert
* @returns Native IDBObjectStore
*/
function unwrap(value: IDBPObjectStore<any, any, any, any>): IDBObjectStore;
/**
* Revert an enhanced transaction to native IDBTransaction
* @param value - Enhanced transaction to revert
* @returns Native IDBTransaction
*/
function unwrap(value: IDBPTransaction<any, any, any>): IDBTransaction;
/**
* Revert a database promise back to native IDBOpenDBRequest
* @param value - Promise for enhanced database
* @returns Native IDBOpenDBRequest
*/
function unwrap<T extends any>(value: Promise<IDBPDatabase<T>>): IDBOpenDBRequest;
/**
* Revert a database promise back to native IDBOpenDBRequest
* @param value - Promise for enhanced database
* @returns Native IDBOpenDBRequest
*/
function unwrap(value: Promise<IDBPDatabase>): IDBOpenDBRequest;
/**
* Revert any promise back to native IDBRequest
* @param value - Promise to revert
* @returns Native IDBRequest
*/
function unwrap<T>(value: Promise<T>): IDBRequest<T>;Usage Examples:
import { openDB, unwrap } from "idb";
// Get enhanced database
const enhancedDB = await openDB("my-database");
// Revert to native for legacy code integration
const nativeDB = unwrap(enhancedDB);
// Use native API
const nativeTransaction = nativeDB.transaction(["users"], "readonly");
const nativeStore = nativeTransaction.objectStore("users");
// Mix enhanced and native APIs as needed
const enhancedTransaction = enhancedDB.transaction("users");
const nativeStore2 = unwrap(enhancedTransaction.store);
// Revert promises to requests (useful for event handling)
const getUserPromise = enhancedDB.get("users", "user123");
const nativeRequest = unwrap(getUserPromise);
nativeRequest.addEventListener("success", (event) => {
console.log("Request succeeded:", event.target.result);
});Advanced functionality for customizing the behavior of wrapped objects.
/**
* Replace the proxy traps used for wrapping IDB objects
* @param callback - Function that receives current traps and returns new traps
*/
function replaceTraps(
callback: (currentTraps: ProxyHandler<any>) => ProxyHandler<any>
): void;Advanced Usage:
import { replaceTraps } from "idb";
// Add custom logging to all wrapped objects
replaceTraps((currentTraps) => ({
...currentTraps,
get(target, prop, receiver) {
console.log(`Accessing property: ${String(prop)}`);
return currentTraps.get!(target, prop, receiver);
}
}));
// Custom behavior for specific properties
replaceTraps((currentTraps) => ({
...currentTraps,
get(target, prop, receiver) {
if (prop === "customMethod") {
return () => console.log("Custom method called");
}
return currentTraps.get!(target, prop, receiver);
}
}));When migrating existing code from native IndexedDB to IDB:
// Before: Native IndexedDB
const request = indexedDB.open("my-database");
request.onsuccess = () => {
const db = request.result;
const transaction = db.transaction(["users"], "readwrite");
const store = transaction.objectStore("users");
const addRequest = store.add({ name: "Alice" });
addRequest.onsuccess = () => {
console.log("User added");
};
};
// After: Using IDB with openDB (recommended)
const db = await openDB("my-database");
await db.add("users", { name: "Alice" });
console.log("User added");
// Alternative: Using wrap for gradual migration
const nativeDB = await new Promise((resolve, reject) => {
const request = indexedDB.open("my-database");
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
const enhancedDB = wrap(nativeDB);
await enhancedDB.add("users", { name: "Alice" });When you need to interface with existing code that expects native IDB objects:
import { openDB, unwrap } from "idb";
async function legacyFunction(nativeDB: IDBDatabase) {
// Legacy code expects native IDBDatabase
const transaction = nativeDB.transaction(["users"], "readonly");
// ... legacy operations
}
// Use enhanced database normally
const enhancedDB = await openDB("my-database");
// Convert for legacy function
await legacyFunction(unwrap(enhancedDB));
// Continue using enhanced database
const users = await enhancedDB.getAll("users");