const DB_NAME = 'CodeForgeDB' const DB_VERSION = 1 export interface DBSchema { projects: { key: string value: { id: string name: string files: any[] models: any[] components: any[] componentTrees: any[] workflows: any[] lambdas: any[] theme: any playwrightTests: any[] storybookStories: any[] unitTests: any[] flaskConfig: any nextjsConfig: any npmSettings: any featureToggles: any createdAt: number updatedAt: number } } files: { key: string value: { id: string name: string content: string language: string path: string updatedAt: number } } models: { key: string value: { id: string name: string fields: any[] updatedAt: number } } components: { key: string value: { id: string name: string code: string updatedAt: number } } workflows: { key: string value: { id: string name: string nodes: any[] edges: any[] updatedAt: number } } settings: { key: string value: any } } type StoreName = keyof DBSchema class Database { private db: IDBDatabase | null = null private initPromise: Promise | null = null async init(): Promise { if (this.db) return if (this.initPromise) return this.initPromise this.initPromise = new Promise((resolve, reject) => { const request = indexedDB.open(DB_NAME, DB_VERSION) request.onerror = () => reject(request.error) request.onsuccess = () => { this.db = request.result resolve() } request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result if (!db.objectStoreNames.contains('projects')) { const projectStore = db.createObjectStore('projects', { keyPath: 'id' }) projectStore.createIndex('name', 'name', { unique: false }) projectStore.createIndex('updatedAt', 'updatedAt', { unique: false }) } if (!db.objectStoreNames.contains('files')) { const fileStore = db.createObjectStore('files', { keyPath: 'id' }) fileStore.createIndex('name', 'name', { unique: false }) fileStore.createIndex('path', 'path', { unique: false }) } if (!db.objectStoreNames.contains('models')) { const modelStore = db.createObjectStore('models', { keyPath: 'id' }) modelStore.createIndex('name', 'name', { unique: false }) } if (!db.objectStoreNames.contains('components')) { const componentStore = db.createObjectStore('components', { keyPath: 'id' }) componentStore.createIndex('name', 'name', { unique: false }) } if (!db.objectStoreNames.contains('workflows')) { const workflowStore = db.createObjectStore('workflows', { keyPath: 'id' }) workflowStore.createIndex('name', 'name', { unique: false }) } if (!db.objectStoreNames.contains('settings')) { db.createObjectStore('settings', { keyPath: 'key' }) } } }) return this.initPromise } async get( storeName: T, key: string ): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readonly') const store = transaction.objectStore(storeName) const request = store.get(key) request.onerror = () => reject(request.error) request.onsuccess = () => resolve(request.result) }) } async getAll(storeName: T): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readonly') const store = transaction.objectStore(storeName) const request = store.getAll() request.onerror = () => reject(request.error) request.onsuccess = () => resolve(request.result) }) } async put( storeName: T, value: DBSchema[T]['value'] ): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readwrite') const store = transaction.objectStore(storeName) const request = store.put(value) request.onerror = () => reject(request.error) request.onsuccess = () => resolve() }) } async delete(storeName: T, key: string): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readwrite') const store = transaction.objectStore(storeName) const request = store.delete(key) request.onerror = () => reject(request.error) request.onsuccess = () => resolve() }) } async clear(storeName: T): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readwrite') const store = transaction.objectStore(storeName) const request = store.clear() request.onerror = () => reject(request.error) request.onsuccess = () => resolve() }) } async query( storeName: T, indexName: string, query: IDBValidKey | IDBKeyRange ): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readonly') const store = transaction.objectStore(storeName) const index = store.index(indexName) const request = index.getAll(query) request.onerror = () => reject(request.error) request.onsuccess = () => resolve(request.result) }) } async count(storeName: T): Promise { await this.init() if (!this.db) throw new Error('Database not initialized') return new Promise((resolve, reject) => { const transaction = this.db!.transaction(storeName, 'readonly') const store = transaction.objectStore(storeName) const request = store.count() request.onerror = () => reject(request.error) request.onsuccess = () => resolve(request.result) }) } } export const db = new Database()