/* * db.ts * Zyquo Cloud Web * * Author: Simon-Pierre Boucher * Mail: contact@spboucher.ai * * Tiny promise wrapper around IndexedDB — no external dependency (every * dependency is key-theft surface). One database, versioned schema. */ const DB_NAME = 'zyquo.cloud.web' const DB_VERSION = 1 export const STORE_CONVERSATIONS = 'conversations' let dbPromise: Promise | null = null export function openDB(): Promise { if (dbPromise) return dbPromise dbPromise = new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION) request.onupgradeneeded = () => { const db = request.result // v1: conversations store keyed by id, indexed by updatedAt for sorting. if (!db.objectStoreNames.contains(STORE_CONVERSATIONS)) { const store = db.createObjectStore(STORE_CONVERSATIONS, { keyPath: 'id' }) store.createIndex('updatedAt', 'updatedAt') } } request.onsuccess = () => { request.result.onversionchange = () => request.result.close() resolve(request.result) } request.onerror = () => reject(request.error ?? new Error('IndexedDB open failed')) request.onblocked = () => reject(new Error('IndexedDB open blocked')) }) return dbPromise } function requestToPromise(request: IDBRequest): Promise { return new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result) request.onerror = () => reject(request.error ?? new Error('IndexedDB request failed')) }) } export async function dbGet(store: string, key: string): Promise { const db = await openDB() const tx = db.transaction(store, 'readonly') return requestToPromise(tx.objectStore(store).get(key) as IDBRequest) } export async function dbGetAll(store: string): Promise { const db = await openDB() const tx = db.transaction(store, 'readonly') return requestToPromise(tx.objectStore(store).getAll() as IDBRequest) } export async function dbPut(store: string, value: unknown): Promise { const db = await openDB() const tx = db.transaction(store, 'readwrite') await requestToPromise(tx.objectStore(store).put(value)) } export async function dbDelete(store: string, key: string): Promise { const db = await openDB() const tx = db.transaction(store, 'readwrite') await requestToPromise(tx.objectStore(store).delete(key)) } export async function dbClear(store: string): Promise { const db = await openDB() const tx = db.transaction(store, 'readwrite') await requestToPromise(tx.objectStore(store).clear()) }