Spaces:
Running
Running
| ts | |
| import { create } from 'zustand' | |
| import { devtools, persist } from 'zustand/middleware' | |
| import { AIModel, AppState, OptimizationRequest, OptimizationResult } from '@/types' | |
| import { PromptOptimizer } from '@/utils/promptOptimizer' | |
| import { sanitizePrompt, validatePrompt } from '@/utils/validation' | |
| /** | |
| * Zustand store for managing application state | |
| */ | |
| interface AppStore extends AppState { | |
| // Actions | |
| setPrompt: (prompt: string) => void | |
| setSelectedModel: (model: AIModel | null) => void | |
| setShowComparison: (show: boolean) => void | |
| optimizePrompt: () => Promise<void> | |
| resetResults: () => void | |
| clearError: () => void | |
| setCopiedState: (type: 'original' | 'optimized', copied: boolean) => void | |
| retryOptimization: () => Promise<void> | |
| // Computed | |
| canOptimize: () => boolean | |
| validation: () => ReturnType<typeof validatePrompt> | |
| } | |
| /** | |
| * Maximum retry attempts for failed optimizations | |
| */ | |
| const MAX_RETRY_ATTEMPTS = 3 | |
| /** | |
| * Zustand store implementation with persistence and devtools | |
| */ | |
| export const useAppStore = create<AppStore>()( | |
| devtools( | |
| persist( | |
| (set, get) => ({ | |
| // Initial state | |
| prompt: '', | |
| selectedModel: null, | |
| isOptimizing: false, | |
| result: null, | |
| error: null, | |
| showComparison: false, | |
| characterCount: 0, | |
| isLoading: false, | |
| copiedStates: { | |
| original: false, | |
| optimized: false | |
| }, | |
| // Actions | |
| setPrompt: (prompt: string) => { | |
| const sanitized = sanitizePrompt(prompt) | |
| set({ | |
| prompt: sanitized, | |
| characterCount: sanitized.length, | |
| error: null | |
| }) | |
| }, | |
| setSelectedModel: (model: AIModel | null) => { | |
| set({ | |
| selectedModel: model, | |
| error: null | |
| }) | |
| }, | |
| setShowComparison: (show: boolean) => { | |
| set({ showComparison: show }) | |
| }, | |
| optimizePrompt: async () => { | |
| const state = get() | |
| const validation = validatePrompt(state.prompt) | |
| if (!validation.isValid) { | |
| set({ error: 'Prompt ist ungültig. Bitte überprüfe deine Eingabe.' }) | |
| return | |
| } | |
| if (!state.selectedModel) { | |
| set({ error: 'Bitte wähle eine Ziel-KI aus' }) | |
| return | |
| } | |
| set({ isOptimizing: true, error: null }) | |
| try { | |
| const request: OptimizationRequest = { | |
| prompt: state.prompt, | |
| targetModel: state.selectedModel | |
| } | |
| const result = await PromptOptimizer.optimize(request) | |
| set({ | |
| result, | |
| isOptimizing: false, | |
| error: null | |
| }) | |
| } catch (error) { | |
| set({ | |
| isOptimizing: false, | |
| error: error instanceof Error ? error.message : 'Ein unbekannter Fehler ist aufgetreten' | |
| }) | |
| } | |
| }, | |
| resetResults: () => { | |
| set({ | |
| result: null, | |
| error: null, | |
| showComparison: false, | |
| copiedStates: { original: false, optimized: false } | |
| }) | |
| }, | |
| clearError: () => { | |
| set({ error: null }) | |
| }, | |
| setCopiedState: (type: 'original' | 'optimized', copied: boolean) => { | |
| set(state => ({ | |
| copiedStates: { | |
| ...state.copiedStates, | |
| [type]: copied | |
| } | |
| })) | |
| }, | |
| retryOptimization: async () => { | |
| let attempts = 0 | |
| const retryDelay = 1000 // 1 second | |
| while (attempts < MAX_RETRY_ATTEMPTS) { | |
| try { | |
| await get().optimizePrompt() | |
| return // Success, exit retry loop | |
| } catch (error) { | |
| attempts++ | |
| if (attempts >= MAX_RETRY_ATTEMPTS) { | |
| set({ | |
| error: 'Optimierung fehlgeschlagen. Bitte versuche es später erneut.', | |
| isOptimizing: false | |
| }) | |
| return | |
| } | |
| // Wait before retry | |
| await new Promise(resolve => setTimeout(resolve, retryDelay)) | |
| } | |
| } | |
| }, | |
| // Computed values | |
| canOptimize: () => { | |
| const state = get() | |
| return state.prompt.length > 0 && | |
| state.selectedModel !== null && | |
| !state.isOptimizing | |
| }, | |
| validation: () => { | |
| return validatePrompt(get().prompt) | |
| } | |
| }), | |
| { | |
| name: 'prompt-enhancer-storage', | |
| partialize: (state) => ({ | |
| // Only persist non-volatile data | |
| selectedModel: state.selectedModel, | |
| prompt: state.prompt.length < 1000 ? state.prompt : '', // Only persist short prompts | |
| showComparison: state.showComparison | |
| }), | |
| onRehydrateStorage: () => (state) => { | |
| console.log('Rehydrated store from storage:', state) | |
| } | |
| } | |
| ), | |
| { | |
| name: 'prompt-enhancer-store' | |
| } | |
| ) | |
| ) | |
| </html> |