web / frontend /src /lib /storage.ts
Chandima Prabhath
feat: Add chat components and modals for enhanced user interaction
1904e4c
/**
* 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]: [],
});