@embedpdf/engines 2.11.1 → 2.12.0

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 (35) hide show
  1. package/dist/browser-B5n5EUyW.cjs +2 -0
  2. package/dist/browser-B5n5EUyW.cjs.map +1 -0
  3. package/dist/{browser-BuzIa755.js → browser-BKLM0ThC.js} +5 -2
  4. package/dist/browser-BKLM0ThC.js.map +1 -0
  5. package/dist/{direct-engine-oh_i6TH_.js → direct-engine-B7gUkBcT.js} +153 -6
  6. package/dist/direct-engine-B7gUkBcT.js.map +1 -0
  7. package/dist/direct-engine-DDe3a0AP.cjs +2 -0
  8. package/dist/direct-engine-DDe3a0AP.cjs.map +1 -0
  9. package/dist/index.cjs +1 -1
  10. package/dist/index.js +2 -2
  11. package/dist/lib/converters/index.cjs +1 -1
  12. package/dist/lib/converters/index.js +1 -1
  13. package/dist/lib/pdfium/engine.d.ts +16 -0
  14. package/dist/lib/pdfium/index.cjs +1 -1
  15. package/dist/lib/pdfium/index.js +3 -3
  16. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  17. package/dist/lib/pdfium/web/direct-engine.js +2 -2
  18. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  19. package/dist/lib/pdfium/web/worker-engine.js +6 -3
  20. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  21. package/dist/preact/index.cjs +1 -1
  22. package/dist/preact/index.js +1 -1
  23. package/dist/react/index.cjs +1 -1
  24. package/dist/react/index.js +1 -1
  25. package/dist/svelte/index.cjs +1 -1
  26. package/dist/svelte/index.js +1 -1
  27. package/dist/vue/index.cjs +1 -1
  28. package/dist/vue/index.js +1 -1
  29. package/package.json +5 -5
  30. package/dist/browser-BpXqcQ3U.cjs +0 -2
  31. package/dist/browser-BpXqcQ3U.cjs.map +0 -1
  32. package/dist/browser-BuzIa755.js.map +0 -1
  33. package/dist/direct-engine-IJ8DmFTb.cjs +0 -2
  34. package/dist/direct-engine-IJ8DmFTb.cjs.map +0 -1
  35. package/dist/direct-engine-oh_i6TH_.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"worker-engine.js","sources":["../../../../src/lib/orchestrator/remote-executor.ts","../../../../src/lib/image-encoder/worker-pool.ts"],"sourcesContent":["import {\n BatchProgress,\n Logger,\n NoopLogger,\n PdfDocumentObject,\n PdfPageObject,\n PdfTask,\n PdfErrorReason,\n PdfFile,\n PdfOpenDocumentBufferOptions,\n PdfMetadataObject,\n PdfBookmarksObject,\n PdfBookmarkObject,\n PdfRenderPageOptions,\n PdfRenderThumbnailOptions,\n PdfRenderPageAnnotationOptions,\n PdfAnnotationObject,\n PdfTextRectObject,\n PdfAttachmentObject,\n PdfAddAttachmentParams,\n PdfWidgetAnnoObject,\n PdfWidgetAnnoField,\n PdfDocumentJavaScriptActionObject,\n PdfWidgetJavaScriptActionObject,\n FormFieldValue,\n PdfFlattenPageOptions,\n PdfPageFlattenResult,\n PdfRedactTextOptions,\n Rect,\n PageTextSlice,\n PdfGlyphObject,\n PdfPageGeometry,\n PdfPageTextRuns,\n PdfPrintOptions,\n PdfSignatureObject,\n AnnotationCreateContext,\n Task,\n TaskError,\n PdfErrorCode,\n SearchResult,\n serializeLogger,\n IPdfiumExecutor,\n ImageDataLike,\n AnnotationAppearanceMap,\n} from '@embedpdf/models';\nimport type { WorkerRequest, WorkerResponse } from './pdfium-native-runner';\nimport type { FontFallbackConfig } from '../pdfium/font-fallback';\n\n/**\n * Options for creating a RemoteExecutor\n */\nexport interface RemoteExecutorOptions {\n /**\n * URL to the pdfium.wasm file (required)\n */\n wasmUrl: string;\n /**\n * Logger instance for debugging\n */\n logger?: Logger;\n /**\n * Font fallback configuration for handling missing fonts\n */\n fontFallback?: FontFallbackConfig;\n}\n\nconst LOG_SOURCE = 'RemoteExecutor';\nconst LOG_CATEGORY = 'Worker';\n\n/**\n * Message types for worker communication\n */\ntype MessageType =\n | 'destroy'\n | 'openDocumentBuffer'\n | 'getMetadata'\n | 'setMetadata'\n | 'getDocPermissions'\n | 'getDocUserPermissions'\n | 'getSignatures'\n | 'getBookmarks'\n | 'setBookmarks'\n | 'deleteBookmarks'\n | 'renderPageRaw'\n | 'renderPageRect'\n | 'renderThumbnailRaw'\n | 'renderPageAnnotationRaw'\n | 'renderPageAnnotationsRaw'\n | 'getPageAnnotations'\n | 'getPageAnnotationsRaw'\n | 'createPageAnnotation'\n | 'updatePageAnnotation'\n | 'removePageAnnotation'\n | 'getPageTextRects'\n | 'searchInPage'\n | 'getAnnotationsBatch'\n | 'searchBatch'\n | 'getAttachments'\n | 'addAttachment'\n | 'removeAttachment'\n | 'readAttachmentContent'\n | 'getDocumentJavaScriptActions'\n | 'getPageAnnoWidgets'\n | 'getPageWidgetJavaScriptActions'\n | 'setFormFieldValue'\n | 'setFormFieldState'\n | 'renameWidgetField'\n | 'shareWidgetField'\n | 'regenerateWidgetAppearances'\n | 'flattenPage'\n | 'extractPages'\n | 'createDocument'\n | 'importPages'\n | 'deletePage'\n | 'extractText'\n | 'redactTextInRects'\n | 'applyRedaction'\n | 'applyAllRedactions'\n | 'flattenAnnotation'\n | 'exportAnnotationAppearanceAsPdf'\n | 'exportAnnotationsAppearanceAsPdf'\n | 'getTextSlices'\n | 'getPageGlyphs'\n | 'getPageGeometry'\n | 'getPageTextRuns'\n | 'merge'\n | 'mergePages'\n | 'preparePrintDocument'\n | 'saveAsCopy'\n | 'closeDocument'\n | 'closeAllDocuments'\n | 'setDocumentEncryption'\n | 'removeEncryption'\n | 'unlockOwnerPermissions'\n | 'isEncrypted'\n | 'isOwnerUnlocked';\n\n/**\n * RemoteExecutor - Proxy for worker communication\n *\n * This implements IPdfExecutor but forwards all calls to a Web Worker.\n * It handles:\n * - Serialization/deserialization of messages\n * - Promise/Task conversion\n * - Error handling\n * - Progress tracking\n */\nexport class RemoteExecutor implements IPdfiumExecutor {\n private static READY_TASK_ID = '0';\n private pendingRequests = new Map<string, Task<any, any>>();\n private requestCounter = 0;\n private logger: Logger;\n private readyTask: Task<boolean, PdfErrorReason>;\n\n constructor(\n private worker: Worker,\n options: RemoteExecutorOptions,\n ) {\n this.logger = options.logger ?? new NoopLogger();\n this.worker.addEventListener('message', this.handleMessage);\n\n // Create ready task - will be resolved when worker sends 'ready'\n this.readyTask = new Task<boolean, PdfErrorReason>();\n this.pendingRequests.set(RemoteExecutor.READY_TASK_ID, this.readyTask);\n\n // Send initialization message with WASM URL and font fallback config\n this.worker.postMessage({\n id: RemoteExecutor.READY_TASK_ID,\n type: 'wasmInit',\n wasmUrl: options.wasmUrl,\n logger: options.logger ? serializeLogger(options.logger) : undefined,\n fontFallback: options.fontFallback,\n });\n\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'RemoteExecutor created');\n }\n\n /**\n * Generate unique request ID\n */\n private generateId(): string {\n return `req-${Date.now()}-${this.requestCounter++}`;\n }\n\n /**\n * Send a message to the worker and return a Task\n * Waits for worker to be ready before sending\n */\n private send<T, P = unknown>(method: MessageType, args: any[]): Task<T, PdfErrorReason, P> {\n const id = this.generateId();\n const task = new Task<T, PdfErrorReason, P>();\n\n const request: WorkerRequest = {\n id,\n type: 'execute',\n method,\n args,\n };\n\n // Wait for worker to be ready before sending\n this.readyTask.wait(\n () => {\n this.pendingRequests.set(id, task);\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Sending ${method} request:`, id);\n this.worker.postMessage(request);\n },\n (error) => {\n this.logger.error(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Worker init failed, rejecting ${method}:`,\n error,\n );\n task.reject({\n code: PdfErrorCode.Initialization,\n message: 'Worker initialization failed',\n });\n },\n );\n\n return task;\n }\n\n /**\n * Handle messages from worker\n */\n private handleMessage = (event: MessageEvent<WorkerResponse>) => {\n const response = event.data;\n\n // Handle ready response - resolve the readyTask\n if (response.type === 'ready') {\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'Worker is ready');\n this.readyTask.resolve(true);\n return;\n }\n\n const task = this.pendingRequests.get(response.id);\n\n if (!task) {\n this.logger.warn(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received response for unknown request: ${response.id}`,\n );\n return;\n }\n\n switch (response.type) {\n case 'result':\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Received result for ${response.id}`);\n task.resolve(response.data);\n this.pendingRequests.delete(response.id);\n break;\n\n case 'error':\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received error for ${response.id}:`,\n response.error,\n );\n if (response.error) {\n task.fail(response.error);\n } else {\n task.reject({ code: PdfErrorCode.Unknown, message: 'Unknown error' });\n }\n this.pendingRequests.delete(response.id);\n break;\n\n case 'progress':\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Received progress for ${response.id}`);\n task.progress(response.progress);\n break;\n }\n };\n\n /**\n * Cleanup and terminate worker\n */\n destroy(): void {\n this.worker.removeEventListener('message', this.handleMessage);\n\n // Reject all pending requests (except readyTask)\n this.pendingRequests.forEach((task, id) => {\n if (id !== RemoteExecutor.READY_TASK_ID) {\n task.abort('Worker destroyed');\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Aborted pending request: ${id}`);\n }\n });\n this.pendingRequests.clear();\n\n this.worker.terminate();\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'RemoteExecutor destroyed');\n }\n\n // ========== IPdfExecutor Implementation ==========\n\n openDocumentBuffer(\n file: PdfFile,\n options?: PdfOpenDocumentBufferOptions,\n ): PdfTask<PdfDocumentObject> {\n return this.send<PdfDocumentObject>('openDocumentBuffer', [file, options]);\n }\n\n getMetadata(doc: PdfDocumentObject): PdfTask<PdfMetadataObject> {\n return this.send<PdfMetadataObject>('getMetadata', [doc]);\n }\n\n setMetadata(doc: PdfDocumentObject, metadata: Partial<PdfMetadataObject>): PdfTask<boolean> {\n return this.send<boolean>('setMetadata', [doc, metadata]);\n }\n\n getDocPermissions(doc: PdfDocumentObject): PdfTask<number> {\n return this.send<number>('getDocPermissions', [doc]);\n }\n\n getDocUserPermissions(doc: PdfDocumentObject): PdfTask<number> {\n return this.send<number>('getDocUserPermissions', [doc]);\n }\n\n getSignatures(doc: PdfDocumentObject): PdfTask<PdfSignatureObject[]> {\n return this.send<PdfSignatureObject[]>('getSignatures', [doc]);\n }\n\n getBookmarks(doc: PdfDocumentObject): PdfTask<PdfBookmarksObject> {\n return this.send<PdfBookmarksObject>('getBookmarks', [doc]);\n }\n\n setBookmarks(doc: PdfDocumentObject, bookmarks: PdfBookmarkObject[]): PdfTask<boolean> {\n return this.send<boolean>('setBookmarks', [doc, bookmarks]);\n }\n\n deleteBookmarks(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('deleteBookmarks', [doc]);\n }\n\n renderPageRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderPageOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageRaw', [doc, page, options]);\n }\n\n renderPageRect(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n rect: Rect,\n options?: PdfRenderPageOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageRect', [doc, page, rect, options]);\n }\n\n renderThumbnailRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderThumbnailOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderThumbnailRaw', [doc, page, options]);\n }\n\n renderPageAnnotationRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n options?: PdfRenderPageAnnotationOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageAnnotationRaw', [doc, page, annotation, options]);\n }\n\n renderPageAnnotationsRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderPageAnnotationOptions,\n ): PdfTask<AnnotationAppearanceMap> {\n return this.send<AnnotationAppearanceMap>('renderPageAnnotationsRaw', [doc, page, options]);\n }\n\n getPageAnnotationsRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n ): PdfTask<PdfAnnotationObject[]> {\n return this.send<PdfAnnotationObject[]>('getPageAnnotationsRaw', [doc, page]);\n }\n\n getPageAnnotations(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfAnnotationObject[]> {\n return this.send<PdfAnnotationObject[]>('getPageAnnotations', [doc, page]);\n }\n\n createPageAnnotation<A extends PdfAnnotationObject>(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: A,\n context?: AnnotationCreateContext<A>,\n ): PdfTask<string> {\n return this.send<string>('createPageAnnotation', [doc, page, annotation, context]);\n }\n\n updatePageAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n options?: { regenerateAppearance?: boolean },\n ): PdfTask<boolean> {\n return this.send<boolean>('updatePageAnnotation', [doc, page, annotation, options]);\n }\n\n removePageAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('removePageAnnotation', [doc, page, annotation]);\n }\n\n getPageTextRects(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfTextRectObject[]> {\n return this.send<PdfTextRectObject[]>('getPageTextRects', [doc, page]);\n }\n\n searchInPage(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n keyword: string,\n flags: number,\n ): PdfTask<SearchResult[]> {\n return this.send<SearchResult[]>('searchInPage', [doc, page, keyword, flags]);\n }\n\n getAnnotationsBatch(\n doc: PdfDocumentObject,\n pages: PdfPageObject[],\n ): PdfTask<Record<number, PdfAnnotationObject[]>, BatchProgress<PdfAnnotationObject[]>> {\n return this.send<Record<number, PdfAnnotationObject[]>, BatchProgress<PdfAnnotationObject[]>>(\n 'getAnnotationsBatch',\n [doc, pages],\n );\n }\n\n searchBatch(\n doc: PdfDocumentObject,\n pages: PdfPageObject[],\n keyword: string,\n flags: number,\n ): PdfTask<Record<number, SearchResult[]>, BatchProgress<SearchResult[]>> {\n return this.send<Record<number, SearchResult[]>, BatchProgress<SearchResult[]>>('searchBatch', [\n doc,\n pages,\n keyword,\n flags,\n ]);\n }\n\n getAttachments(doc: PdfDocumentObject): PdfTask<PdfAttachmentObject[]> {\n return this.send<PdfAttachmentObject[]>('getAttachments', [doc]);\n }\n\n addAttachment(doc: PdfDocumentObject, params: PdfAddAttachmentParams): PdfTask<boolean> {\n return this.send<boolean>('addAttachment', [doc, params]);\n }\n\n removeAttachment(doc: PdfDocumentObject, attachment: PdfAttachmentObject): PdfTask<boolean> {\n return this.send<boolean>('removeAttachment', [doc, attachment]);\n }\n\n readAttachmentContent(\n doc: PdfDocumentObject,\n attachment: PdfAttachmentObject,\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('readAttachmentContent', [doc, attachment]);\n }\n\n getDocumentJavaScriptActions(\n doc: PdfDocumentObject,\n ): PdfTask<PdfDocumentJavaScriptActionObject[]> {\n return this.send<PdfDocumentJavaScriptActionObject[]>('getDocumentJavaScriptActions', [doc]);\n }\n\n getPageAnnoWidgets(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfWidgetAnnoObject[]> {\n return this.send<PdfWidgetAnnoObject[]>('getPageAnnoWidgets', [doc, page]);\n }\n\n getPageWidgetJavaScriptActions(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n ): PdfTask<PdfWidgetJavaScriptActionObject[]> {\n return this.send<PdfWidgetJavaScriptActionObject[]>('getPageWidgetJavaScriptActions', [\n doc,\n page,\n ]);\n }\n\n setFormFieldValue(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n value: FormFieldValue,\n ): PdfTask<boolean> {\n return this.send<boolean>('setFormFieldValue', [doc, page, annotation, value]);\n }\n\n setFormFieldState(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n field: PdfWidgetAnnoField,\n ): PdfTask<boolean> {\n return this.send<boolean>('setFormFieldState', [doc, page, annotation, field]);\n }\n\n renameWidgetField(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n name: string,\n ): PdfTask<boolean> {\n return this.send<boolean>('renameWidgetField', [doc, page, annotation, name]);\n }\n\n shareWidgetField(\n doc: PdfDocumentObject,\n sourcePage: PdfPageObject,\n sourceAnnotation: PdfWidgetAnnoObject,\n targetPage: PdfPageObject,\n targetAnnotation: PdfWidgetAnnoObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('shareWidgetField', [\n doc,\n sourcePage,\n sourceAnnotation,\n targetPage,\n targetAnnotation,\n ]);\n }\n\n regenerateWidgetAppearances(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotationIds: string[],\n ): PdfTask<boolean> {\n return this.send<boolean>('regenerateWidgetAppearances', [doc, page, annotationIds]);\n }\n\n flattenPage(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfFlattenPageOptions,\n ): PdfTask<PdfPageFlattenResult> {\n return this.send<PdfPageFlattenResult>('flattenPage', [doc, page, options]);\n }\n\n extractPages(doc: PdfDocumentObject, pageIndexes: number[]): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('extractPages', [doc, pageIndexes]);\n }\n\n createDocument(id: string): PdfTask<PdfDocumentObject> {\n return this.send<PdfDocumentObject>('createDocument', [id]);\n }\n\n importPages(\n destDoc: PdfDocumentObject,\n srcDoc: PdfDocumentObject,\n srcPageIndices: number[],\n insertIndex?: number,\n ): PdfTask<PdfPageObject[]> {\n return this.send<PdfPageObject[]>('importPages', [\n destDoc,\n srcDoc,\n srcPageIndices,\n insertIndex,\n ]);\n }\n\n deletePage(doc: PdfDocumentObject, pageIndex: number): PdfTask<boolean> {\n return this.send<boolean>('deletePage', [doc, pageIndex]);\n }\n\n extractText(doc: PdfDocumentObject, pageIndexes: number[]): PdfTask<string> {\n return this.send<string>('extractText', [doc, pageIndexes]);\n }\n\n redactTextInRects(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n rects: Rect[],\n options?: PdfRedactTextOptions,\n ): PdfTask<boolean> {\n return this.send<boolean>('redactTextInRects', [doc, page, rects, options]);\n }\n\n applyRedaction(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('applyRedaction', [doc, page, annotation]);\n }\n\n applyAllRedactions(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<boolean> {\n return this.send<boolean>('applyAllRedactions', [doc, page]);\n }\n\n flattenAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('flattenAnnotation', [doc, page, annotation]);\n }\n\n exportAnnotationAppearanceAsPdf(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('exportAnnotationAppearanceAsPdf', [doc, page, annotation]);\n }\n\n exportAnnotationsAppearanceAsPdf(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotations: PdfAnnotationObject[],\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('exportAnnotationsAppearanceAsPdf', [doc, page, annotations]);\n }\n\n getTextSlices(doc: PdfDocumentObject, slices: PageTextSlice[]): PdfTask<string[]> {\n return this.send<string[]>('getTextSlices', [doc, slices]);\n }\n\n getPageGlyphs(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfGlyphObject[]> {\n return this.send<PdfGlyphObject[]>('getPageGlyphs', [doc, page]);\n }\n\n getPageGeometry(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfPageGeometry> {\n return this.send<PdfPageGeometry>('getPageGeometry', [doc, page]);\n }\n\n getPageTextRuns(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfPageTextRuns> {\n return this.send<PdfPageTextRuns>('getPageTextRuns', [doc, page]);\n }\n\n merge(files: PdfFile[]): PdfTask<PdfFile> {\n return this.send<PdfFile>('merge', [files]);\n }\n\n mergePages(mergeConfigs: Array<{ docId: string; pageIndices: number[] }>): PdfTask<PdfFile> {\n return this.send<PdfFile>('mergePages', [mergeConfigs]);\n }\n\n preparePrintDocument(doc: PdfDocumentObject, options?: PdfPrintOptions): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('preparePrintDocument', [doc, options]);\n }\n\n saveAsCopy(doc: PdfDocumentObject): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('saveAsCopy', [doc]);\n }\n\n closeDocument(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('closeDocument', [doc]);\n }\n\n closeAllDocuments(): PdfTask<boolean> {\n return this.send<boolean>('closeAllDocuments', []);\n }\n\n setDocumentEncryption(\n doc: PdfDocumentObject,\n userPassword: string,\n ownerPassword: string,\n allowedFlags: number,\n ): PdfTask<boolean> {\n return this.send<boolean>('setDocumentEncryption', [\n doc,\n userPassword,\n ownerPassword,\n allowedFlags,\n ]);\n }\n\n removeEncryption(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('removeEncryption', [doc]);\n }\n\n unlockOwnerPermissions(doc: PdfDocumentObject, ownerPassword: string): PdfTask<boolean> {\n return this.send<boolean>('unlockOwnerPermissions', [doc, ownerPassword]);\n }\n\n isEncrypted(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('isEncrypted', [doc]);\n }\n\n isOwnerUnlocked(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('isOwnerUnlocked', [doc]);\n }\n}\n","import { Logger, NoopLogger } from '@embedpdf/models';\nimport type { EncodeImageRequest, EncodeImageResponse } from './image-encoder-worker';\n\nconst LOG_SOURCE = 'ImageEncoderPool';\nconst LOG_CATEGORY = 'Encoder';\n\ninterface EncodingTask {\n resolve: (blob: Blob) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Pool of image encoding workers to offload OffscreenCanvas operations\n * from the main PDFium worker thread\n */\nexport class ImageEncoderWorkerPool {\n private workers: Worker[] = [];\n private pendingTasks = new Map<string, EncodingTask>();\n private nextWorkerId = 0;\n private requestCounter = 0;\n private logger: Logger;\n\n /**\n * Create a pool of image encoding workers\n * @param poolSize - Number of workers to create (default: 2)\n * @param workerUrl - URL to the worker script\n * @param logger - Logger instance\n */\n constructor(\n private poolSize: number = 2,\n private workerUrl: string,\n logger?: Logger,\n ) {\n this.logger = logger ?? new NoopLogger();\n this.initialize();\n }\n\n /**\n * Initialize the worker pool\n */\n private initialize() {\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Creating worker pool with ${this.poolSize} workers`,\n );\n\n for (let i = 0; i < this.poolSize; i++) {\n try {\n const worker = new Worker(this.workerUrl, { type: 'module' });\n worker.onmessage = this.handleWorkerMessage.bind(this);\n worker.onerror = this.handleWorkerError.bind(this);\n this.workers.push(worker);\n\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Worker ${i} created successfully`);\n } catch (error) {\n this.logger.error(LOG_SOURCE, LOG_CATEGORY, `Failed to create worker ${i}:`, error);\n }\n }\n }\n\n /**\n * Handle messages from workers\n */\n private handleWorkerMessage(event: MessageEvent<EncodeImageResponse>) {\n const response = event.data;\n const task = this.pendingTasks.get(response.id);\n\n if (!task) {\n this.logger.warn(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received response for unknown task: ${response.id}`,\n );\n return;\n }\n\n this.pendingTasks.delete(response.id);\n\n if (response.type === 'result') {\n task.resolve(response.data as Blob);\n } else {\n const errorData = response.data as { message: string };\n task.reject(new Error(errorData.message));\n }\n }\n\n /**\n * Handle worker errors\n */\n private handleWorkerError(error: ErrorEvent) {\n this.logger.error(LOG_SOURCE, LOG_CATEGORY, 'Worker error:', error.message);\n }\n\n /**\n * Get the next available worker using round-robin\n */\n private getNextWorker(): Worker | null {\n if (this.workers.length === 0) {\n return null;\n }\n\n const worker = this.workers[this.nextWorkerId];\n this.nextWorkerId = (this.nextWorkerId + 1) % this.workers.length;\n return worker;\n }\n\n /**\n * Encode ImageData to Blob using a worker from the pool\n * @param imageData - Raw image data\n * @param imageType - Target image format\n * @param quality - Image quality (0-1) for lossy formats\n * @returns Promise that resolves to encoded Blob\n */\n encode(\n imageData: { data: Uint8ClampedArray; width: number; height: number },\n imageType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/bmp' = 'image/png',\n quality?: number,\n ): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const worker = this.getNextWorker();\n\n if (!worker) {\n reject(new Error('No workers available in the pool'));\n return;\n }\n\n const requestId = `encode-${Date.now()}-${this.requestCounter++}`;\n this.pendingTasks.set(requestId, { resolve, reject });\n\n const request: EncodeImageRequest = {\n id: requestId,\n type: 'encode',\n data: {\n imageData: {\n data: imageData.data,\n width: imageData.width,\n height: imageData.height,\n },\n imageType,\n quality,\n },\n };\n\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Sending encoding request ${requestId} (${imageData.width}x${imageData.height})`,\n );\n\n // Transfer the buffer for better performance\n worker.postMessage(request, [imageData.data.buffer]);\n });\n }\n\n /**\n * Destroy all workers in the pool\n */\n destroy() {\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'Destroying worker pool');\n\n // Reject all pending tasks\n this.pendingTasks.forEach((task, id) => {\n task.reject(new Error('Worker pool destroyed'));\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Rejected pending task: ${id}`);\n });\n this.pendingTasks.clear();\n\n // Terminate all workers\n this.workers.forEach((worker, index) => {\n worker.terminate();\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Worker ${index} terminated`);\n });\n this.workers = [];\n }\n\n /**\n * Get the number of active workers in the pool\n */\n get activeWorkers(): number {\n return this.workers.length;\n }\n\n /**\n * Get the number of pending encoding tasks\n */\n get pendingTasksCount(): number {\n return this.pendingTasks.size;\n }\n}\n"],"names":["LOG_SOURCE","LOG_CATEGORY"],"mappings":"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"}
1
+ {"version":3,"file":"worker-engine.js","sources":["../../../../src/lib/orchestrator/remote-executor.ts","../../../../src/lib/image-encoder/worker-pool.ts"],"sourcesContent":["import {\n BatchProgress,\n Logger,\n NoopLogger,\n PdfDocumentObject,\n PdfPageObject,\n PdfTask,\n PdfErrorReason,\n PdfFile,\n PdfOpenDocumentBufferOptions,\n PdfMetadataObject,\n PdfBookmarksObject,\n PdfBookmarkObject,\n PdfRenderPageOptions,\n PdfRenderThumbnailOptions,\n PdfRenderPageAnnotationOptions,\n PdfAnnotationObject,\n PdfTextRectObject,\n PdfAttachmentObject,\n PdfAddAttachmentParams,\n PdfWidgetAnnoObject,\n PdfWidgetAnnoField,\n PdfDocumentJavaScriptActionObject,\n PdfWidgetJavaScriptActionObject,\n FormFieldValue,\n PdfFlattenPageOptions,\n PdfPageFlattenResult,\n PdfRedactTextOptions,\n Rect,\n PageTextSlice,\n PdfGlyphObject,\n PdfPageGeometry,\n PdfPageTextRuns,\n PdfPrintOptions,\n PdfSignatureObject,\n AnnotationCreateContext,\n Task,\n TaskError,\n PdfErrorCode,\n SearchResult,\n serializeLogger,\n IPdfiumExecutor,\n ImageDataLike,\n AnnotationAppearanceMap,\n} from '@embedpdf/models';\nimport type { WorkerRequest, WorkerResponse } from './pdfium-native-runner';\nimport type { FontFallbackConfig } from '../pdfium/font-fallback';\n\n/**\n * Options for creating a RemoteExecutor\n */\nexport interface RemoteExecutorOptions {\n /**\n * URL to the pdfium.wasm file (required)\n */\n wasmUrl: string;\n /**\n * Logger instance for debugging\n */\n logger?: Logger;\n /**\n * Font fallback configuration for handling missing fonts\n */\n fontFallback?: FontFallbackConfig;\n}\n\nconst LOG_SOURCE = 'RemoteExecutor';\nconst LOG_CATEGORY = 'Worker';\n\n/**\n * Message types for worker communication\n */\ntype MessageType =\n | 'destroy'\n | 'openDocumentBuffer'\n | 'getMetadata'\n | 'setMetadata'\n | 'getDocPermissions'\n | 'getDocUserPermissions'\n | 'getSignatures'\n | 'getBookmarks'\n | 'setBookmarks'\n | 'deleteBookmarks'\n | 'renderPageRaw'\n | 'renderPageRect'\n | 'renderThumbnailRaw'\n | 'renderPageAnnotationRaw'\n | 'renderPageAnnotationsRaw'\n | 'getPageAnnotations'\n | 'getPageAnnotationsRaw'\n | 'createPageAnnotation'\n | 'updatePageAnnotation'\n | 'removePageAnnotation'\n | 'getPageTextRects'\n | 'searchInPage'\n | 'getAnnotationsBatch'\n | 'searchBatch'\n | 'getAttachments'\n | 'addAttachment'\n | 'removeAttachment'\n | 'readAttachmentContent'\n | 'getDocumentJavaScriptActions'\n | 'getPageAnnoWidgets'\n | 'getPageWidgetJavaScriptActions'\n | 'setFormFieldValue'\n | 'setFormFieldState'\n | 'renameWidgetField'\n | 'shareWidgetField'\n | 'regenerateWidgetAppearances'\n | 'flattenPage'\n | 'extractPages'\n | 'createDocument'\n | 'importPages'\n | 'deletePage'\n | 'extractText'\n | 'redactTextInRects'\n | 'applyRedaction'\n | 'applyAllRedactions'\n | 'flattenAnnotation'\n | 'exportAnnotationAppearanceAsPdf'\n | 'exportAnnotationsAppearanceAsPdf'\n | 'getTextSlices'\n | 'getPageGlyphs'\n | 'getPageGeometry'\n | 'getPageTextRuns'\n | 'merge'\n | 'mergePages'\n | 'preparePrintDocument'\n | 'saveAsCopy'\n | 'closeDocument'\n | 'closeAllDocuments'\n | 'setDocumentEncryption'\n | 'removeEncryption'\n | 'unlockOwnerPermissions'\n | 'isEncrypted'\n | 'isOwnerUnlocked';\n\n/**\n * RemoteExecutor - Proxy for worker communication\n *\n * This implements IPdfExecutor but forwards all calls to a Web Worker.\n * It handles:\n * - Serialization/deserialization of messages\n * - Promise/Task conversion\n * - Error handling\n * - Progress tracking\n */\nexport class RemoteExecutor implements IPdfiumExecutor {\n private static READY_TASK_ID = '0';\n private pendingRequests = new Map<string, Task<any, any>>();\n private requestCounter = 0;\n private logger: Logger;\n private readyTask: Task<boolean, PdfErrorReason>;\n\n constructor(\n private worker: Worker,\n options: RemoteExecutorOptions,\n ) {\n this.logger = options.logger ?? new NoopLogger();\n this.worker.addEventListener('message', this.handleMessage);\n\n // Create ready task - will be resolved when worker sends 'ready'\n this.readyTask = new Task<boolean, PdfErrorReason>();\n this.pendingRequests.set(RemoteExecutor.READY_TASK_ID, this.readyTask);\n\n // Send initialization message with WASM URL and font fallback config\n this.worker.postMessage({\n id: RemoteExecutor.READY_TASK_ID,\n type: 'wasmInit',\n wasmUrl: options.wasmUrl,\n logger: options.logger ? serializeLogger(options.logger) : undefined,\n fontFallback: options.fontFallback,\n });\n\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'RemoteExecutor created');\n }\n\n /**\n * Generate unique request ID\n */\n private generateId(): string {\n return `req-${Date.now()}-${this.requestCounter++}`;\n }\n\n /**\n * Send a message to the worker and return a Task\n * Waits for worker to be ready before sending\n */\n private send<T, P = unknown>(method: MessageType, args: any[]): Task<T, PdfErrorReason, P> {\n const id = this.generateId();\n const task = new Task<T, PdfErrorReason, P>();\n\n const request: WorkerRequest = {\n id,\n type: 'execute',\n method,\n args,\n };\n\n // Wait for worker to be ready before sending\n this.readyTask.wait(\n () => {\n this.pendingRequests.set(id, task);\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Sending ${method} request:`, id);\n this.worker.postMessage(request);\n },\n (error) => {\n this.logger.error(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Worker init failed, rejecting ${method}:`,\n error,\n );\n task.reject({\n code: PdfErrorCode.Initialization,\n message: 'Worker initialization failed',\n });\n },\n );\n\n return task;\n }\n\n /**\n * Handle messages from worker\n */\n private handleMessage = (event: MessageEvent<WorkerResponse>) => {\n const response = event.data;\n\n // Handle ready response - resolve the readyTask\n if (response.type === 'ready') {\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'Worker is ready');\n this.readyTask.resolve(true);\n return;\n }\n\n const task = this.pendingRequests.get(response.id);\n\n if (!task) {\n this.logger.warn(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received response for unknown request: ${response.id}`,\n );\n return;\n }\n\n switch (response.type) {\n case 'result':\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Received result for ${response.id}`);\n task.resolve(response.data);\n this.pendingRequests.delete(response.id);\n break;\n\n case 'error':\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received error for ${response.id}:`,\n response.error,\n );\n if (response.error) {\n task.fail(response.error);\n } else {\n task.reject({ code: PdfErrorCode.Unknown, message: 'Unknown error' });\n }\n this.pendingRequests.delete(response.id);\n break;\n\n case 'progress':\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Received progress for ${response.id}`);\n task.progress(response.progress);\n break;\n }\n };\n\n /**\n * Cleanup and terminate worker\n */\n destroy(): void {\n this.worker.removeEventListener('message', this.handleMessage);\n\n // Reject all pending requests (except readyTask)\n this.pendingRequests.forEach((task, id) => {\n if (id !== RemoteExecutor.READY_TASK_ID) {\n task.abort('Worker destroyed');\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Aborted pending request: ${id}`);\n }\n });\n this.pendingRequests.clear();\n\n this.worker.terminate();\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'RemoteExecutor destroyed');\n }\n\n // ========== IPdfExecutor Implementation ==========\n\n openDocumentBuffer(\n file: PdfFile,\n options?: PdfOpenDocumentBufferOptions,\n ): PdfTask<PdfDocumentObject> {\n return this.send<PdfDocumentObject>('openDocumentBuffer', [file, options]);\n }\n\n getMetadata(doc: PdfDocumentObject): PdfTask<PdfMetadataObject> {\n return this.send<PdfMetadataObject>('getMetadata', [doc]);\n }\n\n setMetadata(doc: PdfDocumentObject, metadata: Partial<PdfMetadataObject>): PdfTask<boolean> {\n return this.send<boolean>('setMetadata', [doc, metadata]);\n }\n\n getDocPermissions(doc: PdfDocumentObject): PdfTask<number> {\n return this.send<number>('getDocPermissions', [doc]);\n }\n\n getDocUserPermissions(doc: PdfDocumentObject): PdfTask<number> {\n return this.send<number>('getDocUserPermissions', [doc]);\n }\n\n getSignatures(doc: PdfDocumentObject): PdfTask<PdfSignatureObject[]> {\n return this.send<PdfSignatureObject[]>('getSignatures', [doc]);\n }\n\n getBookmarks(doc: PdfDocumentObject): PdfTask<PdfBookmarksObject> {\n return this.send<PdfBookmarksObject>('getBookmarks', [doc]);\n }\n\n setBookmarks(doc: PdfDocumentObject, bookmarks: PdfBookmarkObject[]): PdfTask<boolean> {\n return this.send<boolean>('setBookmarks', [doc, bookmarks]);\n }\n\n deleteBookmarks(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('deleteBookmarks', [doc]);\n }\n\n renderPageRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderPageOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageRaw', [doc, page, options]);\n }\n\n renderPageRect(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n rect: Rect,\n options?: PdfRenderPageOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageRect', [doc, page, rect, options]);\n }\n\n renderThumbnailRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderThumbnailOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderThumbnailRaw', [doc, page, options]);\n }\n\n renderPageAnnotationRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n options?: PdfRenderPageAnnotationOptions,\n ): PdfTask<ImageDataLike> {\n return this.send<ImageDataLike>('renderPageAnnotationRaw', [doc, page, annotation, options]);\n }\n\n renderPageAnnotationsRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfRenderPageAnnotationOptions,\n ): PdfTask<AnnotationAppearanceMap> {\n return this.send<AnnotationAppearanceMap>('renderPageAnnotationsRaw', [doc, page, options]);\n }\n\n getPageAnnotationsRaw(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n ): PdfTask<PdfAnnotationObject[]> {\n return this.send<PdfAnnotationObject[]>('getPageAnnotationsRaw', [doc, page]);\n }\n\n getPageAnnotations(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfAnnotationObject[]> {\n return this.send<PdfAnnotationObject[]>('getPageAnnotations', [doc, page]);\n }\n\n createPageAnnotation<A extends PdfAnnotationObject>(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: A,\n context?: AnnotationCreateContext<A>,\n ): PdfTask<string> {\n return this.send<string>('createPageAnnotation', [doc, page, annotation, context]);\n }\n\n updatePageAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n options?: { regenerateAppearance?: boolean },\n ): PdfTask<boolean> {\n return this.send<boolean>('updatePageAnnotation', [doc, page, annotation, options]);\n }\n\n removePageAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('removePageAnnotation', [doc, page, annotation]);\n }\n\n getPageTextRects(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfTextRectObject[]> {\n return this.send<PdfTextRectObject[]>('getPageTextRects', [doc, page]);\n }\n\n searchInPage(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n keyword: string,\n flags: number,\n ): PdfTask<SearchResult[]> {\n return this.send<SearchResult[]>('searchInPage', [doc, page, keyword, flags]);\n }\n\n getAnnotationsBatch(\n doc: PdfDocumentObject,\n pages: PdfPageObject[],\n ): PdfTask<Record<number, PdfAnnotationObject[]>, BatchProgress<PdfAnnotationObject[]>> {\n return this.send<Record<number, PdfAnnotationObject[]>, BatchProgress<PdfAnnotationObject[]>>(\n 'getAnnotationsBatch',\n [doc, pages],\n );\n }\n\n searchBatch(\n doc: PdfDocumentObject,\n pages: PdfPageObject[],\n keyword: string,\n flags: number,\n ): PdfTask<Record<number, SearchResult[]>, BatchProgress<SearchResult[]>> {\n return this.send<Record<number, SearchResult[]>, BatchProgress<SearchResult[]>>('searchBatch', [\n doc,\n pages,\n keyword,\n flags,\n ]);\n }\n\n getAttachments(doc: PdfDocumentObject): PdfTask<PdfAttachmentObject[]> {\n return this.send<PdfAttachmentObject[]>('getAttachments', [doc]);\n }\n\n addAttachment(doc: PdfDocumentObject, params: PdfAddAttachmentParams): PdfTask<boolean> {\n return this.send<boolean>('addAttachment', [doc, params]);\n }\n\n removeAttachment(doc: PdfDocumentObject, attachment: PdfAttachmentObject): PdfTask<boolean> {\n return this.send<boolean>('removeAttachment', [doc, attachment]);\n }\n\n readAttachmentContent(\n doc: PdfDocumentObject,\n attachment: PdfAttachmentObject,\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('readAttachmentContent', [doc, attachment]);\n }\n\n getDocumentJavaScriptActions(\n doc: PdfDocumentObject,\n ): PdfTask<PdfDocumentJavaScriptActionObject[]> {\n return this.send<PdfDocumentJavaScriptActionObject[]>('getDocumentJavaScriptActions', [doc]);\n }\n\n getPageAnnoWidgets(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfWidgetAnnoObject[]> {\n return this.send<PdfWidgetAnnoObject[]>('getPageAnnoWidgets', [doc, page]);\n }\n\n getPageWidgetJavaScriptActions(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n ): PdfTask<PdfWidgetJavaScriptActionObject[]> {\n return this.send<PdfWidgetJavaScriptActionObject[]>('getPageWidgetJavaScriptActions', [\n doc,\n page,\n ]);\n }\n\n setFormFieldValue(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n value: FormFieldValue,\n ): PdfTask<boolean> {\n return this.send<boolean>('setFormFieldValue', [doc, page, annotation, value]);\n }\n\n setFormFieldState(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n field: PdfWidgetAnnoField,\n ): PdfTask<boolean> {\n return this.send<boolean>('setFormFieldState', [doc, page, annotation, field]);\n }\n\n renameWidgetField(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfWidgetAnnoObject,\n name: string,\n ): PdfTask<boolean> {\n return this.send<boolean>('renameWidgetField', [doc, page, annotation, name]);\n }\n\n shareWidgetField(\n doc: PdfDocumentObject,\n sourcePage: PdfPageObject,\n sourceAnnotation: PdfWidgetAnnoObject,\n targetPage: PdfPageObject,\n targetAnnotation: PdfWidgetAnnoObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('shareWidgetField', [\n doc,\n sourcePage,\n sourceAnnotation,\n targetPage,\n targetAnnotation,\n ]);\n }\n\n regenerateWidgetAppearances(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotationIds: string[],\n ): PdfTask<boolean> {\n return this.send<boolean>('regenerateWidgetAppearances', [doc, page, annotationIds]);\n }\n\n flattenPage(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n options?: PdfFlattenPageOptions,\n ): PdfTask<PdfPageFlattenResult> {\n return this.send<PdfPageFlattenResult>('flattenPage', [doc, page, options]);\n }\n\n extractPages(doc: PdfDocumentObject, pageIndexes: number[]): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('extractPages', [doc, pageIndexes]);\n }\n\n createDocument(id: string): PdfTask<PdfDocumentObject> {\n return this.send<PdfDocumentObject>('createDocument', [id]);\n }\n\n importPages(\n destDoc: PdfDocumentObject,\n srcDoc: PdfDocumentObject,\n srcPageIndices: number[],\n insertIndex?: number,\n ): PdfTask<PdfPageObject[]> {\n return this.send<PdfPageObject[]>('importPages', [\n destDoc,\n srcDoc,\n srcPageIndices,\n insertIndex,\n ]);\n }\n\n deletePage(doc: PdfDocumentObject, pageIndex: number): PdfTask<boolean> {\n return this.send<boolean>('deletePage', [doc, pageIndex]);\n }\n\n extractText(doc: PdfDocumentObject, pageIndexes: number[]): PdfTask<string> {\n return this.send<string>('extractText', [doc, pageIndexes]);\n }\n\n redactTextInRects(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n rects: Rect[],\n options?: PdfRedactTextOptions,\n ): PdfTask<boolean> {\n return this.send<boolean>('redactTextInRects', [doc, page, rects, options]);\n }\n\n applyRedaction(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('applyRedaction', [doc, page, annotation]);\n }\n\n applyAllRedactions(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<boolean> {\n return this.send<boolean>('applyAllRedactions', [doc, page]);\n }\n\n flattenAnnotation(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<boolean> {\n return this.send<boolean>('flattenAnnotation', [doc, page, annotation]);\n }\n\n exportAnnotationAppearanceAsPdf(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotation: PdfAnnotationObject,\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('exportAnnotationAppearanceAsPdf', [doc, page, annotation]);\n }\n\n exportAnnotationsAppearanceAsPdf(\n doc: PdfDocumentObject,\n page: PdfPageObject,\n annotations: PdfAnnotationObject[],\n ): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('exportAnnotationsAppearanceAsPdf', [doc, page, annotations]);\n }\n\n getTextSlices(doc: PdfDocumentObject, slices: PageTextSlice[]): PdfTask<string[]> {\n return this.send<string[]>('getTextSlices', [doc, slices]);\n }\n\n getPageGlyphs(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfGlyphObject[]> {\n return this.send<PdfGlyphObject[]>('getPageGlyphs', [doc, page]);\n }\n\n getPageGeometry(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfPageGeometry> {\n return this.send<PdfPageGeometry>('getPageGeometry', [doc, page]);\n }\n\n getPageTextRuns(doc: PdfDocumentObject, page: PdfPageObject): PdfTask<PdfPageTextRuns> {\n return this.send<PdfPageTextRuns>('getPageTextRuns', [doc, page]);\n }\n\n merge(files: PdfFile[]): PdfTask<PdfFile> {\n return this.send<PdfFile>('merge', [files]);\n }\n\n mergePages(mergeConfigs: Array<{ docId: string; pageIndices: number[] }>): PdfTask<PdfFile> {\n return this.send<PdfFile>('mergePages', [mergeConfigs]);\n }\n\n preparePrintDocument(doc: PdfDocumentObject, options?: PdfPrintOptions): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('preparePrintDocument', [doc, options]);\n }\n\n saveAsCopy(doc: PdfDocumentObject): PdfTask<ArrayBuffer> {\n return this.send<ArrayBuffer>('saveAsCopy', [doc]);\n }\n\n closeDocument(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('closeDocument', [doc]);\n }\n\n closeAllDocuments(): PdfTask<boolean> {\n return this.send<boolean>('closeAllDocuments', []);\n }\n\n setDocumentEncryption(\n doc: PdfDocumentObject,\n userPassword: string,\n ownerPassword: string,\n allowedFlags: number,\n ): PdfTask<boolean> {\n return this.send<boolean>('setDocumentEncryption', [\n doc,\n userPassword,\n ownerPassword,\n allowedFlags,\n ]);\n }\n\n removeEncryption(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('removeEncryption', [doc]);\n }\n\n unlockOwnerPermissions(doc: PdfDocumentObject, ownerPassword: string): PdfTask<boolean> {\n return this.send<boolean>('unlockOwnerPermissions', [doc, ownerPassword]);\n }\n\n isEncrypted(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('isEncrypted', [doc]);\n }\n\n isOwnerUnlocked(doc: PdfDocumentObject): PdfTask<boolean> {\n return this.send<boolean>('isOwnerUnlocked', [doc]);\n }\n}\n","import { Logger, NoopLogger } from '@embedpdf/models';\nimport type { EncodeImageRequest, EncodeImageResponse } from './image-encoder-worker';\n\nconst LOG_SOURCE = 'ImageEncoderPool';\nconst LOG_CATEGORY = 'Encoder';\n\ninterface EncodingTask {\n resolve: (blob: Blob) => void;\n reject: (error: Error) => void;\n}\n\n/**\n * Pool of image encoding workers to offload OffscreenCanvas operations\n * from the main PDFium worker thread\n */\nexport class ImageEncoderWorkerPool {\n private workers: Worker[] = [];\n private pendingTasks = new Map<string, EncodingTask>();\n private nextWorkerId = 0;\n private requestCounter = 0;\n private logger: Logger;\n\n /**\n * Create a pool of image encoding workers\n * @param poolSize - Number of workers to create (default: 2)\n * @param workerUrl - URL to the worker script\n * @param logger - Logger instance\n */\n constructor(\n private poolSize: number = 2,\n private workerUrl: string,\n logger?: Logger,\n ) {\n this.logger = logger ?? new NoopLogger();\n this.initialize();\n }\n\n /**\n * Initialize the worker pool\n */\n private initialize() {\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Creating worker pool with ${this.poolSize} workers`,\n );\n\n for (let i = 0; i < this.poolSize; i++) {\n try {\n const worker = new Worker(this.workerUrl, { type: 'module' });\n worker.onmessage = this.handleWorkerMessage.bind(this);\n worker.onerror = this.handleWorkerError.bind(this);\n this.workers.push(worker);\n\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Worker ${i} created successfully`);\n } catch (error) {\n this.logger.error(LOG_SOURCE, LOG_CATEGORY, `Failed to create worker ${i}:`, error);\n }\n }\n }\n\n /**\n * Handle messages from workers\n */\n private handleWorkerMessage(event: MessageEvent<EncodeImageResponse>) {\n const response = event.data;\n const task = this.pendingTasks.get(response.id);\n\n if (!task) {\n this.logger.warn(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Received response for unknown task: ${response.id}`,\n );\n return;\n }\n\n this.pendingTasks.delete(response.id);\n\n if (response.type === 'result') {\n task.resolve(response.data as Blob);\n } else {\n const errorData = response.data as { message: string };\n task.reject(new Error(errorData.message));\n }\n }\n\n /**\n * Handle worker errors\n */\n private handleWorkerError(error: ErrorEvent) {\n this.logger.error(LOG_SOURCE, LOG_CATEGORY, 'Worker error:', error.message);\n }\n\n /**\n * Get the next available worker using round-robin\n */\n private getNextWorker(): Worker | null {\n if (this.workers.length === 0) {\n return null;\n }\n\n const worker = this.workers[this.nextWorkerId];\n this.nextWorkerId = (this.nextWorkerId + 1) % this.workers.length;\n return worker;\n }\n\n /**\n * Encode ImageData to Blob using a worker from the pool\n * @param imageData - Raw image data\n * @param imageType - Target image format\n * @param quality - Image quality (0-1) for lossy formats\n * @returns Promise that resolves to encoded Blob\n */\n encode(\n imageData: { data: Uint8ClampedArray; width: number; height: number },\n imageType: 'image/png' | 'image/jpeg' | 'image/webp' | 'image/bmp' = 'image/png',\n quality?: number,\n ): Promise<Blob> {\n return new Promise((resolve, reject) => {\n const worker = this.getNextWorker();\n\n if (!worker) {\n reject(new Error('No workers available in the pool'));\n return;\n }\n\n const requestId = `encode-${Date.now()}-${this.requestCounter++}`;\n this.pendingTasks.set(requestId, { resolve, reject });\n\n const request: EncodeImageRequest = {\n id: requestId,\n type: 'encode',\n data: {\n imageData: {\n data: imageData.data,\n width: imageData.width,\n height: imageData.height,\n },\n imageType,\n quality,\n },\n };\n\n this.logger.debug(\n LOG_SOURCE,\n LOG_CATEGORY,\n `Sending encoding request ${requestId} (${imageData.width}x${imageData.height})`,\n );\n\n // Transfer the buffer for better performance\n worker.postMessage(request, [imageData.data.buffer]);\n });\n }\n\n /**\n * Destroy all workers in the pool\n */\n destroy() {\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'Destroying worker pool');\n\n // Reject all pending tasks\n this.pendingTasks.forEach((task, id) => {\n task.reject(new Error('Worker pool destroyed'));\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Rejected pending task: ${id}`);\n });\n this.pendingTasks.clear();\n\n // Terminate all workers\n this.workers.forEach((worker, index) => {\n worker.terminate();\n this.logger.debug(LOG_SOURCE, LOG_CATEGORY, `Worker ${index} terminated`);\n });\n this.workers = [];\n }\n\n /**\n * Get the number of active workers in the pool\n */\n get activeWorkers(): number {\n return this.workers.length;\n }\n\n /**\n * Get the number of pending encoding tasks\n */\n get pendingTasksCount(): number {\n return this.pendingTasks.size;\n }\n}\n"],"names":["LOG_SOURCE","LOG_CATEGORY"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact/hooks"),r=require("preact"),t=require("@embedpdf/models"),n=require("preact/jsx-runtime"),o="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";const i=r.createContext(void 0);function u(){const r=e.useContext(i);if(void 0===r)throw new Error("useEngineContext must be used within a PdfEngineProvider");return r}exports.PdfEngineProvider=function({children:e,engine:r,isLoading:t,error:o}){const u={engine:r,isLoading:t,error:o};return n.jsx(i.Provider,{value:u,children:e})},exports.useEngine=function(){const{engine:e,error:r}=u();if(r)throw r;return e},exports.useEngineContext=u,exports.usePdfiumEngine=function(r){const{wasmUrl:n=o,worker:i=!0,logger:u,encoderPoolSize:s,fontFallback:c}=r??{},[l,d]=e.useState(null),[a,p]=e.useState(!0),[g,f]=e.useState(null),m=e.useRef(null);return e.useEffect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),r=await e(n,{logger:u,encoderPoolSize:s,fontFallback:c});m.current=r,d(r),p(!1)}catch(r){e||(f(r),p(!1))}})(),()=>{var r,n;e=!0,null==(n=null==(r=m.current)?void 0:r.closeAllDocuments)||n.call(r).wait(()=>{var e,r;null==(r=null==(e=m.current)?void 0:e.destroy)||r.call(e),m.current=null},t.ignore)}},[n,i,u,c]),{engine:l,isLoading:a,error:g}};
1
+ "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact/hooks"),r=require("preact"),t=require("@embedpdf/models"),n=require("preact/jsx-runtime"),o="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";const i=r.createContext(void 0);function u(){const r=e.useContext(i);if(void 0===r)throw new Error("useEngineContext must be used within a PdfEngineProvider");return r}exports.PdfEngineProvider=function({children:e,engine:r,isLoading:t,error:o}){const u={engine:r,isLoading:t,error:o};return n.jsx(i.Provider,{value:u,children:e})},exports.useEngine=function(){const{engine:e,error:r}=u();if(r)throw r;return e},exports.useEngineContext=u,exports.usePdfiumEngine=function(r){const{wasmUrl:n=o,worker:i=!0,logger:u,encoderPoolSize:s,fontFallback:c}=r??{},[l,d]=e.useState(null),[a,p]=e.useState(!0),[g,f]=e.useState(null),m=e.useRef(null);return e.useEffect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),r=await e(n,{logger:u,encoderPoolSize:s,fontFallback:c});m.current=r,d(r),p(!1)}catch(r){e||(f(r),p(!1))}})(),()=>{var r,n;e=!0,null==(n=null==(r=m.current)?void 0:r.closeAllDocuments)||n.call(r).wait(()=>{var e,r;null==(r=null==(e=m.current)?void 0:e.destroy)||r.call(e),m.current=null},t.ignore)}},[n,i,u,c]),{engine:l,isLoading:a,error:g}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -2,7 +2,7 @@ import { useState, useRef, useEffect, useContext } from "preact/hooks";
2
2
  import { createContext } from "preact";
3
3
  import { ignore } from "@embedpdf/models";
4
4
  import { jsx } from "preact/jsx-runtime";
5
- const defaultWasmUrl = `https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm`;
5
+ const defaultWasmUrl = `https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm`;
6
6
  function usePdfiumEngine(config) {
7
7
  const {
8
8
  wasmUrl = defaultWasmUrl,
@@ -1,2 +1,2 @@
1
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),r=require("@embedpdf/models"),t=require("react/jsx-runtime"),n="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";const o=e.createContext(void 0);function i(){const r=e.useContext(o);if(void 0===r)throw new Error("useEngineContext must be used within a PdfEngineProvider");return r}exports.PdfEngineProvider=function({children:e,engine:r,isLoading:n,error:i}){const u={engine:r,isLoading:n,error:i};return t.jsx(o.Provider,{value:u,children:e})},exports.useEngine=function(){const{engine:e,error:r}=i();if(r)throw r;return e},exports.useEngineContext=i,exports.usePdfiumEngine=function(t){const{wasmUrl:o=n,worker:i=!0,logger:u,encoderPoolSize:s,fontFallback:c}=t??{},[l,d]=e.useState(null),[a,g]=e.useState(!0),[f,p]=e.useState(null),m=e.useRef(null);return e.useEffect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),r=await e(o,{logger:u,encoderPoolSize:s,fontFallback:c});m.current=r,d(r),g(!1)}catch(r){e||(p(r),g(!1))}})(),()=>{var t,n;e=!0,null==(n=null==(t=m.current)?void 0:t.closeAllDocuments)||n.call(t).wait(()=>{var e,r;null==(r=null==(e=m.current)?void 0:e.destroy)||r.call(e),m.current=null},r.ignore)}},[o,i,u,c]),{engine:l,isLoading:a,error:f}};
1
+ "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),r=require("@embedpdf/models"),t=require("react/jsx-runtime"),n="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";const o=e.createContext(void 0);function i(){const r=e.useContext(o);if(void 0===r)throw new Error("useEngineContext must be used within a PdfEngineProvider");return r}exports.PdfEngineProvider=function({children:e,engine:r,isLoading:n,error:i}){const u={engine:r,isLoading:n,error:i};return t.jsx(o.Provider,{value:u,children:e})},exports.useEngine=function(){const{engine:e,error:r}=i();if(r)throw r;return e},exports.useEngineContext=i,exports.usePdfiumEngine=function(t){const{wasmUrl:o=n,worker:i=!0,logger:u,encoderPoolSize:s,fontFallback:c}=t??{},[l,d]=e.useState(null),[a,g]=e.useState(!0),[f,p]=e.useState(null),m=e.useRef(null);return e.useEffect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),r=await e(o,{logger:u,encoderPoolSize:s,fontFallback:c});m.current=r,d(r),g(!1)}catch(r){e||(p(r),g(!1))}})(),()=>{var t,n;e=!0,null==(n=null==(t=m.current)?void 0:t.closeAllDocuments)||n.call(t).wait(()=>{var e,r;null==(r=null==(e=m.current)?void 0:e.destroy)||r.call(e),m.current=null},r.ignore)}},[o,i,u,c]),{engine:l,isLoading:a,error:f}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,7 @@
1
1
  import { useState, useRef, useEffect, createContext, useContext } from "react";
2
2
  import { ignore } from "@embedpdf/models";
3
3
  import { jsx } from "react/jsx-runtime";
4
- const defaultWasmUrl = `https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm`;
4
+ const defaultWasmUrl = `https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm`;
5
5
  function usePdfiumEngine(config) {
6
6
  const {
7
7
  wasmUrl = defaultWasmUrl,
@@ -1,2 +1,2 @@
1
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client"),t=require("svelte"),n=require("@embedpdf/models");function r(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}require("svelte/internal/disclose-version");const i=r(e),o=Symbol("pdfEngineContext");function s(){const e=t.getContext(o);if(void 0===e)throw new Error("getPdfEngineContext must be used within a PdfEngineProvider");return e}const l="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";exports.PdfEngineProvider=function(e,n){i.push(n,!0),i.user_effect(()=>{var e;e={engine:n.engine,isLoading:n.isLoading,error:n.error},t.setContext(o,e)});var r=i.comment(),s=i.first_child(r);i.snippet(s,()=>n.children),i.append(e,r),i.pop()},exports.useEngine=function(){const{engine:e,error:t}=s();if(t)throw t;return e},exports.useEngineContext=function(){const e=s();if(void 0===e)throw new Error("useEngineContext must be used within a PdfEngineProvider");return e},exports.usePdfiumEngine=function(e){const{wasmUrl:t=l,worker:r=!0,logger:o,fontFallback:s}=e??{},d=i.proxy({engine:null,isLoading:!0,error:null});let c=i.state(null);return"undefined"!=typeof window&&i.user_effect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=r?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),n=await e(t,{logger:o,fontFallback:s});i.set(c,n,!0),d.engine=n,d.isLoading=!1}catch(n){e||(d.error=n,d.isLoading=!1)}})(),()=>{var t,r;e=!0,null==(r=null==(t=i.get(c))?void 0:t.closeAllDocuments)||r.call(t).wait(()=>{var e,t;null==(t=null==(e=i.get(c))?void 0:e.destroy)||t.call(e),i.set(c,null)},n.ignore)}}),d};
1
+ "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client"),t=require("svelte"),n=require("@embedpdf/models");function r(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}require("svelte/internal/disclose-version");const i=r(e),o=Symbol("pdfEngineContext");function s(){const e=t.getContext(o);if(void 0===e)throw new Error("getPdfEngineContext must be used within a PdfEngineProvider");return e}const l="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";exports.PdfEngineProvider=function(e,n){i.push(n,!0),i.user_effect(()=>{var e;e={engine:n.engine,isLoading:n.isLoading,error:n.error},t.setContext(o,e)});var r=i.comment(),s=i.first_child(r);i.snippet(s,()=>n.children),i.append(e,r),i.pop()},exports.useEngine=function(){const{engine:e,error:t}=s();if(t)throw t;return e},exports.useEngineContext=function(){const e=s();if(void 0===e)throw new Error("useEngineContext must be used within a PdfEngineProvider");return e},exports.usePdfiumEngine=function(e){const{wasmUrl:t=l,worker:r=!0,logger:o,fontFallback:s}=e??{},d=i.proxy({engine:null,isLoading:!0,error:null});let c=i.state(null);return"undefined"!=typeof window&&i.user_effect(()=>{let e=!1;return(async()=>{try{const{createPdfiumEngine:e}=r?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),n=await e(t,{logger:o,fontFallback:s});i.set(c,n,!0),d.engine=n,d.isLoading=!1}catch(n){e||(d.error=n,d.isLoading=!1)}})(),()=>{var t,r;e=!0,null==(r=null==(t=i.get(c))?void 0:t.closeAllDocuments)||r.call(t).wait(()=>{var e,t;null==(t=null==(e=i.get(c))?void 0:e.destroy)||t.call(e),i.set(c,null)},n.ignore)}}),d};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -27,7 +27,7 @@ function useEngine() {
27
27
  }
28
28
  return engine;
29
29
  }
30
- const defaultWasmUrl = "https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";
30
+ const defaultWasmUrl = "https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";
31
31
  function usePdfiumEngine(config) {
32
32
  const {
33
33
  wasmUrl = defaultWasmUrl,
@@ -1,2 +1,2 @@
1
- "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@embedpdf/models"),r=Symbol("pdfEngineKey");function t(){const n=e.inject(r);if(!n)throw new Error("useEngineContext must be used within a PdfEngineProvider");return n}const o="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";const i=e.defineComponent({__name:"pdf-engine-provider",props:{engine:{},isLoading:{type:Boolean},error:{}},setup(n){const t=n,{engine:o,isLoading:i,error:u}=e.toRefs(t);return e.provide(r,{engine:o,isLoading:i,error:u}),(n,r)=>e.renderSlot(n.$slots,"default")}});exports.PdfEngineProvider=i,exports.useEngine=function(){const{engine:e,error:n}=t();if(n.value)throw n.value;return e},exports.useEngineContext=t,exports.usePdfiumEngine=function(r={}){const{wasmUrl:t=o,worker:i=!0,logger:u,fontFallback:l}=r,s=e.ref(null),a=e.ref(!0),d=e.ref(null);async function c(){try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),n=await e(t,{logger:u,fontFallback:l});s.value=n,a.value=!1}catch(e){d.value=e,a.value=!1}}function p(){var e,r;null==(r=null==(e=s.value)?void 0:e.closeAllDocuments)||r.call(e).wait(()=>{var e,n;null==(n=null==(e=s.value)?void 0:e.destroy)||n.call(e),s.value=null},n.ignore)}return e.onMounted(c),e.onBeforeUnmount(p),e.watch(()=>[t,i,u,l],()=>{p(),c()}),{engine:s,isLoading:a,error:d}};
1
+ "use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),n=require("@embedpdf/models"),r=Symbol("pdfEngineKey");function t(){const n=e.inject(r);if(!n)throw new Error("useEngineContext must be used within a PdfEngineProvider");return n}const o="https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";const i=e.defineComponent({__name:"pdf-engine-provider",props:{engine:{},isLoading:{type:Boolean},error:{}},setup(n){const t=n,{engine:o,isLoading:i,error:u}=e.toRefs(t);return e.provide(r,{engine:o,isLoading:i,error:u}),(n,r)=>e.renderSlot(n.$slots,"default")}});exports.PdfEngineProvider=i,exports.useEngine=function(){const{engine:e,error:n}=t();if(n.value)throw n.value;return e},exports.useEngineContext=t,exports.usePdfiumEngine=function(r={}){const{wasmUrl:t=o,worker:i=!0,logger:u,fontFallback:l}=r,s=e.ref(null),a=e.ref(!0),d=e.ref(null);async function c(){try{const{createPdfiumEngine:e}=i?await import("@embedpdf/engines/pdfium-worker-engine"):await import("@embedpdf/engines/pdfium-direct-engine"),n=await e(t,{logger:u,fontFallback:l});s.value=n,a.value=!1}catch(e){d.value=e,a.value=!1}}function p(){var e,r;null==(r=null==(e=s.value)?void 0:e.closeAllDocuments)||r.call(e).wait(()=>{var e,n;null==(n=null==(e=s.value)?void 0:e.destroy)||n.call(e),s.value=null},n.ignore)}return e.onMounted(c),e.onBeforeUnmount(p),e.watch(()=>[t,i,u,l],()=>{p(),c()}),{engine:s,isLoading:a,error:d}};
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/vue/index.js CHANGED
@@ -15,7 +15,7 @@ function useEngine() {
15
15
  }
16
16
  return engine;
17
17
  }
18
- const defaultWasmUrl = "https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.11.1/dist/pdfium.wasm";
18
+ const defaultWasmUrl = "https://cdn.jsdelivr.net/npm/@embedpdf/pdfium@2.12.0/dist/pdfium.wasm";
19
19
  function usePdfiumEngine(props = {}) {
20
20
  const { wasmUrl = defaultWasmUrl, worker = true, logger, fontFallback } = props;
21
21
  const engine = ref(null);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/engines",
3
- "version": "2.11.1",
3
+ "version": "2.12.0",
4
4
  "description": "Pluggable runtime layer that abstracts over multiple PDF engines (PDF-ium, Web Workers, mocks, etc.) to provide a unified API for rendering, search, annotation, and other document-level operations in EmbedPDF.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -90,13 +90,13 @@
90
90
  "dependencies": {
91
91
  "@embedpdf/fonts-arabic": "1.0.0",
92
92
  "@embedpdf/fonts-hebrew": "1.0.0",
93
- "@embedpdf/fonts-kr": "1.0.0",
93
+ "@embedpdf/fonts-jp": "1.0.0",
94
94
  "@embedpdf/fonts-latin": "1.0.0",
95
+ "@embedpdf/fonts-kr": "1.0.0",
95
96
  "@embedpdf/fonts-sc": "1.0.0",
96
97
  "@embedpdf/fonts-tc": "1.0.0",
97
- "@embedpdf/fonts-jp": "1.0.0",
98
- "@embedpdf/pdfium": "2.11.1",
99
- "@embedpdf/models": "2.11.1"
98
+ "@embedpdf/models": "2.12.0",
99
+ "@embedpdf/pdfium": "2.12.0"
100
100
  },
101
101
  "peerDependencies": {
102
102
  "preact": "^10.26.4",
@@ -1,2 +0,0 @@
1
- "use strict";function e(e,t,r){const n=t*r*4,a=e=>[255&e,e>>>8&255,e>>>16&255,e>>>24&255],o=new Uint8Array([66,77,...a(66+n),0,0,0,0,66,0,0,0,40,0,0,0,...a(t),...a(-r),1,0,32,0,3,0,0,0,...a(n),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,0,0,0,255,0,0,0,0,255,0]);return new Blob([o,e],{type:"image/bmp"})}class t extends Error{constructor(e){super(e),this.name="ImageConverterError"}}const r=(r,n="image/png",a)=>{const o=r();if("image/bmp"===n)return Promise.resolve(e(o.data,o.width,o.height));if("undefined"==typeof document)return Promise.reject(new t("document is not available. This converter requires a browser environment."));const i=new ImageData(o.data,o.width,o.height);return new Promise((e,r)=>{const o=document.createElement("canvas");o.width=i.width,o.height=i.height,o.getContext("2d").putImageData(i,0,0),o.toBlob(n=>{n?e(n):r(new t("Canvas toBlob returned null"))},n,a)})};exports.ImageConverterError=t,exports.browserImageDataToBlobConverter=r,exports.createHybridImageConverter=function(t){const n=async(n,a="image/png",o)=>{const i=n();if("image/bmp"===a)return e(i.data,i.width,i.height);try{const e=new Uint8ClampedArray(i.data);return await t.encode({data:e,width:i.width,height:i.height},a,o)}catch(s){return console.warn("Worker encoding failed, falling back to main-thread Canvas:",s),r(n,a,o)}};return n.destroy=()=>t.destroy(),n},exports.createWorkerPoolImageConverter=function(t){const r=(r,n="image/png",a)=>{const o=r();if("image/bmp"===n)return Promise.resolve(e(o.data,o.width,o.height));const i=new Uint8ClampedArray(o.data);return t.encode({data:i,width:o.width,height:o.height},n,a)};return r.destroy=()=>t.destroy(),r};
2
- //# sourceMappingURL=browser-BpXqcQ3U.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"browser-BpXqcQ3U.cjs","sources":["../src/lib/image-encoder/bmp.ts","../src/lib/converters/browser.ts"],"sourcesContent":["/**\n * Creates an uncompressed BMP blob from raw RGBA pixel data.\n *\n * Uses BI_BITFIELDS with channel masks matching RGBA byte order, so no\n * per-pixel byte swapping is needed. Top-down row order (negative height)\n * avoids row flipping. The result is a valid BMP that all modern browsers\n * can decode natively in `<img>` elements.\n *\n * This is dramatically faster than PNG/WebP/JPEG encoding via canvas.toBlob()\n * because it performs no compression — just a 66-byte header prepended to the\n * raw pixel buffer.\n */\nexport function rgbaToBmpBlob(rgba: Uint8ClampedArray, width: number, height: number): Blob {\n const pixels = width * height * 4;\n const headerLength = 66;\n const le32 = (v: number) => [v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff];\n\n // prettier-ignore\n const header = new Uint8Array([\n 0x42, 0x4D, // 'BM' signature\n ...le32(headerLength + pixels), // file size\n 0, 0, 0, 0, // reserved\n headerLength, 0, 0, 0, // pixel data offset\n 40, 0, 0, 0, // DIB header size\n ...le32(width), // width\n ...le32(-height), // height (negative = top-down)\n 1, 0, // color planes\n 32, 0, // bits per pixel\n 3, 0, 0, 0, // compression = BI_BITFIELDS\n ...le32(pixels), // image data size\n 0, 0, 0, 0, // h resolution\n 0, 0, 0, 0, // v resolution\n 0, 0, 0, 0, // colors in palette\n 0, 0, 0, 0, // important colors\n 0xFF, 0, 0, 0, // R channel mask\n 0, 0xFF, 0, 0, // G channel mask\n 0, 0, 0xFF, 0, // B channel mask\n ]);\n\n return new Blob([header, rgba], { type: 'image/bmp' });\n}\n","import type { ImageConversionTypes } from '@embedpdf/models';\nimport type { ImageDataConverter, LazyImageData } from './types';\nimport { ImageEncoderWorkerPool } from '../image-encoder';\nimport { rgbaToBmpBlob } from '../image-encoder/bmp';\n\n// ============================================================================\n// Error Classes\n// ============================================================================\n\nexport class ImageConverterError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ImageConverterError';\n }\n}\n\n// ============================================================================\n// Browser Converters\n// ============================================================================\n\n/**\n * Main-thread Canvas-based image converter\n * Simple and works everywhere, but blocks the main thread during encoding\n *\n * Use this as a fallback when worker-based encoding isn't available\n */\nexport const browserImageDataToBlobConverter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no canvas — just a header prepended to raw pixels\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n if (typeof document === 'undefined') {\n return Promise.reject(\n new ImageConverterError(\n 'document is not available. This converter requires a browser environment.',\n ),\n );\n }\n\n const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);\n\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas');\n canvas.width = imageData.width;\n canvas.height = imageData.height;\n canvas.getContext('2d')!.putImageData(imageData, 0, 0);\n\n canvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new ImageConverterError('Canvas toBlob returned null'));\n }\n },\n imageType,\n quality,\n );\n });\n};\n\n/**\n * Worker pool image converter using OffscreenCanvas in dedicated workers\n * Non-blocking - encoding happens off the main thread\n *\n * This is the preferred approach for performance\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createWorkerPoolImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n // Copy the data since we'll transfer it to another worker\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n\n/**\n * Hybrid converter: Worker pool (OffscreenCanvas) → Main thread Canvas fallback\n *\n * Best of both worlds:\n * - Primary: Non-blocking worker-based encoding with OffscreenCanvas\n * - Fallback: Main-thread Canvas for older browsers without OffscreenCanvas in workers\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createHybridImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = async (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height);\n }\n\n try {\n // Try worker pool encoding first (OffscreenCanvas in worker)\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return await workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n } catch (error) {\n // Fallback to main-thread Canvas\n console.warn('Worker encoding failed, falling back to main-thread Canvas:', error);\n return browserImageDataToBlobConverter(getImageData, imageType, quality);\n }\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n"],"names":["rgbaToBmpBlob","rgba","width","height","pixels","le32","v","header","Uint8Array","Blob","type","ImageConverterError","Error","constructor","message","super","this","name","browserImageDataToBlobConverter","getImageData","imageType","quality","pdfImage","Promise","resolve","data","document","reject","imageData","ImageData","canvas","createElement","getContext","putImageData","toBlob","blob","workerPool","converter","async","dataCopy","Uint8ClampedArray","encode","error","console","warn","destroy"],"mappings":"aAYO,SAASA,EAAcC,EAAyBC,EAAeC,GACpE,MAAMC,EAASF,EAAQC,EAAS,EAE1BE,EAAQC,GAAc,CAAK,IAAJA,EAAWA,IAAM,EAAK,IAAOA,IAAM,GAAM,IAAOA,IAAM,GAAM,KAGnFC,EAAS,IAAIC,WAAW,CAC5B,GAAM,MACHH,EANgB,GAMID,GACvB,EAAG,EAAG,EAAG,EAPU,GAQL,EAAG,EAAG,EACpB,GAAI,EAAG,EAAG,KACPC,EAAKH,MACLG,GAAMF,GACT,EAAG,EACH,GAAI,EACJ,EAAG,EAAG,EAAG,KACNE,EAAKD,GACR,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,EAAG,EAAG,EAAG,EACT,IAAM,EAAG,EAAG,EACZ,EAAG,IAAM,EAAG,EACZ,EAAG,EAAG,IAAM,IAGd,OAAO,IAAIK,KAAK,CAACF,EAAQN,GAAO,CAAES,KAAM,aAC1C,CC/BO,MAAMC,UAA4BC,MACvC,WAAAC,CAAYC,GACVC,MAAMD,GACNE,KAAKC,KAAO,qBACd,EAaK,MAAMC,EAA4D,CACvEC,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOG,QAAQC,QAAQxB,EAAcsB,EAASG,KAAMH,EAASpB,MAAOoB,EAASnB,SAG/E,GAAwB,oBAAbuB,SACT,OAAOH,QAAQI,OACb,IAAIhB,EACF,8EAKN,MAAMiB,EAAY,IAAIC,UAAUP,EAASG,KAAMH,EAASpB,MAAOoB,EAASnB,QAExE,OAAO,IAAIoB,QAAQ,CAACC,EAASG,KAC3B,MAAMG,EAASJ,SAASK,cAAc,UACtCD,EAAO5B,MAAQ0B,EAAU1B,MACzB4B,EAAO3B,OAASyB,EAAUzB,OAC1B2B,EAAOE,WAAW,MAAOC,aAAaL,EAAW,EAAG,GAEpDE,EAAOI,OACJC,IACKA,EACFX,EAAQW,GAERR,EAAO,IAAIhB,EAAoB,iCAGnCS,EACAC,iHA2DC,SACLe,GAEA,MAAMC,EAAsCC,MAC1CnB,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOpB,EAAcsB,EAASG,KAAMH,EAASpB,MAAOoB,EAASnB,QAG/D,IAEE,MAAMoC,EAAW,IAAIC,kBAAkBlB,EAASG,MAEhD,aAAaW,EAAWK,OACtB,CACEhB,KAAMc,EACNrC,MAAOoB,EAASpB,MAChBC,OAAQmB,EAASnB,QAEnBiB,EACAC,EAEJ,OAASqB,GAGP,OADAC,QAAQC,KAAK,8DAA+DF,GACrExB,EAAgCC,EAAcC,EAAWC,EAClE,GAMF,OAFAgB,EAAUQ,QAAU,IAAMT,EAAWS,UAE9BR,CACT,yCApFO,SACLD,GAEA,MAAMC,EAAsC,CAC1ClB,EACAC,EAAkC,YAClCC,KAEA,MAAMC,EAAWH,IAGjB,GAAkB,cAAdC,EACF,OAAOG,QAAQC,QAAQxB,EAAcsB,EAASG,KAAMH,EAASpB,MAAOoB,EAASnB,SAI/E,MAAMoC,EAAW,IAAIC,kBAAkBlB,EAASG,MAEhD,OAAOW,EAAWK,OAChB,CACEhB,KAAMc,EACNrC,MAAOoB,EAASpB,MAChBC,OAAQmB,EAASnB,QAEnBiB,EACAC,IAOJ,OAFAgB,EAAUQ,QAAU,IAAMT,EAAWS,UAE9BR,CACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"browser-BuzIa755.js","sources":["../src/lib/image-encoder/bmp.ts","../src/lib/converters/browser.ts"],"sourcesContent":["/**\n * Creates an uncompressed BMP blob from raw RGBA pixel data.\n *\n * Uses BI_BITFIELDS with channel masks matching RGBA byte order, so no\n * per-pixel byte swapping is needed. Top-down row order (negative height)\n * avoids row flipping. The result is a valid BMP that all modern browsers\n * can decode natively in `<img>` elements.\n *\n * This is dramatically faster than PNG/WebP/JPEG encoding via canvas.toBlob()\n * because it performs no compression — just a 66-byte header prepended to the\n * raw pixel buffer.\n */\nexport function rgbaToBmpBlob(rgba: Uint8ClampedArray, width: number, height: number): Blob {\n const pixels = width * height * 4;\n const headerLength = 66;\n const le32 = (v: number) => [v & 0xff, (v >>> 8) & 0xff, (v >>> 16) & 0xff, (v >>> 24) & 0xff];\n\n // prettier-ignore\n const header = new Uint8Array([\n 0x42, 0x4D, // 'BM' signature\n ...le32(headerLength + pixels), // file size\n 0, 0, 0, 0, // reserved\n headerLength, 0, 0, 0, // pixel data offset\n 40, 0, 0, 0, // DIB header size\n ...le32(width), // width\n ...le32(-height), // height (negative = top-down)\n 1, 0, // color planes\n 32, 0, // bits per pixel\n 3, 0, 0, 0, // compression = BI_BITFIELDS\n ...le32(pixels), // image data size\n 0, 0, 0, 0, // h resolution\n 0, 0, 0, 0, // v resolution\n 0, 0, 0, 0, // colors in palette\n 0, 0, 0, 0, // important colors\n 0xFF, 0, 0, 0, // R channel mask\n 0, 0xFF, 0, 0, // G channel mask\n 0, 0, 0xFF, 0, // B channel mask\n ]);\n\n return new Blob([header, rgba], { type: 'image/bmp' });\n}\n","import type { ImageConversionTypes } from '@embedpdf/models';\nimport type { ImageDataConverter, LazyImageData } from './types';\nimport { ImageEncoderWorkerPool } from '../image-encoder';\nimport { rgbaToBmpBlob } from '../image-encoder/bmp';\n\n// ============================================================================\n// Error Classes\n// ============================================================================\n\nexport class ImageConverterError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ImageConverterError';\n }\n}\n\n// ============================================================================\n// Browser Converters\n// ============================================================================\n\n/**\n * Main-thread Canvas-based image converter\n * Simple and works everywhere, but blocks the main thread during encoding\n *\n * Use this as a fallback when worker-based encoding isn't available\n */\nexport const browserImageDataToBlobConverter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no canvas — just a header prepended to raw pixels\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n if (typeof document === 'undefined') {\n return Promise.reject(\n new ImageConverterError(\n 'document is not available. This converter requires a browser environment.',\n ),\n );\n }\n\n const imageData = new ImageData(pdfImage.data, pdfImage.width, pdfImage.height);\n\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas');\n canvas.width = imageData.width;\n canvas.height = imageData.height;\n canvas.getContext('2d')!.putImageData(imageData, 0, 0);\n\n canvas.toBlob(\n (blob) => {\n if (blob) {\n resolve(blob);\n } else {\n reject(new ImageConverterError('Canvas toBlob returned null'));\n }\n },\n imageType,\n quality,\n );\n });\n};\n\n/**\n * Worker pool image converter using OffscreenCanvas in dedicated workers\n * Non-blocking - encoding happens off the main thread\n *\n * This is the preferred approach for performance\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createWorkerPoolImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return Promise.resolve(rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height));\n }\n\n // Copy the data since we'll transfer it to another worker\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n\n/**\n * Hybrid converter: Worker pool (OffscreenCanvas) → Main thread Canvas fallback\n *\n * Best of both worlds:\n * - Primary: Non-blocking worker-based encoding with OffscreenCanvas\n * - Fallback: Main-thread Canvas for older browsers without OffscreenCanvas in workers\n *\n * @param workerPool - Instance of ImageEncoderWorkerPool\n * @returns ImageDataConverter function with destroy() for cleanup\n */\nexport function createHybridImageConverter(\n workerPool: ImageEncoderWorkerPool,\n): ImageDataConverter<Blob> {\n const converter: ImageDataConverter<Blob> = async (\n getImageData: LazyImageData,\n imageType: ImageConversionTypes = 'image/png',\n quality?: number,\n ): Promise<Blob> => {\n const pdfImage = getImageData();\n\n // Fast path: BMP needs no worker round-trip\n if (imageType === 'image/bmp') {\n return rgbaToBmpBlob(pdfImage.data, pdfImage.width, pdfImage.height);\n }\n\n try {\n // Try worker pool encoding first (OffscreenCanvas in worker)\n const dataCopy = new Uint8ClampedArray(pdfImage.data);\n\n return await workerPool.encode(\n {\n data: dataCopy,\n width: pdfImage.width,\n height: pdfImage.height,\n },\n imageType,\n quality,\n );\n } catch (error) {\n // Fallback to main-thread Canvas\n console.warn('Worker encoding failed, falling back to main-thread Canvas:', error);\n return browserImageDataToBlobConverter(getImageData, imageType, quality);\n }\n };\n\n // Attach destroy method to clean up worker pool\n converter.destroy = () => workerPool.destroy();\n\n return converter;\n}\n"],"names":[],"mappings":"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"}