Spaces:
Sleeping
Sleeping
| /** | |
| * Storage Library for Financial Insight System | |
| * Provides a unified interface for data storage with potential for external storage integration | |
| */ | |
| // Define storage keys for better type safety and avoid string duplication | |
| export const STORAGE_KEYS = { | |
| CHATS: 'fis-chats', | |
| SETTINGS: 'fis-settings', | |
| API_ENDPOINT: 'apiEndpoint', | |
| THEME: 'fis-theme', | |
| SOURCES: 'fis-sources', | |
| PROFILE_STORAGE_KEY: 'fis-profile' | |
| } as const; | |
| // Types for our storage | |
| export interface StorageOptions { | |
| ttl?: number; // Time to live in milliseconds | |
| } | |
| export type StorageValue = string | object | number | boolean | null | undefined; | |
| /** | |
| * Storage service that provides unified interface for storing and retrieving data | |
| * Currently uses localStorage, but can be extended to use external storage in the future | |
| */ | |
| class StorageService { | |
| private defaults: Partial<Record<string, StorageValue>> = {}; | |
| // Set default values for storage keys | |
| setDefaults(defaults: Partial<Record<string, StorageValue>>) { | |
| this.defaults = defaults; | |
| } | |
| // Get item from storage with automatic parsing and default fallback | |
| get<T = any>(key: string): T | null { | |
| try { | |
| const item = localStorage.getItem(key); | |
| if (!item) { | |
| // Return default if available | |
| if (key in this.defaults) { | |
| return this.defaults[key] as T; | |
| } | |
| return null; | |
| } | |
| const { value, expires } = JSON.parse(item); | |
| if (expires && expires < Date.now()) { | |
| this.remove(key); | |
| // Return default if available | |
| if (key in this.defaults) { | |
| return this.defaults[key] as T; | |
| } | |
| return null; | |
| } | |
| return value as T; | |
| } catch (error) { | |
| console.error(`Error getting item from storage: ${key}`, error); | |
| // Return default if available | |
| if (key in this.defaults) { | |
| return this.defaults[key] as T; | |
| } | |
| return null; | |
| } | |
| } | |
| // Set item in storage with optional TTL | |
| set(key: string, value: StorageValue, options: StorageOptions = {}): boolean { | |
| try { | |
| const storageItem = { | |
| value, | |
| expires: options.ttl ? Date.now() + options.ttl : null | |
| }; | |
| localStorage.setItem(key, JSON.stringify(storageItem)); | |
| return true; | |
| } catch (error) { | |
| console.error(`Error setting item in storage: ${key}`, error); | |
| return false; | |
| } | |
| } | |
| // Remove item from storage | |
| remove(key: string): boolean { | |
| try { | |
| localStorage.removeItem(key); | |
| return true; | |
| } catch (error) { | |
| console.error(`Error removing item from storage: ${key}`, error); | |
| return false; | |
| } | |
| } | |
| // Check if key exists in storage | |
| has(key: string): boolean { | |
| return localStorage.getItem(key) !== null; | |
| } | |
| // Clear all storage for the application | |
| clear(): boolean { | |
| try { | |
| // Only clear keys that start with our application prefix (fis-) | |
| Object.keys(localStorage).forEach(key => { | |
| if (key.startsWith('fis-')) { | |
| localStorage.removeItem(key); | |
| } | |
| }); | |
| return true; | |
| } catch (error) { | |
| console.error('Error clearing storage', error); | |
| return false; | |
| } | |
| } | |
| /** | |
| * Export all application data for keys defined in STORAGE_KEYS as a JSON object. | |
| * Returns an object with key-value pairs. | |
| */ | |
| export(): Record<string, any> { | |
| const exported: Record<string, any> = {}; | |
| Object.values(STORAGE_KEYS).forEach(key => { | |
| try { | |
| const item = localStorage.getItem(key); | |
| if (item) { | |
| exported[key] = JSON.parse(item); | |
| } | |
| } catch (error) { | |
| console.error(`Error exporting key: ${key}`, error); | |
| } | |
| }); | |
| return exported; | |
| } | |
| /** | |
| * Import data from an external source into local storage. | |
| * Accepts an object with key-value pairs (as produced by export()). | |
| * Overwrites existing keys, but only those defined in STORAGE_KEYS. | |
| */ | |
| import(data: Record<string, any>): boolean { | |
| try { | |
| Object.entries(data).forEach(([key, value]) => { | |
| if (Object.values(STORAGE_KEYS).includes(key as any)) { | |
| localStorage.setItem(key, JSON.stringify(value)); | |
| } | |
| }); | |
| return true; | |
| } catch (error) { | |
| console.error('Error importing data into storage', error); | |
| return false; | |
| } | |
| } | |
| // Reset all keys to their default values | |
| resetToDefaults(): boolean { | |
| try { | |
| Object.entries(this.defaults).forEach(([key, value]) => { | |
| this.set(key, value); | |
| }); | |
| return true; | |
| } catch (error) { | |
| console.error('Error resetting storage to defaults', error); | |
| return false; | |
| } | |
| } | |
| } | |
| // Create and export a singleton instance | |
| export const storage = new StorageService(); | |
| storage.setDefaults({ | |
| [STORAGE_KEYS.CHATS]: [], | |
| [STORAGE_KEYS.SETTINGS]: {}, | |
| [STORAGE_KEYS.API_ENDPOINT]: "https://insight-ai-api.hf.space", | |
| [STORAGE_KEYS.THEME]: "dark", | |
| [STORAGE_KEYS.SOURCES]: [], | |
| }); |