import Dexie, { type EntityTable } from "dexie"; import type { LedgerEntry, SyncOperation } from "@cents/domain"; import type { LedgerRecord, UserPreference } from "./ledgers"; export type SyncMetadata = { id: string; cursor: string; updatedAt: string; }; export const db = new Dexie("cents") as Dexie & { entries: EntityTable; syncOperations: EntityTable; ledgers: EntityTable; userPreferences: EntityTable; syncMetadata: EntityTable; }; db.version(1).stores({ entries: "id, ledgerId, occurredAt, updatedAt, deletedAt", syncOperations: "id, ledgerId, createdAt, syncedAt", }); db.version(2).stores({ entries: "id, ledgerId, occurredAt, updatedAt, deletedAt", syncOperations: "id, ledgerId, createdAt, syncedAt", ledgers: "id, updatedAt, archivedAt", userPreferences: "id, userId, key, updatedAt", }); db.version(3).stores({ entries: "id, ledgerId, occurredAt, updatedAt, deletedAt", syncOperations: "id, ledgerId, createdAt, syncedAt", ledgers: "id, updatedAt, archivedAt", userPreferences: "id, userId, key, updatedAt", syncMetadata: "id, updatedAt", }); type LegacyEntry = LedgerEntry & { ledgerId?: string; ownerId?: string; ledgerIds?: string[] }; type LegacyOperation = SyncOperation & { ledgerId?: string; ledgerIds?: string[]; payload: LegacyEntry }; db.version(4).stores({ entries: "id, ownerId, *ledgerIds, occurredAt, updatedAt, deletedAt", syncOperations: "id, *ledgerIds, createdAt, syncedAt", ledgers: "id, updatedAt, archivedAt", userPreferences: "id, userId, key, updatedAt", syncMetadata: "id, updatedAt", }).upgrade(async (transaction) => { await transaction.table("entries").toCollection().modify((entry) => { entry.ownerId ??= entry.createdBy; entry.ledgerIds = entry.ledgerIds?.length ? [...new Set(entry.ledgerIds)] : entry.ledgerId ? [entry.ledgerId] : []; delete entry.ledgerId; }); await transaction.table("syncOperations").toCollection().modify((operation) => { operation.payload.ownerId ??= operation.payload.createdBy; operation.payload.ledgerIds = operation.payload.ledgerIds?.length ? [...new Set(operation.payload.ledgerIds)] : operation.payload.ledgerId ? [operation.payload.ledgerId] : []; operation.ledgerIds = operation.ledgerIds?.length ? [...new Set(operation.ledgerIds)] : operation.ledgerId ? [operation.ledgerId] : operation.payload.ledgerIds; delete operation.payload.ledgerId; delete operation.ledgerId; }); });