import { DB_NAME, CANVAS_STORE_NAME, CANVAS_AUTOSAVE_KEY, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT } from '../constants'; const DB_VERSION = 1; // Keep version, onupgradeneeded handles store creation interface CanvasSave { id: string; dataURL: string; width: number; height: number; timestamp: number; } export interface LoadedCanvasState { dataURL: string; width: number; height: number; } const openDB = (): Promise => { return new Promise((resolve, reject) => { if (!window.indexedDB) { console.warn("IndexedDB not supported by this browser."); reject(new Error("IndexedDB not supported.")); return; } const request = indexedDB.open(DB_NAME, DB_VERSION); request.onerror = () => reject(new Error('Failed to open IndexedDB: ' + request.error?.message)); request.onsuccess = () => resolve(request.result); request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains(CANVAS_STORE_NAME)) { db.createObjectStore(CANVAS_STORE_NAME, { keyPath: 'id' }); } // No need to alter existing stores if only adding properties to stored objects. // If keyPath or indexes changed, would need more complex migration. }; }); }; export const saveCanvasState = async (dataURL: string, width: number, height: number): Promise => { try { const db = await openDB(); const transaction = db.transaction(CANVAS_STORE_NAME, 'readwrite'); const store = transaction.objectStore(CANVAS_STORE_NAME); const canvasData: CanvasSave = { id: CANVAS_AUTOSAVE_KEY, dataURL, width, height, timestamp: Date.now(), }; store.put(canvasData); return new Promise((resolve, reject) => { transaction.oncomplete = () => resolve(); transaction.onerror = () => { console.error('Transaction error saving canvas state:', transaction.error); reject(new Error('Failed to save canvas state.')); } }); } catch (error) { console.error('Error saving canvas state to IndexedDB:', error); // Gracefully fail, app can still function } }; export const loadCanvasState = async (): Promise => { try { const db = await openDB(); const transaction = db.transaction(CANVAS_STORE_NAME, 'readonly'); const store = transaction.objectStore(CANVAS_STORE_NAME); const request = store.get(CANVAS_AUTOSAVE_KEY); return new Promise((resolve, reject) => { request.onsuccess = () => { if (request.result) { const savedData = request.result as CanvasSave; resolve({ dataURL: savedData.dataURL, // Provide default dimensions if old data doesn't have them width: savedData.width || DEFAULT_CANVAS_WIDTH, height: savedData.height || DEFAULT_CANVAS_HEIGHT, }); } else { resolve(null); } }; request.onerror = () => { console.error('Request error loading canvas state:', request.error); reject(new Error('Failed to load canvas state.')); } }); } catch (error) { console.error('Error loading canvas state from IndexedDB:', error); return null; // Gracefully fail } }; export const clearCanvasStateDB = async (): Promise => { try { const db = await openDB(); const transaction = db.transaction(CANVAS_STORE_NAME, 'readwrite'); const store = transaction.objectStore(CANVAS_STORE_NAME); const request = store.delete(CANVAS_AUTOSAVE_KEY); return new Promise((resolve, reject) => { transaction.oncomplete = () => resolve(); transaction.onerror = () => { console.error('Transaction error clearing canvas state:', transaction.error); reject(new Error('Failed to clear canvas state from DB.')); } request.onerror = () => { // Also handle request error for delete specifically console.error('Request error deleting canvas state:', request.error); reject(new Error('Failed to delete canvas state from DB.')); }; }); } catch (error) { console.error('Error clearing canvas state from IndexedDB:', error); } };