Configure persistence
import { createClient, IndexedDBPersistenceAdapter } from "nostrbase";
const db = createClient({
namespace: "my-app",
relays: ["wss://relay.example"],
persistence: {
adapter: new IndexedDBPersistenceAdapter("my-app-cache"),
batchSize: 100,
flushInterval: 25,
onError: (error) => console.error(error),
},
sync: { tables: ["todos"], initial: true, reconnect: true },
});
await db.ready();
const cached = await db.from("todos").select().local();
ready() restores verified signed events and queued writes. Deletion tombstones load before records. The cache preserves the original event content, including encrypted ciphertext. It never saves decrypted private record data. Ephemeral broadcast and presence events are excluded.
The memory adapter implements the same interface:
import { MemoryPersistenceAdapter } from "nostrbase";
const adapter = new MemoryPersistenceAdapter();
It keeps data only while that adapter exists. IndexedDB survives a browser restart, subject to the browser’s storage policy and available space. Both adapters partition cache and queue entries by the client namespace. Use separate database names for profiles when you need separate device storage.
Writes use batches of at most batchSize events. flushInterval starts a short write delay; it does not guarantee a durable commit before a page closes. Call await db.persistence?.flush() at a checkpoint and await db.closeAsync() for an orderly close. Storage failures reject ready() or flush() and reach onError for background writes. A failed cache batch remains pending for explicit retry.
Cached history and tombstones have no automatic size eviction. Deleting tombstones can make deleted records reappear. Monitor browser storage usage for large collections.