fix(document): pass wasmUrl to pdf.js getDocument so wasm decoders load
getDocument was called with a bare src string, so pdf.js 5.x had no
`wasmUrl` and could not initialise the JBIG2/CCITTFax wasm decoder —
CCITT (G4 fax) scans painted a blank canvas. Pass
{ url, wasmUrl: '/pdfjs-wasm/' }; the directory URL (trailing slash
required) is the single source of truth next to the worker config.
Refs #708
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -205,6 +205,32 @@ describe('createPdfRenderer', () => {
|
|||||||
expect(fakeLoader).toHaveBeenCalledOnce();
|
expect(fakeLoader).toHaveBeenCalledOnce();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('passes a non-null wasmUrl directory (ending in /) to getDocument, not a bare src string', async () => {
|
||||||
|
const getDocument = vi.fn().mockReturnValue({
|
||||||
|
promise: Promise.resolve({ numPages: 1, getPage: vi.fn() })
|
||||||
|
});
|
||||||
|
const lib = {
|
||||||
|
GlobalWorkerOptions: { workerSrc: '' },
|
||||||
|
getDocument,
|
||||||
|
TextLayer: class {
|
||||||
|
render() {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
cancel() {}
|
||||||
|
}
|
||||||
|
} as unknown as typeof import('pdfjs-dist');
|
||||||
|
const r = createPdfRenderer(vi.fn().mockResolvedValue([lib, { default: '' }] as const));
|
||||||
|
await r.init();
|
||||||
|
await r.loadDocument('/api/documents/abc/file');
|
||||||
|
|
||||||
|
expect(getDocument).toHaveBeenCalledTimes(1);
|
||||||
|
const arg = getDocument.mock.calls[0][0] as { url?: string; wasmUrl?: string };
|
||||||
|
expect(arg.url).toBe('/api/documents/abc/file');
|
||||||
|
expect(typeof arg.wasmUrl).toBe('string');
|
||||||
|
expect(arg.wasmUrl).not.toBe('');
|
||||||
|
expect(arg.wasmUrl?.endsWith('/')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('loadDocument sets error and loading=false when getDocument().promise rejects', async () => {
|
it('loadDocument sets error and loading=false when getDocument().promise rejects', async () => {
|
||||||
const failingLib = {
|
const failingLib = {
|
||||||
GlobalWorkerOptions: { workerSrc: '' },
|
GlobalWorkerOptions: { workerSrc: '' },
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ export type LibLoader = () => Promise<readonly [typeof import('pdfjs-dist'), { d
|
|||||||
const defaultLibLoader: LibLoader = () =>
|
const defaultLibLoader: LibLoader = () =>
|
||||||
Promise.all([import('pdfjs-dist'), import('pdfjs-dist/build/pdf.worker.min.mjs?url')]);
|
Promise.all([import('pdfjs-dist'), import('pdfjs-dist/build/pdf.worker.min.mjs?url')]);
|
||||||
|
|
||||||
|
// pdf.js 5.x decodes JBIG2 / CCITTFax / JPEG2000 images via WebAssembly and
|
||||||
|
// needs to know where the .wasm modules are served. Must be a directory URL
|
||||||
|
// with a trailing slash — pdf.js appends `jbig2.wasm` etc. Served from our own
|
||||||
|
// origin by vite-plugin-static-copy (see vite.config.ts). See issue #708.
|
||||||
|
const WASM_URL = '/pdfjs-wasm/';
|
||||||
|
|
||||||
export function createPdfRenderer(libLoader: LibLoader = defaultLibLoader) {
|
export function createPdfRenderer(libLoader: LibLoader = defaultLibLoader) {
|
||||||
// Reactive state — exposed via getters
|
// Reactive state — exposed via getters
|
||||||
let currentPage = $state(1);
|
let currentPage = $state(1);
|
||||||
@@ -44,7 +50,7 @@ export function createPdfRenderer(libLoader: LibLoader = defaultLibLoader) {
|
|||||||
totalPages = 0;
|
totalPages = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const loadingTask = pdfjsLib.getDocument(src);
|
const loadingTask = pdfjsLib.getDocument({ url: src, wasmUrl: WASM_URL });
|
||||||
const doc = await loadingTask.promise;
|
const doc = await loadingTask.promise;
|
||||||
pdfDoc = doc;
|
pdfDoc = doc;
|
||||||
totalPages = doc.numPages;
|
totalPages = doc.numPages;
|
||||||
|
|||||||
Reference in New Issue
Block a user