@embedpdf/engines 2.0.0-next.2 → 2.0.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.
- package/README.md +15 -9
- package/dist/browser-C6QEa8uk.cjs +2 -0
- package/dist/browser-C6QEa8uk.cjs.map +1 -0
- package/dist/browser-awZxztMA.js +76 -0
- package/dist/browser-awZxztMA.js.map +1 -0
- package/dist/{engine-B-RaFU77.js → direct-engine-DuLFAbiv.js} +211 -520
- package/dist/direct-engine-DuLFAbiv.js.map +1 -0
- package/dist/direct-engine-JeNRkc7w.cjs +2 -0
- package/dist/direct-engine-JeNRkc7w.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +301 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/converters/browser.d.ts +33 -0
- package/dist/lib/converters/index.cjs +1 -1
- package/dist/lib/converters/index.cjs.map +1 -1
- package/dist/lib/converters/index.d.ts +3 -51
- package/dist/lib/converters/index.js +6 -1
- package/dist/lib/converters/index.js.map +1 -1
- package/dist/lib/converters/node.d.ts +51 -0
- package/dist/lib/converters/types.d.ts +6 -3
- package/dist/lib/image-encoder/image-encoder-worker.d.ts +24 -0
- package/dist/lib/image-encoder/index.d.ts +2 -0
- package/dist/lib/image-encoder/worker-pool.d.ts +61 -0
- package/dist/lib/orchestrator/index.d.ts +16 -0
- package/dist/lib/orchestrator/pdf-engine.d.ts +99 -0
- package/dist/lib/orchestrator/pdfium-native-runner.d.ts +65 -0
- package/dist/lib/orchestrator/remote-executor.d.ts +93 -0
- package/dist/lib/orchestrator/task-queue.d.ts +87 -0
- package/dist/lib/pdfium/engine.d.ts +52 -93
- package/dist/lib/pdfium/index.cjs +1 -1
- package/dist/lib/pdfium/index.cjs.map +1 -1
- package/dist/lib/pdfium/index.d.ts +6 -1
- package/dist/lib/pdfium/index.js +15 -8
- package/dist/lib/pdfium/index.js.map +1 -1
- package/dist/lib/pdfium/runner.d.ts +2 -2
- package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
- package/dist/lib/pdfium/web/direct-engine.cjs.map +1 -1
- package/dist/lib/pdfium/web/direct-engine.d.ts +33 -2
- package/dist/lib/pdfium/web/direct-engine.js +5 -9
- package/dist/lib/pdfium/web/direct-engine.js.map +1 -1
- package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
- package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
- package/dist/lib/pdfium/web/worker-engine.d.ts +40 -4
- package/dist/lib/pdfium/web/worker-engine.js +412 -9
- package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
- package/dist/lib/webworker/engine.cjs +1 -1
- package/dist/lib/webworker/engine.cjs.map +1 -1
- package/dist/lib/webworker/engine.d.ts +0 -6
- package/dist/lib/webworker/engine.js +0 -13
- package/dist/lib/webworker/engine.js.map +1 -1
- package/dist/lib/webworker/runner.d.ts +0 -12
- package/dist/pdf-engine-BVNF_Yo9.js +790 -0
- package/dist/pdf-engine-BVNF_Yo9.js.map +1 -0
- package/dist/pdf-engine-C3JeKij1.cjs +2 -0
- package/dist/pdf-engine-C3JeKij1.cjs.map +1 -0
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +5 -13
- package/dist/preact/index.js.map +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +5 -13
- package/dist/react/index.js.map +1 -1
- package/dist/shared-preact/hooks/use-pdfium-engine.d.ts +1 -0
- package/dist/shared-react/hooks/use-pdfium-engine.d.ts +1 -0
- package/dist/svelte/index.cjs +1 -1
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js +3 -11
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +3 -12
- package/dist/vue/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/engine-B-RaFU77.js.map +0 -1
- package/dist/engine-CXnLqg_9.cjs +0 -2
- package/dist/engine-CXnLqg_9.cjs.map +0 -1
- package/dist/index-Cp8_nZYM.js +0 -342
- package/dist/index-Cp8_nZYM.js.map +0 -1
- package/dist/index-DuHK0qLu.cjs +0 -2
- package/dist/index-DuHK0qLu.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-engine.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"worker-engine.cjs","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 FormFieldValue,\n PdfFlattenPageOptions,\n PdfPageFlattenResult,\n PdfRedactTextOptions,\n Rect,\n PageTextSlice,\n PdfGlyphObject,\n PdfPageGeometry,\n PdfPrintOptions,\n PdfSignatureObject,\n AnnotationCreateContext,\n Task,\n TaskError,\n PdfErrorCode,\n SearchResult,\n serializeLogger,\n IPdfiumExecutor,\n ImageDataLike,\n} from '@embedpdf/models';\nimport type { WorkerRequest, WorkerResponse } from './pdfium-native-runner';\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\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 | '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 | 'setFormFieldValue'\n | 'flattenPage'\n | 'extractPages'\n | 'extractText'\n | 'redactTextInRects'\n | 'getTextSlices'\n | 'getPageGlyphs'\n | 'getPageGeometry'\n | 'merge'\n | 'mergePages'\n | 'preparePrintDocument'\n | 'saveAsCopy'\n | 'closeDocument'\n | 'closeAllDocuments';\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\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 });\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 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 ): PdfTask<boolean> {\n return this.send<boolean>('updatePageAnnotation', [doc, page, annotation]);\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 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 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 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 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 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","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/webp',\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","_RemoteExecutor","constructor","worker","options","this","pendingRequests","Map","requestCounter","handleMessage","event","response","data","type","logger","debug","readyTask","resolve","task","get","id","delete","error","fail","reject","code","PdfErrorCode","Unknown","message","progress","warn","NoopLogger","addEventListener","Task","set","READY_TASK_ID","postMessage","wasmUrl","serializeLogger","generateId","Date","now","send","method","args","request","wait","Initialization","destroy","removeEventListener","forEach","abort","clear","terminate","openDocumentBuffer","file","getMetadata","doc","setMetadata","metadata","getDocPermissions","getDocUserPermissions","getSignatures","getBookmarks","setBookmarks","bookmarks","deleteBookmarks","renderPageRaw","page","renderPageRect","rect","renderThumbnailRaw","renderPageAnnotationRaw","annotation","getPageAnnotationsRaw","getPageAnnotations","createPageAnnotation","context","updatePageAnnotation","removePageAnnotation","getPageTextRects","searchInPage","keyword","flags","getAnnotationsBatch","pages","searchBatch","getAttachments","addAttachment","params","removeAttachment","attachment","readAttachmentContent","setFormFieldValue","value","flattenPage","extractPages","pageIndexes","extractText","redactTextInRects","rects","getTextSlices","slices","getPageGlyphs","getPageGeometry","merge","files","mergePages","mergeConfigs","preparePrintDocument","saveAsCopy","closeDocument","closeAllDocuments","RemoteExecutor","ImageEncoderWorkerPool","poolSize","workerUrl","workers","pendingTasks","nextWorkerId","initialize","i","Worker","onmessage","handleWorkerMessage","bind","onerror","handleWorkerError","push","errorData","Error","getNextWorker","length","encode","imageData","imageType","quality","Promise","requestId","width","height","buffer","index","activeWorkers","pendingTasksCount","size"],"mappings":"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"}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
1
|
import { Logger } from '@embedpdf/models';
|
|
2
|
-
import {
|
|
2
|
+
import { PdfEngine } from '../../orchestrator/pdf-engine';
|
|
3
|
+
export interface CreatePdfiumEngineOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Logger instance for debugging
|
|
6
|
+
*/
|
|
7
|
+
logger?: Logger;
|
|
8
|
+
/**
|
|
9
|
+
* Number of workers in the image encoder pool (default: 0 - disabled)
|
|
10
|
+
* Set to 2-4 for optimal performance with parallel encoding
|
|
11
|
+
*/
|
|
12
|
+
encoderPoolSize?: number;
|
|
13
|
+
}
|
|
3
14
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
15
|
+
* Create a PDFium engine running in a Web Worker
|
|
16
|
+
*
|
|
17
|
+
* This is the "worker" mode where PDFium runs in a separate worker thread.
|
|
18
|
+
* The PdfEngine orchestrator provides priority-based task scheduling and
|
|
19
|
+
* parallel image encoding with a separate encoder pool.
|
|
20
|
+
*
|
|
21
|
+
* @param wasmUrl - URL to the pdfium.wasm file
|
|
22
|
+
* @param options - Configuration options (can be Logger for backward compatibility)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // Legacy usage (backward compatible)
|
|
26
|
+
* const engine = createPdfiumEngine('/wasm/pdfium.wasm', logger);
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* // With encoder pool (automatic - no URL needed!)
|
|
30
|
+
* const engine = createPdfiumEngine('/wasm/pdfium.wasm', {
|
|
31
|
+
* logger,
|
|
32
|
+
* encoderPoolSize: 2
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* // With custom encoder worker URL
|
|
37
|
+
* const engine = createPdfiumEngine('/wasm/pdfium.wasm', {
|
|
38
|
+
* logger,
|
|
39
|
+
* encoderPoolSize: 2,
|
|
40
|
+
* encoderWorkerUrl: '/custom/encoder-worker.js'
|
|
41
|
+
* });
|
|
6
42
|
*/
|
|
7
|
-
export declare function createPdfiumEngine(wasmUrl: string,
|
|
43
|
+
export declare function createPdfiumEngine(wasmUrl: string, options?: Logger | CreatePdfiumEngineOptions): PdfEngine<Blob>;
|