WebDB
A Promise wrapper around IndexedDB. Native IndexedDB is event-callback + transaction based:
every read or write is five steps (open → transaction → objectStore → request →
onsuccess/onerror). WebDB collapses that to await db.add({ storeName, data }).
API
new WebDB(options)
| Parameter | Description | Type | Default |
|---|---|---|---|
dbName |
Database name | string |
Required |
version |
Schema version; bump it whenever stores changes |
number |
1 |
stores |
Declarative object stores + indexes, created during an upgrade | IDBStoreSchema[] |
[] |
upgrade |
Escape hatch for migrations the schema cannot express, run after stores |
Function |
— |
Every method resolves or rejects with the same IDBResult shape, so callers only check error.
| Method | Description |
|---|---|
openDataBase() |
Open (and upgrade if needed) |
closeDataBase() |
Close and drop the handle |
refreshDatabase() |
Close then reopen |
deleteDatabase() |
Delete the database |
add({ storeName, data }) |
Insert; fails if the key exists |
update({ storeName, data }) |
Put — insert or overwrite |
readByKey({ storeName, key }) |
Read one record |
readAll({ storeName, query?, count? }) |
Read every record |
readByCursor({ storeName, keyRange?, direction? }) |
Walk with a cursor |
count({ storeName, query? }) |
Count records |
delete({ storeName, key }) |
Delete one record |
clear({ storeName }) |
Empty a store |
db.collection<T>(name)
A typed, forgiving handle on one store. Binds the store name once and returns plain values
instead of IDBResult.
| Member | Returns | On failure |
|---|---|---|
get(key) |
Promise<T | null> |
null |
all() |
Promise<T[]> |
[] |
count() |
Promise<number> |
0 |
add(value) |
Promise<boolean> |
false |
put(value) |
Promise<boolean> |
false |
remove(key) |
Promise<boolean> |
false |
clear() |
Promise<boolean> |
false |
const notes = db.collection('books_notes');
await notes.put(note); // false if it failed
const all = await notes.all(); // [] if it failedExample
import { WebDB } from 'ranuts';
const db = new WebDB({
dbName: 'read',
version: 4,
stores: [
{ name: 'books', options: { keyPath: 'id' }, indexes: [{ name: 'byAuthor', keyPath: 'author' }] },
{ name: 'notes', options: { keyPath: 'id' } },
],
});
await db.openDataBase();
await db.add({ storeName: 'books', data: { id: '1', title: 'Walden' } });
const { data } = await db.readByKey({ storeName: 'books', key: '1' });Notes
- Stores can only be created inside an upgrade transaction: that's why they are declared
up front rather than created after the database opens. Creating a missing store or index is
idempotent, so it is safe to keep the same
storesarray across versions. - Version downgrades self-heal. Opening with a version lower than what is on disk throws a
VersionError;WebDBparses the real version out of it, realigns and reopens instead of surfacing the error. - Upgrades are never blocked by this connection. Each open registers
onversionchange, so when another tab or worker asks for a higher version this connection closes itself. - Pair it with
singleFlightso concurrent callers share one open:const ready = singleFlight(() => db.openDataBase()).