/** * SettingsStore - Application configuration and theme management * * This store manages all application settings including AI model parameters, UI preferences, * and theme configuration. It provides persistent storage through localStorage with reactive * state management using Svelte 5 runes. * * **Architecture & Relationships:** * - **SettingsStore** (this class): Configuration state management * - Manages AI model parameters (temperature, max tokens, etc.) * - Handles theme switching and persistence * - Provides localStorage synchronization * - Offers reactive configuration access * * - **ChatService**: Reads model parameters for API requests * - **UI Components**: Subscribe to theme and configuration changes * * **Key Features:** * - **Model Parameters**: Temperature, max tokens, top-p, top-k, repeat penalty * - **Theme Management**: Auto, light, dark theme switching * - **Persistence**: Automatic localStorage synchronization * - **Reactive State**: Svelte 5 runes for automatic UI updates * - **Default Handling**: Graceful fallback to defaults for missing settings * - **Batch Updates**: Efficient multi-setting updates * - **Reset Functionality**: Restore defaults for individual or all settings * * **Configuration Categories:** * - Generation parameters (temperature, tokens, sampling) * - UI preferences (theme, display options) * - System settings (model selection, prompts) * - Advanced options (seed, penalties, context handling) */ import { browser } from '$app/environment'; import { SETTING_CONFIG_DEFAULT } from '$lib/constants/settings-config'; class SettingsStore { config = $state({ ...SETTING_CONFIG_DEFAULT }); theme = $state('auto'); isInitialized = $state(false); constructor() { if (browser) { this.initialize(); } } /** * Initialize the settings store by loading from localStorage */ initialize() { try { this.loadConfig(); this.loadTheme(); this.isInitialized = true; } catch (error) { console.error('Failed to initialize settings store:', error); } } /** * Load configuration from localStorage * Returns default values for missing keys to prevent breaking changes */ private loadConfig() { if (!browser) return; try { const savedVal = JSON.parse(localStorage.getItem('config') || '{}'); // Merge with defaults to prevent breaking changes this.config = { ...SETTING_CONFIG_DEFAULT, ...savedVal }; } catch (error) { console.warn('Failed to parse config from localStorage, using defaults:', error); this.config = { ...SETTING_CONFIG_DEFAULT }; } } /** * Load theme from localStorage */ private loadTheme() { if (!browser) return; this.theme = localStorage.getItem('theme') || 'auto'; } /** * Update a specific configuration setting * @param key - The configuration key to update * @param value - The new value for the configuration key */ updateConfig(key: K, value: SettingsConfigType[K]) { this.config[key] = value; this.saveConfig(); } /** * Update multiple configuration settings at once * @param updates - Object containing the configuration updates */ updateMultipleConfig(updates: Partial) { Object.assign(this.config, updates); this.saveConfig(); } /** * Save the current configuration to localStorage */ private saveConfig() { if (!browser) return; try { localStorage.setItem('config', JSON.stringify(this.config)); } catch (error) { console.error('Failed to save config to localStorage:', error); } } /** * Update the theme setting * @param newTheme - The new theme value */ updateTheme(newTheme: string) { this.theme = newTheme; this.saveTheme(); } /** * Save the current theme to localStorage */ private saveTheme() { if (!browser) return; try { if (this.theme === 'auto') { localStorage.removeItem('theme'); } else { localStorage.setItem('theme', this.theme); } } catch (error) { console.error('Failed to save theme to localStorage:', error); } } /** * Reset configuration to defaults */ resetConfig() { this.config = { ...SETTING_CONFIG_DEFAULT }; this.saveConfig(); } /** * Reset theme to auto */ resetTheme() { this.theme = 'auto'; this.saveTheme(); } /** * Reset all settings to defaults */ resetAll() { this.resetConfig(); this.resetTheme(); } /** * Get a specific configuration value * @param key - The configuration key to get * @returns The configuration value */ getConfig(key: K): SettingsConfigType[K] { return this.config[key]; } /** * Get the entire configuration object * @returns The complete configuration object */ getAllConfig(): SettingsConfigType { return { ...this.config }; } } // Create and export the settings store instance export const settingsStore = new SettingsStore(); // Export reactive getters for easy access in components export const config = () => settingsStore.config; export const theme = () => settingsStore.theme; export const isInitialized = () => settingsStore.isInitialized; // Export bound methods for easy access export const updateConfig = settingsStore.updateConfig.bind(settingsStore); export const updateMultipleConfig = settingsStore.updateMultipleConfig.bind(settingsStore); export const updateTheme = settingsStore.updateTheme.bind(settingsStore); export const resetConfig = settingsStore.resetConfig.bind(settingsStore); export const resetTheme = settingsStore.resetTheme.bind(settingsStore); export const resetAll = settingsStore.resetAll.bind(settingsStore); export const getConfig = settingsStore.getConfig.bind(settingsStore); export const getAllConfig = settingsStore.getAllConfig.bind(settingsStore);