From fe9104e8fce431afaacb90b4f60be5e63fc09911 Mon Sep 17 00:00:00 2001 From: Richard R Date: Thu, 21 May 2026 11:59:12 -0600 Subject: [PATCH] docs(pdf,spinner,config): update parse state UI, spinner theming, and worker env docs Revise PDF viewer to introduce an explicit 'unknown' parse state and improve loader and status messaging for better user clarity. Refactor Spinner to use 'currentColor' for border styling and simplify conditional rendering based on className. Expand compute worker .env.example with explicit concurrency, timeout, and job attempt variables for enhanced configuration transparency. --- compute/worker/.env.example | 7 ++++++- src/app/(app)/pdf/[id]/page.tsx | 30 +++++++++++++++++++----------- src/components/Spinner.tsx | 12 ++++++++++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/compute/worker/.env.example b/compute/worker/.env.example index fa18018..eef2843 100644 --- a/compute/worker/.env.example +++ b/compute/worker/.env.example @@ -30,8 +30,13 @@ S3_FORCE_PATH_STYLE=true # Queue + execution tuning COMPUTE_PREWARM_MODELS=true +COMPUTE_WHISPER_CONCURRENCY=1 +COMPUTE_PDF_CONCURRENCY=2 +COMPUTE_WHISPER_TIMEOUT_MS=30000 +COMPUTE_PDF_TIMEOUT_MS=90000 +COMPUTE_JOB_ATTEMPTS=2 COMPUTE_JOBS_STREAM_MAX_BYTES=268435456 COMPUTE_JOB_STATES_MAX_BYTES=67108864 # Optional stale window for reusing in-flight opKey entries before forcing a new attempt # Default is max(30m, 4x max compute timeout); running jobs also refresh heartbeat every 5s -# COMPUTE_OP_STALE_MS=180000 +# COMPUTE_OP_STALE_MS=1800000 diff --git a/src/app/(app)/pdf/[id]/page.tsx b/src/app/(app)/pdf/[id]/page.tsx index 1cbb1f1..caaccae 100644 --- a/src/app/(app)/pdf/[id]/page.tsx +++ b/src/app/(app)/pdf/[id]/page.tsx @@ -75,11 +75,14 @@ export default function PDFViewerPage() { const backNavTimeoutRef = useRef | null>(null); const clearCurrDocRef = useRef(clearCurrDoc); const [isNavigatingBack, setIsNavigatingBack] = useState(false); - const parseState = parseStatus ?? 'pending'; - const isParseReady = parseState === 'ready'; + const parseUiState: 'unknown' | NonNullable = parseStatus ?? 'unknown'; + const isParseReady = parseUiState === 'ready'; const forceReparseDisabled = isForceReparseDisabled(parseStatus); + const hasRealParseProgress = !!parseProgress + && parseProgress.totalPages > 0 + && parseProgress.pagesParsed >= 0; const shouldShowExpandedParseLoader = !isLoading - && (parseState === 'pending' || parseState === 'running' || parseState === 'failed'); + && (parseUiState === 'failed' || hasRealParseProgress); useEffect(() => { setIsLoading(true); @@ -283,10 +286,10 @@ export default function PDFViewerPage() { const renderPdfStatusLoader = () => { const compactLabel = isLoading ? 'Opening PDF...' - : (parseState === 'ready' ? 'Rendering pages...' : 'Checking parse state...'); + : (parseUiState === 'ready' ? 'Rendering pages...' : 'Checking parse state...'); const compactSubLabel = isLoading ? 'Loading document data' - : (parseState === 'ready' ? 'Preparing first frame' : 'Preparing layout parser'); + : (parseUiState === 'ready' ? 'Preparing first frame' : 'Waiting for parse status'); const totalPages = parseProgress?.totalPages ?? 0; const pagesParsed = parseProgress?.pagesParsed ?? 0; @@ -299,25 +302,30 @@ export default function PDFViewerPage() { let statusText = 'Loading PDF...'; let statusSubText = 'Initializing document renderer'; if (!isLoading) { - if (parseState === 'pending') { + if (parseUiState === 'unknown') { + statusText = 'Checking parse state...'; + statusSubText = 'Waiting for server status snapshot'; + } else if (parseUiState === 'pending') { statusText = 'Preparing PDF layout...'; statusSubText = parseProgress?.phase === 'merge' ? 'Finalizing stitched block structure' : 'Queueing parser and preparing page extraction'; - } else if (parseState === 'running') { + } else if (parseUiState === 'running') { statusText = 'Parsing PDF layout blocks...'; statusSubText = parseProgress?.phase === 'merge' ? 'Merging cross-page sections' : 'Inferring reading order and text regions'; - } else if (parseState === 'failed') { + } else if (parseUiState === 'failed') { statusText = 'PDF parsing failed. Retry to continue.'; statusSubText = 'The parser could not build a usable layout map'; } } - const stageLabel = parseState === 'failed' + const stageLabel = parseUiState === 'unknown' + ? 'Stage: checking' + : parseUiState === 'failed' ? 'Stage: blocked' - : (parseState === 'pending' + : (parseUiState === 'pending' ? 'Stage: prepare' : (isMerging ? 'Stage: merge' : 'Stage: infer')); @@ -354,7 +362,7 @@ export default function PDFViewerPage() {

- {!isLoading && parseState === 'failed' ? ( + {!isLoading && parseUiState === 'failed' ? (