// Rôle : encapsule les opérations IndexedDB génériques utilisées par les toolboxes. const DB_NAME = "sokkog"; const DB_VERSION = 1; const KV_STORE = "kv"; const MODULE_STORE = "modules"; let dbPromise; function openDatabase() { if (dbPromise) return dbPromise; dbPromise = new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); request.onupgradeneeded = () => { const db = request.result; if (!db.objectStoreNames.contains(KV_STORE)) db.createObjectStore(KV_STORE); if (!db.objectStoreNames.contains(MODULE_STORE)) db.createObjectStore(MODULE_STORE, { keyPath: "key" }); }; request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); return dbPromise; } function requestToPromise(request) { return new Promise((resolve, reject) => { request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async function storeRequest(storeName, mode, callback) { const db = await openDatabase(); const transaction = db.transaction(storeName, mode); const store = transaction.objectStore(storeName); return requestToPromise(callback(store)); } export async function getValue(key, fallback) { const value = await storeRequest(KV_STORE, "readonly", (store) => store.get(key)); return value == null ? fallback : value; } export async function setValue(key, value) { await storeRequest(KV_STORE, "readwrite", (store) => store.put(value, key)); } export async function getToolboxes() { return getValue("toolboxes", []); } export async function setToolboxes(toolboxes) { await setValue("toolboxes", toolboxes); } export async function getLinks() { return getValue("links", {}); } export async function setLinks(links) { await setValue("links", links); } export async function getSetting(key, fallback) { return getValue(`setting:${key}`, fallback); } export async function setSetting(key, value) { await setValue(`setting:${key}`, value); } export async function getAllModuleData() { return storeRequest(MODULE_STORE, "readonly", (store) => store.getAll()); } export async function setModuleData(key, data) { await storeRequest(MODULE_STORE, "readwrite", (store) => store.put({ key, data })); } export async function removeModuleData(key) { await storeRequest(MODULE_STORE, "readwrite", (store) => store.delete(key)); } export async function removeModuleDataKeys(keys) { if (!keys.length) return; const db = await openDatabase(); await new Promise((resolve, reject) => { const transaction = db.transaction(MODULE_STORE, "readwrite"); const store = transaction.objectStore(MODULE_STORE); keys.forEach((key) => store.delete(key)); transaction.oncomplete = () => resolve(); transaction.onerror = () => reject(transaction.error); transaction.onabort = () => reject(transaction.error); }); } export async function getStorageEstimate() { if (!navigator.storage?.estimate) return { usage: 0, quota: 0 }; return navigator.storage.estimate(); }