diff --git a/packages/feature-learner/src/web/lesson/DeckViewer.tsx b/packages/feature-learner/src/web/lesson/DeckViewer.tsx index 11d367a..295554b 100644 --- a/packages/feature-learner/src/web/lesson/DeckViewer.tsx +++ b/packages/feature-learner/src/web/lesson/DeckViewer.tsx @@ -49,17 +49,21 @@ export function DeckViewer({ deck, notes, initialPage = 1, keyboard = true, titl const canvas = useRef(null); useEffect(() => { - let live = true, loaded: PdfDoc | null = null; + // pdf.js 6 documents have no destroy(); the loading task owns the document and the worker port. + let live = true, task: { destroy(): Promise } | null = null; setDoc(null); setError(null); setPages(0); loadPdfjs() - .then((pdfjs) => pdfjs.getDocument({ url: deck.url, withCredentials: true }).promise) + .then((pdfjs) => { + const t = pdfjs.getDocument({ url: deck.url, withCredentials: true }); + task = t; + return t.promise; + }) .then((d: PdfDoc) => { - loaded = d; - if (!live) { void d.destroy(); return; } + if (!live) return; setDoc(d); setPages(d.numPages); setPage((p) => Math.min(Math.max(1, p), d.numPages)); }) .catch((e: unknown) => live && setError(`This deck could not be opened. ${(e as Error).message ?? ""}`.trim())); - return () => { live = false; if (loaded) void loaded.destroy(); }; + return () => { live = false; void task?.destroy().catch(() => {}); }; }, [deck.url]); // Render the current page to fit the stage.