File size: 5,124 Bytes
eee3ce2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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>