@yorozu/db-idb
v1.0.151
Published
IndexedDB driver for @yorozu/db
Readme
@yorozu/db-idb
IndexedDB driver for @yorozu/db.
Setup
import { createIdbDriver } from "@yorozu/db-idb"
import type { Logger } from "@yorozu/log"
let driver = createIdbDriver({
dbName: "app", // default: schema.name
indexedDB, // default: globalThis.indexedDB
IDBKeyRange, // default: globalThis.IDBKeyRange
log, // optional Logger; silent default
deferPut: (name) => name !== "meta",
autoFlush: true, // opt-in; or { pendingPuts: 32, idleMs: 1000 }
})
let db = await driver.open(schema)Logger is optional. Internally: opts.log ?? init("yorozu-db-idb", "driver"). Silent default is init with no handlers (or the host passes disabled).
deferPut: when it returns false for a collection, put({ flush: "batch" }) still writes immediately. Default: every collection may batch.
Musts
- Object store / index names match
CollectionDef(no extra prefixes). - Reserved index
"__pk": primary-key walk, even if not inCollectionDef.indexes. scan(..., { direction: "rev" })returns the highest keys first; omit = fwd.scan(..., { keysOnly: true })usesopenKeyCursor. Never readscursor.value. OmitScanHit.value.- Prefix TTL:
scan("by-evict", { lt: [cutoff], keysOnly: true })matches[storedAt, bytes]withstoredAt < cutoffvia IDB array keys ([cutoff] < [cutoff, 0]). getMany/putMany/deleteshare one IDB transaction.count()with pending isstore.count()plus a key probe per pending pk (nogetAllKeys).getManyof only-pending keys skipsIDBDatabase.transaction. Duplicate keys share oneget.scan({ limit })keeps an early-stop cursor when pending exists (skip pending PKs, then merge).- Default
putflush is"now"."batch"buffers untildb.flush()or the next"rw"transact commit, not"r".flush()coalesces by(collection, pk)in one multi-storereadwritetx. flush({ reason, signal }): already-abortedsignalrejects withAbortError(orsignal.reason) before taking the lock; in-flight writes finish. Read transactflushstays a no-op.- Opt-in
autoFlush: omitted = off.true→{ pendingPuts: 32, idleMs: 1000 }. After batch puts, idle-flush viarequestIdlewith{ reason: "idle" }; atpendingPutsdistinct pks, re-arm with timeout 0. Successful flush / close cancels the idle handle. Keep files/avatars immediate via hostdeferPut— default is still every collection may batch. - Nested
transactthrows. Concurrenttransactserializes on a mutex (tx facade; nestedtransactrejects without taking the lock). - Call
await db.flush()beforeclose(). Do not leave{ flush: "batch" }puts outstanding across multi-tab upgrades (onversionchangecloses the connection without flushing). drop(schema)closes tracked connections andindexedDB.deleteDatabase.
