UNPKG

preact-missing-hooks

Version:

A lightweight, extendable collection of missing React-like hooks for Preact — plus fresh, powerful new ones designed specifically for modern Preact apps.

102 lines (93 loc) 3.42 kB
/** * Database controller: table(name), transaction(storeNames, mode, callback, options). * @module indexedDB/dbController */ import type { IndexedDBConfig, TransactionOptions } from "./types"; import type { ITableController } from "./tableController"; import { createTableController, createTransactionTableController, } from "./tableController"; /** Transaction context passed to the callback: provides table(name) bound to this transaction. */ export interface TransactionContext { /** Returns a table controller bound to this transaction. Use for all ops inside the callback. */ table: (name: string) => ITableController; } /** * Database controller built from an open IDBDatabase. * Exposes table(name) and transaction(...). */ export interface IDBController { /** Underlying IDBDatabase (read-only). */ readonly db: IDBDatabase; /** Returns true if an object store with the given name exists. */ hasTable: (name: string) => boolean; /** Returns a table controller for the given store (each op opens its own transaction). */ table: (name: string) => ITableController; /** * Runs a callback inside a single transaction. All operations in the callback use the same transaction. * @param storeNames - Object store names to include in the transaction. * @param mode - 'readonly' | 'readwrite'. * @param callback - Async or sync function receiving { table(name) }. Return value is ignored; await all ops inside. * @param options - Optional onSuccess/onError callbacks. * @returns Promise that resolves when the transaction completes (after all requests and the callback). */ transaction: <T = void>( storeNames: string[], mode: IDBTransactionMode, callback: (tx: TransactionContext) => T | Promise<T>, options?: TransactionOptions ) => Promise<void>; } function withTransactionCallbacks( promise: Promise<void>, options?: TransactionOptions ): Promise<void> { if (!options) return promise; return promise .then(() => options.onSuccess?.()) .catch((err: DOMException) => { options.onError?.(err); throw err; }); } /** * Creates a database controller from an open IDBDatabase instance. */ export function createDBController( db: IDBDatabase, _config: IndexedDBConfig ): IDBController { void _config; // Reserved for future config options return { get db(): IDBDatabase { return db; }, hasTable(name: string): boolean { return db.objectStoreNames.contains(name); }, table(name: string): ITableController { return createTableController(db, name); }, transaction<T = void>( storeNames: string[], mode: IDBTransactionMode, callback: (tx: TransactionContext) => T | Promise<T>, options?: TransactionOptions ): Promise<void> { const tx = db.transaction(storeNames, mode); const txContext: TransactionContext = { table: (tableName: string) => createTransactionTableController(tx, tableName), }; const txPromise = new Promise<void>((resolve, reject) => { tx.oncomplete = () => resolve(); tx.onerror = () => reject(tx.error ?? new DOMException("Transaction failed")); }); const callbackResult = callback(txContext); const promise = Promise.resolve(callbackResult).then(() => txPromise); return withTransactionCallbacks(promise, options); }, }; }