import type { Dataset, DatasetMetadata } from '../types'; const DB_NAME = 'CrossModalDB'; const DB_VERSION = 1; const STORE_NAME = 'datasets'; let dbPromise: Promise | null = null; const getDb = (): Promise => { if (!dbPromise) { dbPromise = new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION); request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains(STORE_NAME)) { db.createObjectStore(STORE_NAME, { keyPath: 'id' }); } }; request.onsuccess = (event) => { resolve((event.target as IDBOpenDBRequest).result); }; request.onerror = (event) => { console.error("IndexedDB error:", (event.target as IDBOpenDBRequest).error); reject("IndexedDB error"); }; }); } return dbPromise; }; const transaction = (mode: IDBTransactionMode) => { return getDb().then(db => { return db.transaction(STORE_NAME, mode).objectStore(STORE_NAME); }); }; export const addDataset = async (dataset: Dataset): Promise => { const store = await transaction('readwrite'); return new Promise((resolve, reject) => { const request = store.put(dataset); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); }; export const getDataset = async (id: string): Promise => { const store = await transaction('readonly'); return new Promise((resolve, reject) => { const request = store.get(id); request.onsuccess = () => { if (request.result) { // IndexedDB doesn't store Date objects correctly, so we need to parse them back. request.result.uploadDate = new Date(request.result.uploadDate); } resolve(request.result); }; request.onerror = () => reject(request.error); }); }; export const getAllDatasetMetadata = async (): Promise => { const store = await transaction('readonly'); return new Promise((resolve, reject) => { const request = store.getAll(); request.onsuccess = () => { const datasets: Dataset[] = request.result; const metadata: DatasetMetadata[] = datasets.map(d => ({ id: d.id, name: d.name, uploadDate: new Date(d.uploadDate), processingState: d.processingState, itemCounts: { images: d.data.images.length, texts: d.data.texts.length, meshes: d.data.meshes.length, } })); resolve(metadata); }; request.onerror = () => reject(request.error); }); }; export const deleteDataset = async (id: string): Promise => { const store = await transaction('readwrite'); return new Promise((resolve, reject) => { const request = store.delete(id); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); }; export const renameDataset = async (id: string, newName: string): Promise => { const store = await transaction('readwrite'); const dataset = await getDataset(id); if (dataset) { dataset.name = newName; await addDataset(dataset); // 'put' will update the existing record } else { throw new Error(`Dataset with id ${id} not found.`); } };