| | |
| | | * @param {object|array} configs An object defining the store, or an array of objects defining the stores |
| | | * @param {number} version the database version |
| | | */ |
| | | register(name, configs = [], version = 1.1) { |
| | | register(name, configs = [], version = 1.2) { |
| | | if (!Array.isArray(configs)) configs = [configs]; |
| | | if (configs.length === 0) return; |
| | | |
| | |
| | | |
| | | let result; |
| | | tx.oncomplete = () => resolve(result); |
| | | tx.onerror = () => reject(tx.error); |
| | | tx.onerror = () => { |
| | | const error = tx.error || new Error('Transaction failed with unknown error'); |
| | | reject(error); |
| | | }; |
| | | |
| | | // Call callback immediately to queue operations |
| | | try { |
| | | result = callback(objectStore, tx); |
| | | } catch (error) { |
| | | reject(error); |
| | | reject(error || new Error('Callback failed with unknown error')); |
| | | } |
| | | }); |
| | | } |
| | |
| | | return data; |
| | | |
| | | } catch (error) { |
| | | if (error.name !== 'AbortError') { |
| | | const isAbortError = error?.name === 'AbortError'; |
| | | |
| | | if (!isAbortError) { |
| | | console.error(`Fetch error for store "${name}":`, error); |
| | | this.notify(name, 'fetch-error', { error }); |
| | | throw error; |
| | | } |
| | | throw error; |
| | | |
| | | } finally { |
| | | store.isFetching = false; |
| | |
| | | */ |
| | | async processFetchedData(name, data, cacheKey, response) { |
| | | const store = this.stores.get(name); |
| | | const items = data.items || []; |
| | | const changes = []; // Track all changes |
| | | const items = (data.items || []).filter(item => item && typeof item === 'object'); |
| | | const changes = []; |
| | | |
| | | // Batch process with single transaction |
| | | if (store.db && items.length > 0) { |
| | |
| | | } |
| | | |
| | | processForStorage(obj, validate = true, path = 'root') { |
| | | if (obj === null || obj === undefined) return { valid: true, data: obj }; |
| | | if (obj === null) { |
| | | return { valid: true, data: null }; |
| | | } |
| | | if (obj === undefined) { |
| | | if (validate) { |
| | | return { valid: false, error: `Undefined value at ${path}` }; |
| | | } |
| | | return { valid: true, data: undefined }; |
| | | } |
| | | |
| | | const type = typeof obj; |
| | | |
| | |
| | | for (const [key, value] of Object.entries(obj)) { |
| | | const result = this.processForStorage(value, validate, `${path}.${key}`); |
| | | if (!result.valid) return result; |
| | | if (result.data !== undefined) processed[key] = result.data; |
| | | // Include null values, skip undefined |
| | | if (result.data !== undefined || value === null) { |
| | | processed[key] = result.data; |
| | | } |
| | | } |
| | | return { valid: true, data: processed }; |
| | | } |
| | |
| | | if (!store) return []; |
| | | |
| | | return Array.from(store.data.values()).filter(item => { |
| | | if (!item || typeof item !== 'object') return false; |
| | | return Object.entries(criteria).every(([key, value]) => { |
| | | const accepted = Array.isArray(value) ? value : [value]; |
| | | return accepted.includes(item[key]); |