IndexedDB Local Data
Use IndexedDB for offline records and outbox queues.
Minimal Helper
type LedgerEntry = {
id: string;
amount: number;
note: string;
synced: boolean;
createdAt: string;
};
function openDb(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open('ledger', 1);
request.onupgradeneeded = () => {
const db = request.result;
db.createObjectStore('entries', { keyPath: 'id' });
db.createObjectStore('outbox', { keyPath: 'id' });
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
async function saveEntry(entry: LedgerEntry) {
const db = await openDb();
const tx = db.transaction(['entries', 'outbox'], 'readwrite');
tx.objectStore('entries').put(entry);
tx.objectStore('outbox').put({ id: entry.id, type: 'entry.create', payload: entry });
}
Sync-Safe Model
| Field | Purpose |
|---|---|
id | Client-generated idempotency key |
synced | UI can show pending state |
createdAt | Conflict and ordering context |
outbox type | Replay operation type |
outbox payload | Data needed for retry |
Add schema migrations before users have real data. Add export before you promise offline-first safety.