@embedpdf/engines 2.0.0-next.1 → 2.0.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/browser-B5Y-F6il.cjs +2 -0
  2. package/dist/browser-B5Y-F6il.cjs.map +1 -0
  3. package/dist/browser-Cm3DA8l_.js +70 -0
  4. package/dist/browser-Cm3DA8l_.js.map +1 -0
  5. package/dist/{engine-B-RaFU77.js → direct-engine-BZRK27cv.js} +197 -508
  6. package/dist/direct-engine-BZRK27cv.js.map +1 -0
  7. package/dist/direct-engine-CZAhOupl.cjs +2 -0
  8. package/dist/direct-engine-CZAhOupl.cjs.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.js +283 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/converters/browser.d.ts +32 -0
  14. package/dist/lib/converters/index.cjs +1 -1
  15. package/dist/lib/converters/index.cjs.map +1 -1
  16. package/dist/lib/converters/index.d.ts +3 -51
  17. package/dist/lib/converters/index.js +6 -1
  18. package/dist/lib/converters/index.js.map +1 -1
  19. package/dist/lib/converters/node.d.ts +51 -0
  20. package/dist/lib/converters/types.d.ts +6 -3
  21. package/dist/lib/image-encoder/image-encoder-worker.d.ts +24 -0
  22. package/dist/lib/image-encoder/index.d.ts +2 -0
  23. package/dist/lib/image-encoder/worker-pool.d.ts +61 -0
  24. package/dist/lib/orchestrator/index.d.ts +16 -0
  25. package/dist/lib/orchestrator/pdf-engine.d.ts +100 -0
  26. package/dist/lib/orchestrator/pdfium-native-runner.d.ts +65 -0
  27. package/dist/lib/orchestrator/remote-executor.d.ts +94 -0
  28. package/dist/lib/orchestrator/task-queue.d.ts +87 -0
  29. package/dist/lib/pdfium/engine.d.ts +50 -84
  30. package/dist/lib/pdfium/index.cjs +1 -1
  31. package/dist/lib/pdfium/index.cjs.map +1 -1
  32. package/dist/lib/pdfium/index.d.ts +5 -1
  33. package/dist/lib/pdfium/index.js +12 -7
  34. package/dist/lib/pdfium/index.js.map +1 -1
  35. package/dist/lib/pdfium/runner.d.ts +2 -2
  36. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  37. package/dist/lib/pdfium/web/direct-engine.cjs.map +1 -1
  38. package/dist/lib/pdfium/web/direct-engine.d.ts +33 -2
  39. package/dist/lib/pdfium/web/direct-engine.js +5 -9
  40. package/dist/lib/pdfium/web/direct-engine.js.map +1 -1
  41. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  42. package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
  43. package/dist/lib/pdfium/web/worker-engine.d.ts +40 -4
  44. package/dist/lib/pdfium/web/worker-engine.js +415 -9
  45. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  46. package/dist/lib/webworker/runner.d.ts +0 -12
  47. package/dist/pdf-engine-CrarIjJ6.cjs +2 -0
  48. package/dist/pdf-engine-CrarIjJ6.cjs.map +1 -0
  49. package/dist/pdf-engine-yZzBqL_l.js +798 -0
  50. package/dist/pdf-engine-yZzBqL_l.js.map +1 -0
  51. package/dist/preact/index.cjs +1 -1
  52. package/dist/preact/index.cjs.map +1 -1
  53. package/dist/preact/index.js +3 -3
  54. package/dist/preact/index.js.map +1 -1
  55. package/dist/react/index.cjs +1 -1
  56. package/dist/react/index.cjs.map +1 -1
  57. package/dist/react/index.js +3 -3
  58. package/dist/react/index.js.map +1 -1
  59. package/dist/shared-preact/hooks/use-pdfium-engine.d.ts +1 -0
  60. package/dist/shared-react/hooks/use-pdfium-engine.d.ts +1 -0
  61. package/dist/svelte/index.cjs +1 -1
  62. package/dist/svelte/index.cjs.map +1 -1
  63. package/dist/svelte/index.js +1 -1
  64. package/dist/svelte/index.js.map +1 -1
  65. package/dist/vue/index.cjs +1 -1
  66. package/dist/vue/index.cjs.map +1 -1
  67. package/dist/vue/index.js +2 -2
  68. package/dist/vue/index.js.map +1 -1
  69. package/package.json +3 -3
  70. package/dist/engine-B-RaFU77.js.map +0 -1
  71. package/dist/engine-CXnLqg_9.cjs +0 -2
  72. package/dist/engine-CXnLqg_9.cjs.map +0 -1
  73. package/dist/index-C3mv9vLs.js +0 -342
  74. package/dist/index-C3mv9vLs.js.map +0 -1
  75. package/dist/index-C4OBhnbs.cjs +0 -2
  76. package/dist/index-C4OBhnbs.cjs.map +0 -1
@@ -1,4 +1,7 @@
1
- import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, ignore, isUuidV4, uuidV4, PdfAnnotationSubtype, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationBorderStyle, PdfAnnotationColorType, PdfAnnotationLineEnding, PdfStampFit, PdfTrappedStatus, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, dateToPdfDate, quadToRect, rectToQuad, PdfStandardFont, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, PdfZoomMode, PdfActionType, MatchFlag } from "@embedpdf/models";
1
+ import { init } from "@embedpdf/pdfium";
2
+ import { Rotation, NoopLogger, PdfTaskHelper, PdfErrorCode, pdfDateToDate, isUuidV4, uuidV4, PdfAnnotationSubtype, PdfPageFlattenFlag, stripPdfUnwantedMarkers, PdfAnnotationIcon, PdfAnnotationBorderStyle, PdfAnnotationColorType, PdfAnnotationLineEnding, PdfStampFit, PdfTrappedStatus, pdfColorToWebColor, webColorToPdfColor, pdfAlphaToWebOpacity, webOpacityToPdfAlpha, dateToPdfDate, quadToRect, rectToQuad, PdfStandardFont, PdfPageObjectType, flagsToNames, namesToFlags, PDF_FORM_FIELD_TYPE, AppearanceMode, Task, toIntRect, transformRect, buildUserToDeviceMatrix, PdfZoomMode, PdfActionType } from "@embedpdf/models";
3
+ import { P as PdfEngine } from "./pdf-engine-yZzBqL_l.js";
4
+ import { b as browserImageDataToBlobConverter } from "./browser-Cm3DA8l_.js";
2
5
  function readString(wasmModule, readChars, parseChars, defaultLength = 100) {
3
6
  let buffer = wasmModule.wasmExports.malloc(defaultLength);
4
7
  for (let i = 0; i < defaultLength; i++) {
@@ -482,27 +485,7 @@ var PdfiumErrorCode = /* @__PURE__ */ ((PdfiumErrorCode2) => {
482
485
  PdfiumErrorCode2[PdfiumErrorCode2["XFALayout"] = 8] = "XFALayout";
483
486
  return PdfiumErrorCode2;
484
487
  })(PdfiumErrorCode || {});
485
- class OffscreenCanvasError extends Error {
486
- constructor(message) {
487
- super(message);
488
- this.name = "OffscreenCanvasError";
489
- }
490
- }
491
- const browserImageDataToBlobConverter = (getImageData, imageType = "image/webp", quality) => {
492
- if (typeof OffscreenCanvas === "undefined") {
493
- return Promise.reject(
494
- new OffscreenCanvasError(
495
- "OffscreenCanvas is not available in this environment. This converter is intended for browser use only. Falling back to WASM-based image encoding."
496
- )
497
- );
498
- }
499
- const pdfImage = getImageData();
500
- const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);
501
- const off = new OffscreenCanvas(imageData.width, imageData.height);
502
- off.getContext("2d").putImageData(imageData, 0, 0);
503
- return off.convertToBlob({ type: imageType, quality });
504
- };
505
- class PdfiumEngine {
488
+ class PdfiumNative {
506
489
  /**
507
490
  * Create an instance of PdfiumEngine
508
491
  * @param wasmModule - pdfium wasm module
@@ -512,12 +495,8 @@ class PdfiumEngine {
512
495
  constructor(pdfiumModule, options = {}) {
513
496
  this.pdfiumModule = pdfiumModule;
514
497
  this.memoryLeakCheckInterval = null;
515
- const {
516
- logger = new NoopLogger(),
517
- imageDataConverter = browserImageDataToBlobConverter
518
- } = options;
498
+ const { logger = new NoopLogger() } = options;
519
499
  this.logger = logger;
520
- this.imageDataConverter = imageDataConverter;
521
500
  this.memoryManager = new MemoryManager(this.pdfiumModule, this.logger);
522
501
  this.cache = new PdfCache(this.pdfiumModule, this.memoryManager);
523
502
  if (this.logger.isEnabled("debug")) {
@@ -581,165 +560,6 @@ class PdfiumEngine {
581
560
  if (bytes) this.memoryManager.free(ptr);
582
561
  }
583
562
  }
584
- /**
585
- * {@inheritDoc @embedpdf/models!PdfEngine.openDocumentUrl}
586
- *
587
- * @public
588
- */
589
- openDocumentUrl(file, options) {
590
- const mode = (options == null ? void 0 : options.mode) ?? "auto";
591
- const password = (options == null ? void 0 : options.password) ?? "";
592
- const requestOptions = options == null ? void 0 : options.requestOptions;
593
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "openDocumentUrl called", file.url, mode);
594
- const task = PdfTaskHelper.create();
595
- (async () => {
596
- try {
597
- const fetchFullTask = await this.fetchFullAndOpen(file, password, requestOptions);
598
- fetchFullTask.wait(
599
- (doc) => task.resolve(doc),
600
- (err) => task.reject(err.reason)
601
- );
602
- } catch (err) {
603
- this.logger.error(LOG_SOURCE, LOG_CATEGORY, "openDocumentUrl error", err);
604
- task.reject({
605
- code: PdfErrorCode.Unknown,
606
- message: String(err)
607
- });
608
- }
609
- })();
610
- return task;
611
- }
612
- /**
613
- * Check if the server supports range requests:
614
- * Sends a HEAD request and sees if 'Accept-Ranges: bytes'.
615
- */
616
- async checkRangeSupport(url, requestOptions) {
617
- try {
618
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "checkRangeSupport", url);
619
- const headResponse = await fetch(url, {
620
- method: "HEAD",
621
- headers: requestOptions == null ? void 0 : requestOptions.headers,
622
- credentials: requestOptions == null ? void 0 : requestOptions.credentials
623
- });
624
- const fileLength = headResponse.headers.get("Content-Length");
625
- const acceptRanges = headResponse.headers.get("Accept-Ranges");
626
- if (acceptRanges === "bytes") {
627
- return {
628
- supportsRanges: true,
629
- fileLength: parseInt(fileLength ?? "0"),
630
- content: null
631
- };
632
- }
633
- const testResponse = await fetch(url, {
634
- headers: { ...requestOptions == null ? void 0 : requestOptions.headers, Range: "bytes=0-1" },
635
- credentials: requestOptions == null ? void 0 : requestOptions.credentials
636
- });
637
- if (testResponse.status === 200) {
638
- const content = await testResponse.arrayBuffer();
639
- return {
640
- supportsRanges: false,
641
- fileLength: parseInt(fileLength ?? "0"),
642
- content
643
- };
644
- }
645
- return {
646
- supportsRanges: testResponse.status === 206,
647
- fileLength: parseInt(fileLength ?? "0"),
648
- content: null
649
- };
650
- } catch (e) {
651
- this.logger.error(LOG_SOURCE, LOG_CATEGORY, "checkRangeSupport failed", e);
652
- throw new Error("Failed to check range support: " + e);
653
- }
654
- }
655
- /**
656
- * Fully fetch the file (using fetch) into an ArrayBuffer,
657
- * then call openDocumentFromBuffer.
658
- */
659
- async fetchFullAndOpen(file, password, requestOptions) {
660
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "fetchFullAndOpen", file.url);
661
- const response = await fetch(file.url, {
662
- headers: requestOptions == null ? void 0 : requestOptions.headers,
663
- credentials: requestOptions == null ? void 0 : requestOptions.credentials
664
- });
665
- if (!response.ok) {
666
- throw new Error(`Could not fetch PDF: ${response.statusText}`);
667
- }
668
- const arrayBuf = await response.arrayBuffer();
669
- const pdfFile = {
670
- id: file.id,
671
- content: arrayBuf
672
- };
673
- return this.openDocumentBuffer(pdfFile, { password });
674
- }
675
- /**
676
- * Use your synchronous partial-loading approach:
677
- * - In your snippet, it's done via `openDocumentFromLoader`.
678
- * - We'll do a synchronous XHR read callback that pulls
679
- * the desired byte ranges.
680
- */
681
- async openDocumentWithRangeRequest(file, password, knownFileLength, requestOptions) {
682
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "openDocumentWithRangeRequest", file.url);
683
- const fileLength = knownFileLength ?? (await this.retrieveFileLength(file.url, requestOptions)).fileLength;
684
- const callback = (offset, length) => {
685
- const xhr = new XMLHttpRequest();
686
- xhr.open("GET", file.url, false);
687
- xhr.overrideMimeType("text/plain; charset=x-user-defined");
688
- xhr.setRequestHeader("Range", `bytes=${offset}-${offset + length - 1}`);
689
- if (requestOptions == null ? void 0 : requestOptions.headers) {
690
- Object.entries(requestOptions.headers).forEach(([key, value]) => {
691
- xhr.setRequestHeader(key, value);
692
- });
693
- }
694
- if (requestOptions == null ? void 0 : requestOptions.credentials) {
695
- xhr.withCredentials = requestOptions.credentials === "include";
696
- }
697
- xhr.send(null);
698
- if (xhr.status === 206 || xhr.status === 200) {
699
- return this.convertResponseToUint8Array(xhr.responseText);
700
- }
701
- throw new Error(`Range request failed with status ${xhr.status}`);
702
- };
703
- return this.openDocumentFromLoader(
704
- {
705
- id: file.id,
706
- fileLength,
707
- callback
708
- },
709
- password
710
- );
711
- }
712
- /**
713
- * Helper to do a HEAD request or partial GET to find file length.
714
- */
715
- async retrieveFileLength(url, requestOptions) {
716
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "retrieveFileLength", url);
717
- const resp = await fetch(url, {
718
- method: "HEAD",
719
- headers: requestOptions == null ? void 0 : requestOptions.headers,
720
- credentials: requestOptions == null ? void 0 : requestOptions.credentials
721
- });
722
- if (!resp.ok) {
723
- throw new Error(`Failed HEAD request for file length: ${resp.statusText}`);
724
- }
725
- const lenStr = resp.headers.get("Content-Length") || "0";
726
- const fileLength = parseInt(lenStr, 10) || 0;
727
- if (!fileLength) {
728
- throw new Error(`Content-Length not found or zero.`);
729
- }
730
- return { fileLength };
731
- }
732
- /**
733
- * Convert response text (x-user-defined) to a Uint8Array
734
- * for partial data.
735
- */
736
- convertResponseToUint8Array(text) {
737
- const array = new Uint8Array(text.length);
738
- for (let i = 0; i < text.length; i++) {
739
- array[i] = text.charCodeAt(i) & 255;
740
- }
741
- return array;
742
- }
743
563
  /**
744
564
  * {@inheritDoc @embedpdf/models!PdfEngine.openDocument}
745
565
  *
@@ -805,89 +625,6 @@ class PdfiumEngine {
805
625
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `OpenDocumentBuffer`, "End", file.id);
806
626
  return PdfTaskHelper.resolve(pdfDoc);
807
627
  }
808
- openDocumentFromLoader(fileLoader, password = "") {
809
- const { fileLength, callback, ...file } = fileLoader;
810
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "openDocumentFromLoader", file, password);
811
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `OpenDocumentFromLoader`, "Begin", file.id);
812
- const readBlock = (_pThis, offset, pBuf, length) => {
813
- try {
814
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "readBlock", offset, length, pBuf);
815
- if (offset < 0 || offset >= fileLength) {
816
- this.logger.error(LOG_SOURCE, LOG_CATEGORY, "Offset out of bounds:", offset);
817
- return 0;
818
- }
819
- const data = callback(offset, length);
820
- const dest = new Uint8Array(this.pdfiumModule.pdfium.HEAPU8.buffer, pBuf, data.length);
821
- dest.set(data);
822
- return data.length;
823
- } catch (error) {
824
- this.logger.error(LOG_SOURCE, LOG_CATEGORY, "ReadBlock error:", error);
825
- return 0;
826
- }
827
- };
828
- const callbackPtr = this.pdfiumModule.pdfium.addFunction(readBlock, "iiiii");
829
- const structSize = 12;
830
- const fileAccessPtr = this.memoryManager.malloc(structSize);
831
- this.pdfiumModule.pdfium.setValue(fileAccessPtr, fileLength, "i32");
832
- this.pdfiumModule.pdfium.setValue(fileAccessPtr + 4, callbackPtr, "i32");
833
- this.pdfiumModule.pdfium.setValue(fileAccessPtr + 8, 0, "i32");
834
- const docPtr = this.pdfiumModule.FPDF_LoadCustomDocument(fileAccessPtr, password);
835
- if (!docPtr) {
836
- const lastError = this.pdfiumModule.FPDF_GetLastError();
837
- this.logger.error(
838
- LOG_SOURCE,
839
- LOG_CATEGORY,
840
- `FPDF_LoadCustomDocument failed with ${lastError}`
841
- );
842
- this.memoryManager.free(fileAccessPtr);
843
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `OpenDocumentFromLoader`, "End", file.id);
844
- return PdfTaskHelper.reject({
845
- code: lastError,
846
- message: `FPDF_LoadCustomDocument failed`
847
- });
848
- }
849
- const pageCount = this.pdfiumModule.FPDF_GetPageCount(docPtr);
850
- const pages = [];
851
- const sizePtr = this.memoryManager.malloc(8);
852
- for (let index = 0; index < pageCount; index++) {
853
- const result = this.pdfiumModule.FPDF_GetPageSizeByIndexF(docPtr, index, sizePtr);
854
- if (!result) {
855
- const lastError = this.pdfiumModule.FPDF_GetLastError();
856
- this.logger.error(
857
- LOG_SOURCE,
858
- LOG_CATEGORY,
859
- `FPDF_GetPageSizeByIndexF failed with ${lastError}`
860
- );
861
- this.memoryManager.free(sizePtr);
862
- this.pdfiumModule.FPDF_CloseDocument(docPtr);
863
- this.memoryManager.free(fileAccessPtr);
864
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `OpenDocumentFromLoader`, "End", file.id);
865
- return PdfTaskHelper.reject({
866
- code: lastError,
867
- message: `FPDF_GetPageSizeByIndexF failed`
868
- });
869
- }
870
- const rotation = this.pdfiumModule.EPDF_GetPageRotationByIndex(docPtr, index);
871
- const page = {
872
- index,
873
- size: {
874
- width: this.pdfiumModule.pdfium.getValue(sizePtr, "float"),
875
- height: this.pdfiumModule.pdfium.getValue(sizePtr + 4, "float")
876
- },
877
- rotation
878
- };
879
- pages.push(page);
880
- }
881
- this.memoryManager.free(sizePtr);
882
- const pdfDoc = {
883
- id: file.id,
884
- pageCount,
885
- pages
886
- };
887
- this.cache.setDocument(file.id, fileAccessPtr, docPtr);
888
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `OpenDocumentFromLoader`, "End", file.id);
889
- return PdfTaskHelper.resolve(pdfDoc);
890
- }
891
628
  /**
892
629
  * {@inheritDoc @embedpdf/models!PdfEngine.getMetadata}
893
630
  *
@@ -1187,7 +924,7 @@ class PdfiumEngine {
1187
924
  *
1188
925
  * @public
1189
926
  */
1190
- renderPage(doc, page, options) {
927
+ renderPageRaw(doc, page, options) {
1191
928
  this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "renderPage", doc, page, options);
1192
929
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `RenderPage`, "Begin", `${doc.id}-${page.index}`);
1193
930
  const rect = { origin: { x: 0, y: 0 }, size: page.size };
@@ -1213,56 +950,6 @@ class PdfiumEngine {
1213
950
  this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `RenderPageRect`, "End", `${doc.id}-${page.index}`);
1214
951
  return task;
1215
952
  }
1216
- /**
1217
- * {@inheritDoc @embedpdf/models!PdfEngine.getAllAnnotations}
1218
- *
1219
- * @public
1220
- */
1221
- getAllAnnotations(doc) {
1222
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getAllAnnotations-with-progress", doc);
1223
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAllAnnotations", "Begin", doc.id);
1224
- const task = PdfTaskHelper.create();
1225
- let cancelled = false;
1226
- task.wait(ignore, (err) => {
1227
- if (err.type === "abort") cancelled = true;
1228
- });
1229
- const ctx = this.cache.getContext(doc.id);
1230
- if (!ctx) {
1231
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAllAnnotations", "End", doc.id);
1232
- task.reject({ code: PdfErrorCode.DocNotOpen, message: "document does not open" });
1233
- return task;
1234
- }
1235
- const CHUNK_SIZE = 100;
1236
- const out = {};
1237
- const processChunk = (startIdx) => {
1238
- if (cancelled) return;
1239
- const endIdx = Math.min(startIdx + CHUNK_SIZE, doc.pageCount);
1240
- for (let pageIdx = startIdx; pageIdx < endIdx && !cancelled; ++pageIdx) {
1241
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "GetAllAnnotations", "Begin", doc.id, pageIdx);
1242
- const annots = this.readPageAnnotationsRaw(ctx, doc.pages[pageIdx]);
1243
- out[pageIdx] = annots;
1244
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "GetAllAnnotations", "End", doc.id, pageIdx);
1245
- task.progress({ page: pageIdx, annotations: annots });
1246
- }
1247
- if (cancelled) return;
1248
- if (endIdx >= doc.pageCount) {
1249
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAllAnnotations", "End", doc.id);
1250
- task.resolve(out);
1251
- return;
1252
- }
1253
- setTimeout(() => processChunk(endIdx), 0);
1254
- };
1255
- processChunk(0);
1256
- return task;
1257
- }
1258
- readAllAnnotations(doc, ctx) {
1259
- const annotationsByPage = {};
1260
- for (let i = 0; i < doc.pageCount; i++) {
1261
- const pageAnnotations = this.readPageAnnotations(ctx, doc.pages[i]);
1262
- annotationsByPage[i] = pageAnnotations;
1263
- }
1264
- return annotationsByPage;
1265
- }
1266
953
  /**
1267
954
  * {@inheritDoc @embedpdf/models!PdfEngine.getPageAnnotations}
1268
955
  *
@@ -1688,7 +1375,7 @@ class PdfiumEngine {
1688
1375
  *
1689
1376
  * @public
1690
1377
  */
1691
- renderThumbnail(doc, page, options) {
1378
+ renderThumbnailRaw(doc, page, options) {
1692
1379
  const { scaleFactor = 1, ...rest } = options ?? {};
1693
1380
  this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "renderThumbnail", doc, page, options);
1694
1381
  this.logger.perf(
@@ -1712,7 +1399,7 @@ class PdfiumEngine {
1712
1399
  message: "document does not open"
1713
1400
  });
1714
1401
  }
1715
- const result = this.renderPage(doc, page, {
1402
+ const result = this.renderPageRaw(doc, page, {
1716
1403
  scaleFactor: Math.max(scaleFactor, 0.5),
1717
1404
  ...rest
1718
1405
  });
@@ -3560,7 +3247,7 @@ class PdfiumEngine {
3560
3247
  });
3561
3248
  }
3562
3249
  /**
3563
- * Read page annotations
3250
+ * Read page annotations without loading the page (raw approach)
3564
3251
  *
3565
3252
  * @param ctx - document context
3566
3253
  * @param page - page info
@@ -3584,6 +3271,48 @@ class PdfiumEngine {
3584
3271
  }
3585
3272
  return out;
3586
3273
  }
3274
+ /**
3275
+ * Get page annotations (public API, returns Task)
3276
+ *
3277
+ * @param doc - pdf document
3278
+ * @param page - page info
3279
+ * @returns task with annotations on the pdf page
3280
+ *
3281
+ * @public
3282
+ */
3283
+ getPageAnnotationsRaw(doc, page) {
3284
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getPageAnnotationsRaw", doc, page);
3285
+ this.logger.perf(
3286
+ LOG_SOURCE,
3287
+ LOG_CATEGORY,
3288
+ `GetPageAnnotationsRaw`,
3289
+ "Begin",
3290
+ `${doc.id}-${page.index}`
3291
+ );
3292
+ const ctx = this.cache.getContext(doc.id);
3293
+ if (!ctx) {
3294
+ return PdfTaskHelper.reject({
3295
+ code: PdfErrorCode.DocNotOpen,
3296
+ message: "document does not open"
3297
+ });
3298
+ }
3299
+ const out = this.readPageAnnotationsRaw(ctx, page);
3300
+ this.logger.perf(
3301
+ LOG_SOURCE,
3302
+ LOG_CATEGORY,
3303
+ `GetPageAnnotationsRaw`,
3304
+ "End",
3305
+ `${doc.id}-${page.index}`
3306
+ );
3307
+ this.logger.debug(
3308
+ LOG_SOURCE,
3309
+ LOG_CATEGORY,
3310
+ "getPageAnnotationsRaw",
3311
+ `${doc.id}-${page.index}`,
3312
+ out
3313
+ );
3314
+ return PdfTaskHelper.resolve(out);
3315
+ }
3587
3316
  /**
3588
3317
  * Read pdf annotation from pdf document
3589
3318
  *
@@ -5783,14 +5512,12 @@ class PdfiumEngine {
5783
5512
  *
5784
5513
  * @public
5785
5514
  */
5786
- renderPageAnnotation(doc, page, annotation, options) {
5515
+ renderPageAnnotationRaw(doc, page, annotation, options) {
5787
5516
  const {
5788
5517
  scaleFactor = 1,
5789
5518
  rotation = Rotation.Degree0,
5790
5519
  dpr = 1,
5791
- mode = AppearanceMode.Normal,
5792
- imageType = "image/webp",
5793
- imageQuality
5520
+ mode = AppearanceMode.Normal
5794
5521
  } = options ?? {};
5795
5522
  this.logger.debug(
5796
5523
  LOG_SOURCE,
@@ -5893,97 +5620,14 @@ class PdfiumEngine {
5893
5620
  message: "EPDF_RenderAnnotBitmap failed"
5894
5621
  });
5895
5622
  }
5896
- const dispose = () => this.memoryManager.free(heapPtr);
5897
- this.imageDataConverter(
5898
- () => {
5899
- const rgba = new Uint8ClampedArray(
5900
- this.pdfiumModule.pdfium.HEAPU8.subarray(heapPtr, heapPtr + bytes)
5901
- );
5902
- return {
5903
- width: wDev,
5904
- height: hDev,
5905
- data: rgba
5906
- };
5907
- },
5908
- imageType,
5909
- imageQuality
5910
- ).then((out) => task.resolve(out)).catch((e) => {
5911
- if (e instanceof OffscreenCanvasError) {
5912
- try {
5913
- const blob = this.encodeViaWasm(
5914
- { ptr: heapPtr, width: wDev, height: hDev, stride },
5915
- { type: imageType, quality: imageQuality }
5916
- );
5917
- task.resolve(blob);
5918
- } catch (wasmError) {
5919
- task.reject({ code: PdfErrorCode.Unknown, message: String(wasmError) });
5920
- }
5921
- } else {
5922
- task.reject({ code: PdfErrorCode.Unknown, message: String(e) });
5923
- }
5924
- }).finally(dispose);
5623
+ const data = this.pdfiumModule.pdfium.HEAPU8.subarray(heapPtr, heapPtr + bytes);
5624
+ const imageData = new ImageData(new Uint8ClampedArray(data), wDev, hDev);
5625
+ task.resolve(imageData);
5626
+ this.memoryManager.free(heapPtr);
5925
5627
  return task;
5926
5628
  }
5927
- encodeViaWasm(buf, opts) {
5928
- const pdf = this.pdfiumModule.pdfium;
5929
- const blobFrom = (outPtr, size, mime) => {
5930
- const view = pdf.HEAPU8.subarray(outPtr, outPtr + size);
5931
- const copy = new Uint8Array(view);
5932
- this.memoryManager.free(outPtr);
5933
- return new Blob([copy], { type: mime });
5934
- };
5935
- const pngLevel = 6;
5936
- const outPtrPtr = this.memoryManager.malloc(4);
5937
- try {
5938
- switch (opts.type) {
5939
- /*
5940
- case 'image/webp': {
5941
- const size = this.pdfiumModule.EPDF_WebP_EncodeRGBA(
5942
- buf.ptr,
5943
- buf.width,
5944
- buf.height,
5945
- buf.stride,
5946
- webpQ,
5947
- outPtrPtr,
5948
- );
5949
- const outPtr = pdf.getValue(outPtrPtr, 'i32');
5950
- return blobFrom(outPtr, size, 'image/webp');
5951
- }
5952
- case 'image/jpeg': {
5953
- const size = this.pdfiumModule.EPDF_JPEG_EncodeRGBA(
5954
- buf.ptr,
5955
- buf.width,
5956
- buf.height,
5957
- buf.stride,
5958
- jpegQ,
5959
- outPtrPtr,
5960
- );
5961
- const outPtr = pdf.getValue(outPtrPtr, 'i32');
5962
- return blobFrom(outPtr, size, 'image/jpeg');
5963
- }
5964
- */
5965
- case "image/png":
5966
- default: {
5967
- const size = this.pdfiumModule.EPDF_PNG_EncodeRGBA(
5968
- buf.ptr,
5969
- buf.width,
5970
- buf.height,
5971
- buf.stride,
5972
- pngLevel,
5973
- outPtrPtr
5974
- );
5975
- const outPtr = pdf.getValue(outPtrPtr, "i32");
5976
- return blobFrom(WasmPointer(outPtr), size, "image/png");
5977
- }
5978
- }
5979
- } finally {
5980
- this.memoryManager.free(outPtrPtr);
5981
- }
5982
- }
5983
5629
  renderRectEncoded(doc, page, rect, options) {
5984
5630
  const task = new Task();
5985
- const imageType = (options == null ? void 0 : options.imageType) ?? "image/webp";
5986
- const quality = options == null ? void 0 : options.imageQuality;
5987
5631
  const rotation = (options == null ? void 0 : options.rotation) ?? Rotation.Degree0;
5988
5632
  const ctx = this.cache.getContext(doc.id);
5989
5633
  if (!ctx) {
@@ -6051,39 +5695,39 @@ class PdfiumEngine {
6051
5695
  this.memoryManager.free(mPtr);
6052
5696
  this.memoryManager.free(clipPtr);
6053
5697
  }
6054
- const dispose = () => {
6055
- this.pdfiumModule.FPDFBitmap_Destroy(bitmapPtr);
6056
- this.memoryManager.free(heapPtr);
6057
- };
6058
- this.imageDataConverter(
6059
- () => {
6060
- const heapBuf = this.pdfiumModule.pdfium.HEAPU8.buffer;
6061
- const data = new Uint8ClampedArray(heapBuf, heapPtr, bytes);
6062
- return {
6063
- width: wDev,
6064
- height: hDev,
6065
- data
6066
- };
6067
- },
6068
- imageType,
6069
- quality
6070
- ).then((out) => task.resolve(out)).catch((e) => {
6071
- this.logger.error(LOG_SOURCE, LOG_CATEGORY, "Error", e);
6072
- if (e instanceof OffscreenCanvasError) {
6073
- this.logger.info(LOG_SOURCE, LOG_CATEGORY, "Fallback to WASM encoding");
6074
- try {
6075
- const blob = this.encodeViaWasm(
6076
- { ptr: heapPtr, width: wDev, height: hDev, stride },
6077
- { type: imageType, quality }
6078
- );
6079
- task.resolve(blob);
6080
- } catch (wasmError) {
6081
- task.reject({ code: PdfErrorCode.Unknown, message: String(wasmError) });
6082
- }
6083
- } else {
6084
- task.reject({ code: PdfErrorCode.Unknown, message: String(e) });
6085
- }
6086
- }).finally(dispose);
5698
+ this.logger.perf(
5699
+ LOG_SOURCE,
5700
+ LOG_CATEGORY,
5701
+ `RenderRectEncodedData`,
5702
+ "Begin",
5703
+ `${doc.id}-${page.index}`
5704
+ );
5705
+ const data = this.pdfiumModule.pdfium.HEAPU8.subarray(heapPtr, heapPtr + bytes);
5706
+ this.logger.perf(
5707
+ LOG_SOURCE,
5708
+ LOG_CATEGORY,
5709
+ `RenderRectEncodedData`,
5710
+ "End",
5711
+ `${doc.id}-${page.index}`
5712
+ );
5713
+ this.logger.perf(
5714
+ LOG_SOURCE,
5715
+ LOG_CATEGORY,
5716
+ `RenderRectEncodedImageData`,
5717
+ "Begin",
5718
+ `${doc.id}-${page.index}`
5719
+ );
5720
+ const imageData = new ImageData(new Uint8ClampedArray(data), wDev, hDev);
5721
+ this.logger.perf(
5722
+ LOG_SOURCE,
5723
+ LOG_CATEGORY,
5724
+ `RenderRectEncodedImageData`,
5725
+ "End",
5726
+ `${doc.id}-${page.index}`
5727
+ );
5728
+ task.resolve(imageData);
5729
+ this.pdfiumModule.FPDFBitmap_Destroy(bitmapPtr);
5730
+ this.memoryManager.free(heapPtr);
6087
5731
  return task;
6088
5732
  }
6089
5733
  /**
@@ -6671,75 +6315,110 @@ class PdfiumEngine {
6671
6315
  *
6672
6316
  * @public
6673
6317
  */
6674
- searchAllPages(doc, keyword, options) {
6675
- var _a;
6676
- this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "searchAllPages", doc, keyword, options);
6677
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchAllPages", "Begin", doc.id);
6318
+ searchInPage(doc, page, keyword, flags) {
6319
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "searchInPage", doc, page, keyword, flags);
6320
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `SearchInPage`, "Begin", `${doc.id}-${page.index}`);
6678
6321
  const ctx = this.cache.getContext(doc.id);
6679
6322
  if (!ctx) {
6680
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchAllPages", "End", doc.id);
6681
- return PdfTaskHelper.resolve({
6682
- results: [],
6683
- total: 0
6323
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, `PreparePrintDocument`, "End", doc.id);
6324
+ return PdfTaskHelper.reject({
6325
+ code: PdfErrorCode.DocNotOpen,
6326
+ message: "Document is not open"
6684
6327
  });
6685
6328
  }
6686
6329
  const length = 2 * (keyword.length + 1);
6687
6330
  const keywordPtr = this.memoryManager.malloc(length);
6688
6331
  this.pdfiumModule.pdfium.stringToUTF16(keyword, keywordPtr, length);
6689
- const flag = ((_a = options == null ? void 0 : options.flags) == null ? void 0 : _a.reduce((acc, f) => acc | f, MatchFlag.None)) ?? MatchFlag.None;
6690
- const task = PdfTaskHelper.create();
6691
- let cancelled = false;
6692
- task.wait(
6693
- () => {
6694
- },
6695
- (err) => {
6696
- if (err.type === "abort") cancelled = true;
6697
- }
6698
- );
6699
- const CHUNK_SIZE = 100;
6700
- const allResults = [];
6701
- const processChunk = (startIdx) => {
6702
- if (cancelled) return;
6703
- const endIdx = Math.min(startIdx + CHUNK_SIZE, doc.pageCount);
6704
- try {
6705
- for (let pageIndex = startIdx; pageIndex < endIdx && !cancelled; pageIndex++) {
6706
- const pageResults = this.searchAllInPage(ctx, doc.pages[pageIndex], keywordPtr, flag);
6707
- allResults.push(...pageResults);
6708
- task.progress({ page: pageIndex, results: pageResults });
6709
- }
6710
- } catch (e) {
6711
- if (!cancelled) {
6712
- this.memoryManager.free(keywordPtr);
6713
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchAllPages", "End", doc.id);
6714
- task.reject({
6715
- code: PdfErrorCode.Unknown,
6716
- message: `Error searching document: ${e}`
6717
- });
6718
- }
6332
+ try {
6333
+ const results = this.searchAllInPage(ctx, page, keywordPtr, flags);
6334
+ return PdfTaskHelper.resolve(results);
6335
+ } finally {
6336
+ this.memoryManager.free(keywordPtr);
6337
+ }
6338
+ }
6339
+ /**
6340
+ * Get annotations for multiple pages in a single batch.
6341
+ * Emits progress per page for streaming updates.
6342
+ *
6343
+ * @param doc - PDF document
6344
+ * @param pages - Array of pages to process
6345
+ * @returns Task with results keyed by page index, with per-page progress
6346
+ *
6347
+ * @public
6348
+ */
6349
+ getAnnotationsBatch(doc, pages) {
6350
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "getAnnotationsBatch", doc.id, pages.length);
6351
+ const task = new Task();
6352
+ queueMicrotask(() => {
6353
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAnnotationsBatch", "Begin", doc.id);
6354
+ const ctx = this.cache.getContext(doc.id);
6355
+ if (!ctx) {
6356
+ task.reject({ code: PdfErrorCode.DocNotOpen, message: "Document is not open" });
6719
6357
  return;
6720
6358
  }
6721
- if (cancelled) return;
6722
- if (endIdx >= doc.pageCount) {
6723
- this.memoryManager.free(keywordPtr);
6724
- this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchAllPages", "End", doc.id);
6725
- task.resolve({ results: allResults, total: allResults.length });
6359
+ const results = {};
6360
+ const total = pages.length;
6361
+ for (let i = 0; i < pages.length; i++) {
6362
+ const page = pages[i];
6363
+ const annotations = this.readPageAnnotationsRaw(ctx, page);
6364
+ results[page.index] = annotations;
6365
+ task.progress({
6366
+ pageIndex: page.index,
6367
+ result: annotations,
6368
+ completed: i + 1,
6369
+ total
6370
+ });
6371
+ }
6372
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "GetAnnotationsBatch", "End", doc.id);
6373
+ task.resolve(results);
6374
+ });
6375
+ return task;
6376
+ }
6377
+ /**
6378
+ * Search across multiple pages in a single batch.
6379
+ * Emits progress per page for streaming updates.
6380
+ *
6381
+ * @param doc - PDF document
6382
+ * @param pages - Array of pages to search
6383
+ * @param keyword - Search keyword
6384
+ * @param flags - Search flags
6385
+ * @returns Task with results keyed by page index, with per-page progress
6386
+ *
6387
+ * @public
6388
+ */
6389
+ searchBatch(doc, pages, keyword, flags) {
6390
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "searchBatch", doc.id, pages.length, keyword);
6391
+ const task = new Task();
6392
+ queueMicrotask(() => {
6393
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchBatch", "Begin", doc.id);
6394
+ const ctx = this.cache.getContext(doc.id);
6395
+ if (!ctx) {
6396
+ task.reject({ code: PdfErrorCode.DocNotOpen, message: "Document is not open" });
6726
6397
  return;
6727
6398
  }
6728
- setTimeout(() => processChunk(endIdx), 0);
6729
- };
6730
- setTimeout(() => processChunk(0), 0);
6731
- task.wait(
6732
- () => {
6733
- },
6734
- (err) => {
6735
- if (err.type === "abort") {
6736
- try {
6737
- this.memoryManager.free(keywordPtr);
6738
- } catch {
6739
- }
6399
+ const length = 2 * (keyword.length + 1);
6400
+ const keywordPtr = this.memoryManager.malloc(length);
6401
+ this.pdfiumModule.pdfium.stringToUTF16(keyword, keywordPtr, length);
6402
+ try {
6403
+ const results = {};
6404
+ const total = pages.length;
6405
+ for (let i = 0; i < pages.length; i++) {
6406
+ const page = pages[i];
6407
+ const pageResults = this.searchAllInPage(ctx, page, keywordPtr, flags);
6408
+ results[page.index] = pageResults;
6409
+ task.progress({
6410
+ pageIndex: page.index,
6411
+ result: pageResults,
6412
+ completed: i + 1,
6413
+ total
6414
+ });
6740
6415
  }
6416
+ this.logger.perf(LOG_SOURCE, LOG_CATEGORY, "SearchBatch", "End", doc.id);
6417
+ task.resolve(results);
6418
+ } finally {
6419
+ this.memoryManager.free(keywordPtr);
6741
6420
  }
6742
- );
6421
+ });
6743
6422
  return task;
6744
6423
  }
6745
6424
  /**
@@ -7078,16 +6757,26 @@ class PdfiumEngine {
7078
6757
  }
7079
6758
  }
7080
6759
  }
6760
+ async function createPdfiumEngine(wasmUrl, options) {
6761
+ const response = await fetch(wasmUrl);
6762
+ const wasmBinary = await response.arrayBuffer();
6763
+ const wasmModule = await init({ wasmBinary });
6764
+ const native = new PdfiumNative(wasmModule, { logger: options == null ? void 0 : options.logger });
6765
+ native.initialize();
6766
+ return new PdfEngine(native, {
6767
+ imageConverter: browserImageDataToBlobConverter,
6768
+ logger: options == null ? void 0 : options.logger
6769
+ });
6770
+ }
7081
6771
  export {
7082
6772
  BitmapFormat as B,
7083
- OffscreenCanvasError as O,
7084
6773
  PdfiumErrorCode as P,
7085
6774
  RenderFlag as R,
7086
- PdfiumEngine as a,
7087
- browserImageDataToBlobConverter as b,
7088
- readArrayBuffer as c,
6775
+ PdfiumNative as a,
6776
+ readArrayBuffer as b,
6777
+ createPdfiumEngine as c,
7089
6778
  computeFormDrawParams as d,
7090
6779
  isValidCustomKey as i,
7091
6780
  readString as r
7092
6781
  };
7093
- //# sourceMappingURL=engine-B-RaFU77.js.map
6782
+ //# sourceMappingURL=direct-engine-BZRK27cv.js.map