Pier-Jean's picture
Initial deploy: Docling Studio (local mode, port 7860)
5539271
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,
}
})