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.
This commit is contained in:
Richard R 2026-05-21 11:59:12 -06:00
parent 08df437e61
commit fe9104e8fc
3 changed files with 35 additions and 14 deletions

View file

@ -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

View file

@ -75,11 +75,14 @@ export default function PDFViewerPage() {
const backNavTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const clearCurrDocRef = useRef(clearCurrDoc);
const [isNavigatingBack, setIsNavigatingBack] = useState(false);
const parseState = parseStatus ?? 'pending';
const isParseReady = parseState === 'ready';
const parseUiState: 'unknown' | NonNullable<typeof parseStatus> = 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() {
</p>
</div>
{!isLoading && parseState === 'failed' ? (
{!isLoading && parseUiState === 'failed' ? (
<div className="mt-3 flex justify-start">
<button
type="button"

View file

@ -4,9 +4,17 @@ interface SpinnerProps {
}
export function LoadingSpinner({ className }: SpinnerProps = {}) {
if (className) {
return (
<div
className={`animate-spin rounded-full border-2 border-current border-t-transparent ${className}`}
/>
);
}
return (
<div className={className || "absolute inset-0 flex items-center justify-center"}>
<div className="animate-spin h-4 w-4 border-2 border-foreground border-t-transparent rounded-full" />
<div className="absolute inset-0 flex items-center justify-center">
<div className="animate-spin h-4 w-4 border-2 border-current border-t-transparent rounded-full" />
</div>
);
}