53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
/* IndexedDB-backed persistence for settings and saved scenes.
|
|
* Mirrors the mockup's `nvsim/kv` store. */
|
|
|
|
const DB_NAME = 'nvsim';
|
|
const DB_VER = 1;
|
|
const STORE = 'kv';
|
|
|
|
let dbPromise: Promise<IDBDatabase> | null = null;
|
|
|
|
function openDb(): Promise<IDBDatabase> {
|
|
if (dbPromise) return dbPromise;
|
|
dbPromise = new Promise<IDBDatabase>((resolve, reject) => {
|
|
const req = indexedDB.open(DB_NAME, DB_VER);
|
|
req.onupgradeneeded = () => {
|
|
const db = req.result;
|
|
if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE);
|
|
};
|
|
req.onsuccess = () => resolve(req.result);
|
|
req.onerror = () => reject(req.error);
|
|
});
|
|
return dbPromise;
|
|
}
|
|
|
|
export async function kvGet<T = unknown>(key: string): Promise<T | undefined> {
|
|
const db = await openDb();
|
|
return await new Promise<T | undefined>((resolve, reject) => {
|
|
const tx = db.transaction(STORE, 'readonly');
|
|
const r = tx.objectStore(STORE).get(key);
|
|
r.onsuccess = () => resolve(r.result as T | undefined);
|
|
r.onerror = () => reject(r.error);
|
|
});
|
|
}
|
|
|
|
export async function kvSet(key: string, value: unknown): Promise<void> {
|
|
const db = await openDb();
|
|
return await new Promise<void>((resolve, reject) => {
|
|
const tx = db.transaction(STORE, 'readwrite');
|
|
tx.objectStore(STORE).put(value, key);
|
|
tx.oncomplete = () => resolve();
|
|
tx.onerror = () => reject(tx.error);
|
|
});
|
|
}
|
|
|
|
export async function kvDelete(key: string): Promise<void> {
|
|
const db = await openDb();
|
|
return await new Promise<void>((resolve, reject) => {
|
|
const tx = db.transaction(STORE, 'readwrite');
|
|
tx.objectStore(STORE).delete(key);
|
|
tx.oncomplete = () => resolve();
|
|
tx.onerror = () => reject(tx.error);
|
|
});
|
|
}
|