Spaces:
Running
Running
| 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<Analysis[]>([]) | |
| const currentAnalysis = ref<Analysis | null>(null) | |
| const running = ref(false) | |
| const error = ref<string | null>(null) | |
| const pollingInterval = ref<ReturnType<typeof setInterval> | null>(null) | |
| const pollingTimeout = ref<ReturnType<typeof setTimeout> | null>(null) | |
| const MAX_POLLING_DURATION = 10 * 60 * 1000 // 10 minutes | |
| const currentPages = computed<Page[]>(() => { | |
| 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<void> { | |
| 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<Chunk[]>(() => { | |
| 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<Chunk[]> { | |
| 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<Analysis> { | |
| 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<void> { | |
| 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<void> { | |
| 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, | |
| } | |
| }) | |