/** * Service for managing automation configurations in IndexedDB */ export interface AutomationConfig { id: string; name: string; description?: string; operations: Array<{ operation: string; parameters: any; }>; createdAt: string; updatedAt: string; } class AutomationStorage { private dbName = 'StirlingPDF_Automations'; private dbVersion = 1; private storeName = 'automations'; private db: IDBDatabase | null = null; async init(): Promise { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, this.dbVersion); request.onerror = () => { reject(new Error('Failed to open automation storage database')); }; request.onsuccess = () => { this.db = request.result; resolve(); }; request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains(this.storeName)) { const store = db.createObjectStore(this.storeName, { keyPath: 'id' }); store.createIndex('name', 'name', { unique: false }); store.createIndex('createdAt', 'createdAt', { unique: false }); } }; }); } async ensureDB(): Promise { if (!this.db) { await this.init(); } if (!this.db) { throw new Error('Database not initialized'); } return this.db; } async saveAutomation(automation: Omit): Promise { const db = await this.ensureDB(); const timestamp = new Date().toISOString(); const automationWithMeta: AutomationConfig = { id: `automation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, ...automation, createdAt: timestamp, updatedAt: timestamp }; return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], 'readwrite'); const store = transaction.objectStore(this.storeName); const request = store.add(automationWithMeta); request.onsuccess = () => { resolve(automationWithMeta); }; request.onerror = () => { reject(new Error('Failed to save automation')); }; }); } async updateAutomation(automation: AutomationConfig): Promise { const db = await this.ensureDB(); const updatedAutomation: AutomationConfig = { ...automation, updatedAt: new Date().toISOString() }; return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], 'readwrite'); const store = transaction.objectStore(this.storeName); const request = store.put(updatedAutomation); request.onsuccess = () => { resolve(updatedAutomation); }; request.onerror = () => { reject(new Error('Failed to update automation')); }; }); } async getAutomation(id: string): Promise { const db = await this.ensureDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); const request = store.get(id); request.onsuccess = () => { resolve(request.result || null); }; request.onerror = () => { reject(new Error('Failed to get automation')); }; }); } async getAllAutomations(): Promise { const db = await this.ensureDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], 'readonly'); const store = transaction.objectStore(this.storeName); const request = store.getAll(); request.onsuccess = () => { const automations = request.result || []; // Sort by creation date, newest first automations.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); resolve(automations); }; request.onerror = () => { reject(new Error('Failed to get automations')); }; }); } async deleteAutomation(id: string): Promise { const db = await this.ensureDB(); return new Promise((resolve, reject) => { const transaction = db.transaction([this.storeName], 'readwrite'); const store = transaction.objectStore(this.storeName); const request = store.delete(id); request.onsuccess = () => { resolve(); }; request.onerror = () => { reject(new Error('Failed to delete automation')); }; }); } async searchAutomations(query: string): Promise { const automations = await this.getAllAutomations(); if (!query.trim()) { return automations; } const lowerQuery = query.toLowerCase(); return automations.filter(automation => automation.name.toLowerCase().includes(lowerQuery) || (automation.description && automation.description.toLowerCase().includes(lowerQuery)) || automation.operations.some(op => op.operation.toLowerCase().includes(lowerQuery)) ); } } // Export singleton instance export const automationStorage = new AutomationStorage();