import { defineStore } from 'pinia' import { ref, computed } from 'vue' import type { Analysis, Chunk, ChunkingOptions, Page, PipelineOptions } from '../../shared/types' import * as api from './api' export const useAnalysisStore = defineStore('analysis', () => { const analyses = ref([]) const currentAnalysis = ref(null) const running = ref(false) const error = ref(null) const pollingInterval = ref | null>(null) const pollingTimeout = ref | null>(null) const MAX_POLLING_DURATION = 10 * 60 * 1000 // 10 minutes const currentPages = computed(() => { if (!currentAnalysis.value?.pagesJson) return [] try { return JSON.parse(currentAnalysis.value.pagesJson) as Page[] } catch { return [] } }) function clearError(): void { error.value = null } async function load(): Promise { try { error.value = null analyses.value = await api.fetchAnalyses() } catch (e) { error.value = (e as Error).message || 'Failed to load analyses' console.error('Failed to load analyses', e) } } const currentChunks = computed(() => { if (!currentAnalysis.value?.chunksJson) return [] try { return JSON.parse(currentAnalysis.value.chunksJson) as Chunk[] } catch { return [] } }) const rechunking = ref(false) async function rechunk(jobId: string, chunkingOptions: ChunkingOptions): Promise { rechunking.value = true error.value = null try { const chunks = await api.rechunkAnalysis(jobId, chunkingOptions) if (currentAnalysis.value?.id === jobId) { currentAnalysis.value = await api.fetchAnalysis(jobId) } return chunks } catch (e) { error.value = (e as Error).message || 'Failed to rechunk' console.error('Failed to rechunk', e) throw e } finally { rechunking.value = false } } async function run( documentId: string, pipelineOptions: PipelineOptions | null = null, chunkingOptions: ChunkingOptions | null = null, ): Promise { running.value = true error.value = null try { const analysis = await api.createAnalysis(documentId, pipelineOptions, chunkingOptions) currentAnalysis.value = analysis analyses.value.unshift(analysis) startPolling(analysis.id) return analysis } catch (e) { running.value = false error.value = (e as Error).message || 'Failed to start analysis' console.error('Failed to start analysis', e) throw e } } function startPolling(id: string): void { stopPolling() pollingInterval.value = setInterval(async () => { try { const updated = await api.fetchAnalysis(id) currentAnalysis.value = updated const idx = analyses.value.findIndex((a) => a.id === id) if (idx !== -1) analyses.value[idx] = updated if (updated.status === 'COMPLETED' || updated.status === 'FAILED') { stopPolling() running.value = false } } catch (e) { error.value = (e as Error).message || 'Polling error' console.error('Polling error', e) stopPolling() running.value = false } }, 2000) pollingTimeout.value = setTimeout(() => { if (pollingInterval.value) { error.value = 'Analysis timed out' stopPolling() running.value = false } }, MAX_POLLING_DURATION) } function stopPolling(): void { if (pollingInterval.value) { clearInterval(pollingInterval.value) pollingInterval.value = null } if (pollingTimeout.value) { clearTimeout(pollingTimeout.value) pollingTimeout.value = null } } async function select(id: string): Promise { try { currentAnalysis.value = await api.fetchAnalysis(id) } catch (e) { error.value = (e as Error).message || 'Failed to load analysis' console.error('Failed to load analysis', e) } } async function remove(id: string): Promise { try { await api.deleteAnalysis(id) analyses.value = analyses.value.filter((a) => a.id !== id) if (currentAnalysis.value?.id === id) currentAnalysis.value = null } catch (e) { error.value = (e as Error).message || 'Failed to delete analysis' console.error('Failed to delete analysis', e) } } return { analyses, currentAnalysis, currentPages, currentChunks, running, rechunking, error, clearError, load, run, rechunk, select, remove, stopPolling, } })