From 0d5a7d8adcb21318eedbc8929839d3881ba58b8d Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 7 Jul 2026 12:03:44 +0200 Subject: [PATCH 1/4] Remove TODO-comments in the "GetOperatorList" and "GetTextContent" handlers Any errors are already propagated via the stream-sinks, since these handlers use `ReadableStream`, and as mentioned in the TODO-comments re-throwing errors will lead to "spam" in the console; hence let's just remove them. --- src/core/worker.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 5ed1400d5..82297eca0 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -929,9 +929,6 @@ class WorkerMessageHandler { return; // ignoring errors from the terminated thread } sink.error(reason); - - // TODO: Should `reason` be re-thrown here (currently that casues - // "Uncaught exception: ..." messages in the console)? } ) .finally(() => { @@ -974,9 +971,6 @@ class WorkerMessageHandler { return; // ignoring errors from the terminated thread } sink.error(reason); - - // TODO: Should `reason` be re-thrown here (currently that casues - // "Uncaught exception: ..." messages in the console)? } ) .finally(() => { From d29293622e09d56bfed5bbb0ca3d09c5fc98e9de Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 7 Jul 2026 13:02:46 +0200 Subject: [PATCH 2/4] Shorten the `info`-logging in the "GetOperatorList" and "GetTextContent" handlers By re-using the `WorkerTask`-names these disabled-by-default logging statements become ever so slightly shorter, which cannot hurt. --- src/core/worker.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 82297eca0..700493103 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -915,11 +915,10 @@ class WorkerMessageHandler { pageIndex, }) .then( - operatorListInfo => { + opListInfo => { if (start) { info( - `page=${pageIndex + 1} - getOperatorList: time=` + - `${Date.now() - start}ms, len=${operatorListInfo.length}` + `${task.name}; time=${Date.now() - start}ms, len=${opListInfo.length}` ); } sink.close(); @@ -959,10 +958,7 @@ class WorkerMessageHandler { .then( () => { if (start) { - info( - `page=${pageIndex + 1} - getTextContent: time=` + - `${Date.now() - start}ms` - ); + info(`${task.name}; time=${Date.now() - start}ms`); } sink.close(); }, From f0b5fc3b732542f6bd4df064495600ceda6dabdf Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 7 Jul 2026 12:28:47 +0200 Subject: [PATCH 3/4] Remove unused parameters from worker message-handler functions A lot of these (often old) handlers don't need any parameters, hence their `data` parameters needlessly increase code-size. Also, for the functions that do need parameters, use parameter destructuring consistently throughout the message-handler functions. --- src/core/worker.js | 272 ++++++++++++++++++++++----------------------- 1 file changed, 136 insertions(+), 136 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 700493103..0f6276fb2 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -391,8 +391,8 @@ class WorkerMessageHandler { .then(pdfManagerReady, onFailure); } - handler.on("GetPage", function (data) { - return pdfManager.getPage(data.pageIndex).then(function (page) { + handler.on("GetPage", function ({ pageIndex }) { + return pdfManager.getPage(pageIndex).then(function (page) { return Promise.all([ pdfManager.ensure(page, "rotate"), pdfManager.ensure(page, "ref"), @@ -410,73 +410,65 @@ class WorkerMessageHandler { }); }); - handler.on("GetPageIndex", function (data) { - const pageRef = Ref.get(data.num, data.gen); - return pdfManager.ensureCatalog("getPageIndex", [pageRef]); + handler.on("GetPageIndex", function ({ num, gen }) { + return pdfManager.ensureCatalog("getPageIndex", [Ref.get(num, gen)]); }); - handler.on("GetDestinations", function (data) { + handler.on("GetDestinations", function () { return pdfManager.ensureCatalog("destinations"); }); - handler.on("GetDestination", function (data) { - return pdfManager.ensureCatalog("getDestination", [data.id]); + handler.on("GetDestination", function ({ id }) { + return pdfManager.ensureCatalog("getDestination", [id]); }); - handler.on("GetPageLabels", function (data) { + handler.on("GetPageLabels", function () { return pdfManager.ensureCatalog("pageLabels"); }); - handler.on("GetPageLayout", function (data) { + handler.on("GetPageLayout", function () { return pdfManager.ensureCatalog("pageLayout"); }); - handler.on("GetPageMode", function (data) { + handler.on("GetPageMode", function () { return pdfManager.ensureCatalog("pageMode"); }); - handler.on("GetViewerPreferences", function (data) { + handler.on("GetViewerPreferences", function () { return pdfManager.ensureCatalog("viewerPreferences"); }); - handler.on("GetOpenAction", function (data) { + handler.on("GetOpenAction", function () { return pdfManager.ensureCatalog("openAction"); }); - handler.on("GetAttachments", function (data) { + handler.on("GetAttachments", function () { return pdfManager.ensureCatalog("attachments"); }); - handler.on( - "GetAttachmentContent", - /** - * @param {string} id - * Unique attachment identifier (required). - */ - async function (id) { - let passwordEx; + handler.on("GetAttachmentContent", async function (id) { + let passwordEx; - // Loop to prompt again after an incorrect password. - while (true) { - const password = passwordEx ? await getPassword(passwordEx) : null; + // Loop to prompt again after an incorrect password. + while (true) { + const password = passwordEx ? await getPassword(passwordEx) : null; - try { - if (password) { - pdfManager.updatePassword(password); - } - return await pdfManager.ensureCatalog("attachmentContent", [id]); - } catch (ex) { - if (ex instanceof PasswordException) { - passwordEx = ex; - continue; - } - throw ex; + try { + if (password) { + pdfManager.updatePassword(password); } + return await pdfManager.ensureCatalog("attachmentContent", [id]); + } catch (ex) { + if (ex instanceof PasswordException) { + passwordEx = ex; + continue; + } + throw ex; } } - ); + }); - handler.on("GetDocJSActions", function (data) { + handler.on("GetDocJSActions", function () { return pdfManager.ensureCatalog("jsActions"); }); @@ -534,19 +526,19 @@ class WorkerMessageHandler { } ); - handler.on("GetOutline", function (data) { + handler.on("GetOutline", function () { return pdfManager.ensureCatalog("documentOutline"); }); - handler.on("GetOptionalContentConfig", function (data) { + handler.on("GetOptionalContentConfig", function () { return pdfManager.ensureCatalog("optionalContentConfig"); }); - handler.on("GetPermissions", function (data) { + handler.on("GetPermissions", function () { return pdfManager.ensureCatalog("permissions"); }); - handler.on("GetMetadata", function (data) { + handler.on("GetMetadata", function () { return Promise.all([ pdfManager.ensureDoc("documentInfo"), pdfManager.ensureCatalog("metadata"), @@ -554,11 +546,11 @@ class WorkerMessageHandler { ]); }); - handler.on("GetMarkInfo", function (data) { + handler.on("GetMarkInfo", function () { return pdfManager.ensureCatalog("markInfo"); }); - handler.on("GetData", function (data) { + handler.on("GetData", function () { return pdfManager.requestLoadedStream().then(stream => stream.bytes); }); @@ -573,13 +565,13 @@ class WorkerMessageHandler { }); }); - handler.on("GetFieldObjects", function (data) { + handler.on("GetFieldObjects", function () { return pdfManager .ensureDoc("fieldObjects") .then(fieldObjects => fieldObjects?.allFields || null); }); - handler.on("GetSignatures", function (data) { + handler.on("GetSignatures", function () { return pdfManager.ensureDoc("signatures"); }); @@ -587,11 +579,11 @@ class WorkerMessageHandler { return pdfManager.ensureDoc("getSignatureData", [id]); }); - handler.on("HasJSActions", function (data) { + handler.on("HasJSActions", function () { return pdfManager.ensureDoc("hasJSActions"); }); - handler.on("GetCalculationOrderIds", function (data) { + handler.on("GetCalculationOrderIds", function () { return pdfManager.ensureDoc("calculationOrderIds"); }); @@ -893,96 +885,104 @@ class WorkerMessageHandler { } ); - handler.on("GetOperatorList", function (data, sink) { - const { pageId, pageIndex } = data; - pdfManager.getPage(pageId).then(function (page) { - const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`); - startWorkerTask(task); + handler.on( + "GetOperatorList", + function ( + { pageId, pageIndex, intent, cacheKey, annotationStorage, modifiedIds }, + sink + ) { + pdfManager.getPage(pageId).then(function (page) { + const task = new WorkerTask(`GetOperatorList: page ${pageIndex}`); + startWorkerTask(task); - // NOTE: Keep this condition in sync with the `info` helper function. - const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0; + // NOTE: Keep this condition in sync with the `info` helper function. + const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0; - // Pre compile the pdf page and fetch the fonts/images. - page - .getOperatorList({ - handler, - sink, - task, - intent: data.intent, - cacheKey: data.cacheKey, - annotationStorage: data.annotationStorage, - modifiedIds: data.modifiedIds, - pageIndex, - }) - .then( - opListInfo => { - if (start) { - info( - `${task.name}; time=${Date.now() - start}ms, len=${opListInfo.length}` - ); + // Pre compile the pdf page and fetch the fonts/images. + page + .getOperatorList({ + handler, + sink, + task, + intent, + cacheKey, + annotationStorage, + modifiedIds, + pageIndex, + }) + .then( + opListInfo => { + if (start) { + info( + `${task.name}; time=${Date.now() - start}ms, len=${opListInfo.length}` + ); + } + sink.close(); + }, + reason => { + if (task.terminated) { + return; // ignoring errors from the terminated thread + } + sink.error(reason); } - sink.close(); - }, - reason => { - if (task.terminated) { - return; // ignoring errors from the terminated thread + ) + .finally(() => { + finishWorkerTask(task); + }); + }); + } + ); + + handler.on( + "GetTextContent", + function ( + { pageId, pageIndex, includeMarkedContent, disableNormalization }, + sink + ) { + pdfManager.getPage(pageId).then(function (page) { + const task = new WorkerTask("GetTextContent: page " + pageIndex); + startWorkerTask(task); + + // NOTE: Keep this condition in sync with the `info` helper function. + const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0; + + page + .extractTextContent({ + handler, + task, + sink, + includeMarkedContent, + disableNormalization, + }) + .then( + () => { + if (start) { + info(`${task.name}; time=${Date.now() - start}ms`); + } + sink.close(); + }, + reason => { + if (task.terminated) { + return; // ignoring errors from the terminated thread + } + sink.error(reason); } - sink.error(reason); - } - ) - .finally(() => { - finishWorkerTask(task); - }); - }); - }); + ) + .finally(() => { + finishWorkerTask(task); + }); + }); + } + ); - handler.on("GetTextContent", function (data, sink) { - const { pageId, pageIndex, includeMarkedContent, disableNormalization } = - data; - - pdfManager.getPage(pageId).then(function (page) { - const task = new WorkerTask("GetTextContent: page " + pageIndex); - startWorkerTask(task); - - // NOTE: Keep this condition in sync with the `info` helper function. - const start = verbosity >= VerbosityLevel.INFOS ? Date.now() : 0; - - page - .extractTextContent({ - handler, - task, - sink, - includeMarkedContent, - disableNormalization, - }) - .then( - () => { - if (start) { - info(`${task.name}; time=${Date.now() - start}ms`); - } - sink.close(); - }, - reason => { - if (task.terminated) { - return; // ignoring errors from the terminated thread - } - sink.error(reason); - } - ) - .finally(() => { - finishWorkerTask(task); - }); - }); - }); - - handler.on("GetStructTree", function (data) { + handler.on("GetStructTree", function ({ pageIndex }) { return pdfManager - .getPage(data.pageIndex) + .getPage(pageIndex) .then(page => pdfManager.ensure(page, "getStructTree")); }); - handler.on("FontFallback", function (data) { - return pdfManager.fontFallback(data.id, handler); + handler.on("FontFallback", function ({ id }) { + return pdfManager.fontFallback(id, handler); }); if ( @@ -1005,11 +1005,11 @@ class WorkerMessageHandler { }); } - handler.on("Cleanup", function (data) { + handler.on("Cleanup", function () { return pdfManager.cleanup(/* manuallyTriggered = */ true); }); - handler.on("Terminate", async function (data) { + handler.on("Terminate", async function () { terminated = true; const waitOn = []; @@ -1037,21 +1037,21 @@ class WorkerMessageHandler { handler = null; }); - handler.on("Ready", function (data) { + handler.on("Ready", function () { setupDoc(docParams); docParams = null; // we don't need docParams anymore -- saving memory. }); if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) { - handler.on("GetXFADatasets", function (data) { + handler.on("GetXFADatasets", function () { return pdfManager.ensureDoc("xfaDatasets"); }); - handler.on("GetStartXRefPos", function (data) { + handler.on("GetStartXRefPos", function () { return pdfManager.ensureDoc("startXRef"); }); - handler.on("GetAnnotArray", function (data) { + handler.on("GetAnnotArray", function ({ pageIndex }) { return pdfManager - .getPage(data.pageIndex) + .getPage(pageIndex) .then(page => page.annotations.map(a => a.toString())); }); handler.on("GetWorkerCoverage", function () { From d13c28a044113c4b5c24c803439abc1c32b88a45 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 7 Jul 2026 12:35:01 +0200 Subject: [PATCH 4/4] Change Promise-returning worker message-handler functions to be asynchronous A number of these functions are old enough that they predate async/await, and making them asynchronous is ever so slightly shorter/simpler. --- src/core/worker.js | 84 ++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 43 deletions(-) diff --git a/src/core/worker.js b/src/core/worker.js index 0f6276fb2..7ae43c5ee 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -391,23 +391,22 @@ class WorkerMessageHandler { .then(pdfManagerReady, onFailure); } - handler.on("GetPage", function ({ pageIndex }) { - return pdfManager.getPage(pageIndex).then(function (page) { - return Promise.all([ - pdfManager.ensure(page, "rotate"), - pdfManager.ensure(page, "ref"), - pdfManager.ensure(page, "userUnit"), - pdfManager.ensure(page, "view"), - ]).then(function ([rotate, ref, userUnit, view]) { - return { - rotate, - ref, - refStr: ref?.toString() ?? null, - userUnit, - view, - }; - }); - }); + handler.on("GetPage", async function ({ pageIndex }) { + const page = await pdfManager.getPage(pageIndex); + + const [rotate, ref, userUnit, view] = await Promise.all([ + pdfManager.ensure(page, "rotate"), + pdfManager.ensure(page, "ref"), + pdfManager.ensure(page, "userUnit"), + pdfManager.ensure(page, "view"), + ]); + return { + rotate, + ref, + refStr: ref?.toString() ?? null, + userUnit, + view, + }; }); handler.on("GetPageIndex", function ({ num, gen }) { @@ -472,10 +471,9 @@ class WorkerMessageHandler { return pdfManager.ensureCatalog("jsActions"); }); - handler.on("GetPageJSActions", function ({ pageIndex }) { - return pdfManager - .getPage(pageIndex) - .then(page => pdfManager.ensure(page, "jsActions")); + handler.on("GetPageJSActions", async function ({ pageIndex }) { + const page = await pdfManager.getPage(pageIndex); + return pdfManager.ensure(page, "jsActions"); }); handler.on( @@ -550,25 +548,27 @@ class WorkerMessageHandler { return pdfManager.ensureCatalog("markInfo"); }); - handler.on("GetData", function () { - return pdfManager.requestLoadedStream().then(stream => stream.bytes); + handler.on("GetData", async function () { + const stream = await pdfManager.requestLoadedStream(); + return stream.bytes; }); - handler.on("GetAnnotations", function ({ pageIndex, intent }) { - return pdfManager.getPage(pageIndex).then(function (page) { - const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`); - startWorkerTask(task); + handler.on("GetAnnotations", async function ({ pageIndex, intent }) { + const page = await pdfManager.getPage(pageIndex); - return page.getAnnotationsData(handler, task, intent).finally(() => { - finishWorkerTask(task); - }); - }); + const task = new WorkerTask(`GetAnnotations: page ${pageIndex}`); + startWorkerTask(task); + + try { + return await page.getAnnotationsData(handler, task, intent); + } finally { + finishWorkerTask(task); + } }); - handler.on("GetFieldObjects", function () { - return pdfManager - .ensureDoc("fieldObjects") - .then(fieldObjects => fieldObjects?.allFields || null); + handler.on("GetFieldObjects", async function () { + const fieldObjects = await pdfManager.ensureDoc("fieldObjects"); + return fieldObjects?.allFields || null; }); handler.on("GetSignatures", function () { @@ -975,10 +975,9 @@ class WorkerMessageHandler { } ); - handler.on("GetStructTree", function ({ pageIndex }) { - return pdfManager - .getPage(pageIndex) - .then(page => pdfManager.ensure(page, "getStructTree")); + handler.on("GetStructTree", async function ({ pageIndex }) { + const page = await pdfManager.getPage(pageIndex); + return pdfManager.ensure(page, "getStructTree"); }); handler.on("FontFallback", function ({ id }) { @@ -1049,10 +1048,9 @@ class WorkerMessageHandler { handler.on("GetStartXRefPos", function () { return pdfManager.ensureDoc("startXRef"); }); - handler.on("GetAnnotArray", function ({ pageIndex }) { - return pdfManager - .getPage(pageIndex) - .then(page => page.annotations.map(a => a.toString())); + handler.on("GetAnnotArray", async function ({ pageIndex }) { + const page = await pdfManager.getPage(pageIndex); + return page.annotations.map(a => a.toString()); }); handler.on("GetWorkerCoverage", function () { return globalThis.__coverage__ ?? {};