"use client"; import { useMemo } from "react"; import { useQueries, useQuery } from "@tanstack/react-query"; import type { DisplaySummary } from "../lib/transcripts"; import type { Manifest } from "../lib/manifest"; import { readerFor } from "../lib/archive/readers"; export type SummariesState = { manifest: Manifest | null; summaries: DisplaySummary[]; loadedPages: number; pageCount: number; summariesReady: boolean; error: Error | null; }; export function useManifest(origin = "") { return useQuery({ queryKey: ["manifest", origin], queryFn: () => readerFor(origin).readSummariesManifest(), }); } export function useSummaries(origin = ""): SummariesState { const manifestQuery = useManifest(origin); const manifest = manifestQuery.data ?? null; const pageCount = manifest?.pageCount ?? 0; const pageQueries = useQueries({ queries: Array.from({ length: pageCount }, (_, i) => ({ queryKey: ["summaries-page", origin, i], queryFn: () => readerFor(origin).readSummariesPage(i), enabled: pageCount > 0, })), }); const loadedPages = pageQueries.filter((q) => q.data).length; const summariesReady = pageCount > 0 && loadedPages === pageCount; // Concatenate available pages; sort once all pages are in. Pages may arrive // out of order, so a late sort keeps the newest-first ordering stable // regardless of arrival order. Matches the LMDB composite-key order // [uploadDate, channelSlug, id] reversed. const summaries = useMemo(() => { if (loadedPages === 0) return []; const out: DisplaySummary[] = []; for (const q of pageQueries) if (q.data) out.push(...q.data); if (summariesReady) { out.sort( (a, b) => b.uploadDate.localeCompare(a.uploadDate) || a.channelSlug.localeCompare(b.channelSlug) || a.id.localeCompare(b.id), ); } return out; // pageQueries identity changes every render; key off loadedPages + ready. // eslint-disable-next-line react-hooks/exhaustive-deps }, [loadedPages, summariesReady]); const error = manifestQuery.error instanceof Error ? manifestQuery.error : (pageQueries.find((q) => q.error)?.error as Error | undefined) ?? null; return { manifest, summaries, loadedPages, pageCount, summariesReady, error, }; }