diff --git a/src/work/EngineContext.tsx b/src/work/EngineContext.tsx index d997c5c..0527242 100644 --- a/src/work/EngineContext.tsx +++ b/src/work/EngineContext.tsx @@ -153,6 +153,23 @@ export function EngineProvider({ return attachPersister(engine, { key: snapshotKey }); }, [engine, injected, snapshotKey, activeDocKey]); + // Rehydrate PDF bytes from IndexedDB (session-scoped). Snapshot restore + // only brings back metadata; without this the viewer points at a dead + // blob / fake fixture path and PDF.js reports "Invalid PDF structure". + useEffect(() => { + if (injected) return; + let cancelled = false; + void (async () => { + await byteStore.hydrate(); + if (!cancelled) { + setEngineRevision((n) => n + 1); + } + })(); + return () => { + cancelled = true; + }; + }, [byteStore, injected, sessionId]); + // Persist the active-document pointer alongside the engine snapshot so a // reload lands the user back where they were. useEffect(() => { diff --git a/src/work/SessionContext.tsx b/src/work/SessionContext.tsx index 40a5483..de68ad6 100644 --- a/src/work/SessionContext.tsx +++ b/src/work/SessionContext.tsx @@ -80,7 +80,8 @@ export function SessionProvider({ (sessionId: SessionId) => { let store = byteStores.get(sessionId); if (!store) { - store = createPdfByteStore(); + // sessionId enables IndexedDB mirror so PDF bytes survive reloads. + store = createPdfByteStore({ sessionId }); byteStores.set(sessionId, store); } return store;