@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.
Files changed (82) hide show
  1. package/README.md +15 -9
  2. package/dist/browser-C6QEa8uk.cjs +2 -0
  3. package/dist/browser-C6QEa8uk.cjs.map +1 -0
  4. package/dist/browser-awZxztMA.js +76 -0
  5. package/dist/browser-awZxztMA.js.map +1 -0
  6. package/dist/{engine-B-RaFU77.js → direct-engine-DuLFAbiv.js} +211 -520
  7. package/dist/direct-engine-DuLFAbiv.js.map +1 -0
  8. package/dist/direct-engine-JeNRkc7w.cjs +2 -0
  9. package/dist/direct-engine-JeNRkc7w.cjs.map +1 -0
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +301 -10
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/converters/browser.d.ts +33 -0
  15. package/dist/lib/converters/index.cjs +1 -1
  16. package/dist/lib/converters/index.cjs.map +1 -1
  17. package/dist/lib/converters/index.d.ts +3 -51
  18. package/dist/lib/converters/index.js +6 -1
  19. package/dist/lib/converters/index.js.map +1 -1
  20. package/dist/lib/converters/node.d.ts +51 -0
  21. package/dist/lib/converters/types.d.ts +6 -3
  22. package/dist/lib/image-encoder/image-encoder-worker.d.ts +24 -0
  23. package/dist/lib/image-encoder/index.d.ts +2 -0
  24. package/dist/lib/image-encoder/worker-pool.d.ts +61 -0
  25. package/dist/lib/orchestrator/index.d.ts +16 -0
  26. package/dist/lib/orchestrator/pdf-engine.d.ts +99 -0
  27. package/dist/lib/orchestrator/pdfium-native-runner.d.ts +65 -0
  28. package/dist/lib/orchestrator/remote-executor.d.ts +93 -0
  29. package/dist/lib/orchestrator/task-queue.d.ts +87 -0
  30. package/dist/lib/pdfium/engine.d.ts +52 -93
  31. package/dist/lib/pdfium/index.cjs +1 -1
  32. package/dist/lib/pdfium/index.cjs.map +1 -1
  33. package/dist/lib/pdfium/index.d.ts +6 -1
  34. package/dist/lib/pdfium/index.js +15 -8
  35. package/dist/lib/pdfium/index.js.map +1 -1
  36. package/dist/lib/pdfium/runner.d.ts +2 -2
  37. package/dist/lib/pdfium/web/direct-engine.cjs +1 -1
  38. package/dist/lib/pdfium/web/direct-engine.cjs.map +1 -1
  39. package/dist/lib/pdfium/web/direct-engine.d.ts +33 -2
  40. package/dist/lib/pdfium/web/direct-engine.js +5 -9
  41. package/dist/lib/pdfium/web/direct-engine.js.map +1 -1
  42. package/dist/lib/pdfium/web/worker-engine.cjs +1 -1
  43. package/dist/lib/pdfium/web/worker-engine.cjs.map +1 -1
  44. package/dist/lib/pdfium/web/worker-engine.d.ts +40 -4
  45. package/dist/lib/pdfium/web/worker-engine.js +412 -9
  46. package/dist/lib/pdfium/web/worker-engine.js.map +1 -1
  47. package/dist/lib/webworker/engine.cjs +1 -1
  48. package/dist/lib/webworker/engine.cjs.map +1 -1
  49. package/dist/lib/webworker/engine.d.ts +0 -6
  50. package/dist/lib/webworker/engine.js +0 -13
  51. package/dist/lib/webworker/engine.js.map +1 -1
  52. package/dist/lib/webworker/runner.d.ts +0 -12
  53. package/dist/pdf-engine-BVNF_Yo9.js +790 -0
  54. package/dist/pdf-engine-BVNF_Yo9.js.map +1 -0
  55. package/dist/pdf-engine-C3JeKij1.cjs +2 -0
  56. package/dist/pdf-engine-C3JeKij1.cjs.map +1 -0
  57. package/dist/preact/index.cjs +1 -1
  58. package/dist/preact/index.cjs.map +1 -1
  59. package/dist/preact/index.js +5 -13
  60. package/dist/preact/index.js.map +1 -1
  61. package/dist/react/index.cjs +1 -1
  62. package/dist/react/index.cjs.map +1 -1
  63. package/dist/react/index.js +5 -13
  64. package/dist/react/index.js.map +1 -1
  65. package/dist/shared-preact/hooks/use-pdfium-engine.d.ts +1 -0
  66. package/dist/shared-react/hooks/use-pdfium-engine.d.ts +1 -0
  67. package/dist/svelte/index.cjs +1 -1
  68. package/dist/svelte/index.cjs.map +1 -1
  69. package/dist/svelte/index.js +3 -11
  70. package/dist/svelte/index.js.map +1 -1
  71. package/dist/vue/index.cjs +1 -1
  72. package/dist/vue/index.cjs.map +1 -1
  73. package/dist/vue/index.js +3 -12
  74. package/dist/vue/index.js.map +1 -1
  75. package/package.json +3 -3
  76. package/dist/engine-B-RaFU77.js.map +0 -1
  77. package/dist/engine-CXnLqg_9.cjs +0 -2
  78. package/dist/engine-CXnLqg_9.cjs.map +0 -1
  79. package/dist/index-Cp8_nZYM.js +0 -342
  80. package/dist/index-Cp8_nZYM.js.map +0 -1
  81. package/dist/index-DuHK0qLu.cjs +0 -2
  82. package/dist/index-DuHK0qLu.cjs.map +0 -1
@@ -0,0 +1,790 @@
1
+ import { NoopLogger, Task, PdfEngineOperation, PdfErrorCode, CompoundTask } from "@embedpdf/models";
2
+ const LOG_SOURCE$1 = "TaskQueue";
3
+ const LOG_CATEGORY$1 = "Queue";
4
+ var Priority = /* @__PURE__ */ ((Priority2) => {
5
+ Priority2[Priority2["CRITICAL"] = 3] = "CRITICAL";
6
+ Priority2[Priority2["HIGH"] = 2] = "HIGH";
7
+ Priority2[Priority2["MEDIUM"] = 1] = "MEDIUM";
8
+ Priority2[Priority2["LOW"] = 0] = "LOW";
9
+ return Priority2;
10
+ })(Priority || {});
11
+ class WorkerTaskQueue {
12
+ constructor(options = {}) {
13
+ this.queue = [];
14
+ this.running = 0;
15
+ this.resultTasks = /* @__PURE__ */ new Map();
16
+ this.idleListeners = /* @__PURE__ */ new Set();
17
+ const {
18
+ concurrency = 1,
19
+ comparator,
20
+ ranker,
21
+ onIdle,
22
+ maxQueueSize,
23
+ autoStart = true,
24
+ logger
25
+ } = options;
26
+ this.logger = logger ?? new NoopLogger();
27
+ this.opts = {
28
+ concurrency: Math.max(1, concurrency),
29
+ comparator,
30
+ ranker,
31
+ onIdle: onIdle ?? (() => {
32
+ }),
33
+ maxQueueSize: maxQueueSize ?? Number.POSITIVE_INFINITY,
34
+ autoStart
35
+ };
36
+ }
37
+ setComparator(comparator) {
38
+ this.opts.comparator = comparator;
39
+ }
40
+ setRanker(ranker) {
41
+ this.opts.ranker = ranker;
42
+ }
43
+ size() {
44
+ return this.queue.length;
45
+ }
46
+ inFlight() {
47
+ return this.running;
48
+ }
49
+ isIdle() {
50
+ return this.queue.length === 0 && this.running === 0;
51
+ }
52
+ async drain() {
53
+ if (this.isIdle()) return;
54
+ await new Promise((resolve) => {
55
+ const check = () => {
56
+ if (this.isIdle()) {
57
+ this.offIdle(check);
58
+ resolve();
59
+ }
60
+ };
61
+ this.onIdle(check);
62
+ });
63
+ }
64
+ notifyIdle() {
65
+ if (this.isIdle()) {
66
+ [...this.idleListeners].forEach((fn) => fn());
67
+ this.idleListeners.clear();
68
+ this.opts.onIdle();
69
+ }
70
+ }
71
+ onIdle(fn) {
72
+ this.idleListeners.add(fn);
73
+ }
74
+ offIdle(fn) {
75
+ this.idleListeners.delete(fn);
76
+ }
77
+ /**
78
+ * Enqueue a task factory - with automatic type inference!
79
+ *
80
+ * The factory function is ONLY called when it's the task's turn to execute.
81
+ *
82
+ * Usage:
83
+ * const task = queue.enqueue({
84
+ * execute: () => this.executor.getMetadata(doc), // Factory - not called yet!
85
+ * meta: { operation: 'getMetadata' }
86
+ * }, { priority: Priority.LOW });
87
+ *
88
+ * The returned task has the SAME type as executor.getMetadata() would return!
89
+ */
90
+ enqueue(taskDef, options = {}) {
91
+ const id = this.generateId();
92
+ const priority = options.priority ?? 1;
93
+ const resultTask = new Task();
94
+ if (this.queue.length >= this.opts.maxQueueSize) {
95
+ const error = new Error("Queue is full (maxQueueSize reached).");
96
+ resultTask.reject(error);
97
+ return resultTask;
98
+ }
99
+ this.resultTasks.set(id, resultTask);
100
+ const queuedTask = {
101
+ id,
102
+ priority,
103
+ meta: options.meta ?? taskDef.meta,
104
+ executeFactory: taskDef.execute
105
+ // Store factory, don't call it yet!
106
+ };
107
+ this.queue.push(queuedTask);
108
+ this.logger.debug(
109
+ LOG_SOURCE$1,
110
+ LOG_CATEGORY$1,
111
+ `Task enqueued: ${id} | Priority: ${priority} | Running: ${this.running} | Queued: ${this.queue.length}`
112
+ );
113
+ const originalAbort = resultTask.abort.bind(resultTask);
114
+ resultTask.abort = (reason) => {
115
+ this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, `Task aborted: ${id}`);
116
+ this.cancel(id);
117
+ originalAbort(reason);
118
+ };
119
+ if (this.opts.autoStart) this.process(options.fifo === true);
120
+ return resultTask;
121
+ }
122
+ /**
123
+ * Cancel/remove a task from the queue
124
+ */
125
+ cancel(taskId) {
126
+ const before = this.queue.length;
127
+ this.queue = this.queue.filter((t) => {
128
+ if (t.id === taskId) {
129
+ t.cancelled = true;
130
+ return false;
131
+ }
132
+ return true;
133
+ });
134
+ this.resultTasks.delete(taskId);
135
+ if (before !== this.queue.length) {
136
+ this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, `Task cancelled and removed: ${taskId}`);
137
+ this.kick();
138
+ }
139
+ }
140
+ kick() {
141
+ queueMicrotask(() => this.process());
142
+ }
143
+ async process(fifo = false) {
144
+ this.logger.debug(
145
+ LOG_SOURCE$1,
146
+ LOG_CATEGORY$1,
147
+ `process() called | Running: ${this.running} | Concurrency: ${this.opts.concurrency} | Queued: ${this.queue.length}`
148
+ );
149
+ while (this.running < this.opts.concurrency && this.queue.length > 0) {
150
+ this.logger.debug(
151
+ LOG_SOURCE$1,
152
+ LOG_CATEGORY$1,
153
+ `Starting new task | Running: ${this.running} | Queued: ${this.queue.length}`
154
+ );
155
+ if (!fifo) this.sortQueue();
156
+ const queuedTask = this.queue.shift();
157
+ if (queuedTask.cancelled) {
158
+ this.logger.debug(LOG_SOURCE$1, LOG_CATEGORY$1, `Skipping cancelled task: ${queuedTask.id}`);
159
+ continue;
160
+ }
161
+ const resultTask = this.resultTasks.get(queuedTask.id);
162
+ if (!resultTask) continue;
163
+ this.running++;
164
+ (async () => {
165
+ let realTask = null;
166
+ try {
167
+ realTask = queuedTask.executeFactory();
168
+ if (!realTask) {
169
+ throw new Error("Task factory returned null/undefined");
170
+ }
171
+ realTask.wait(
172
+ (result) => {
173
+ if (resultTask.state.stage === 0) {
174
+ resultTask.resolve(result);
175
+ }
176
+ },
177
+ (error) => {
178
+ if (resultTask.state.stage === 0) {
179
+ if (error.type === "abort") {
180
+ resultTask.abort(error.reason);
181
+ } else {
182
+ resultTask.reject(error.reason);
183
+ }
184
+ }
185
+ }
186
+ );
187
+ realTask.onProgress((progress) => {
188
+ resultTask.progress(progress);
189
+ });
190
+ await realTask.toPromise();
191
+ } catch (error) {
192
+ if (resultTask.state.stage === 0) {
193
+ resultTask.reject(error);
194
+ }
195
+ } finally {
196
+ this.resultTasks.delete(queuedTask.id);
197
+ this.running--;
198
+ this.logger.debug(
199
+ LOG_SOURCE$1,
200
+ LOG_CATEGORY$1,
201
+ `Task completed: ${queuedTask.id} | Running: ${this.running} | Queued: ${this.queue.length}`
202
+ );
203
+ if (this.isIdle()) {
204
+ this.notifyIdle();
205
+ } else if (this.queue.length > 0) {
206
+ this.kick();
207
+ }
208
+ }
209
+ })().catch((error) => {
210
+ this.logger.error(
211
+ LOG_SOURCE$1,
212
+ LOG_CATEGORY$1,
213
+ "Unhandled error in task execution wrapper:",
214
+ error
215
+ );
216
+ this.running = Math.max(0, this.running - 1);
217
+ if (this.isIdle()) {
218
+ this.notifyIdle();
219
+ } else if (this.queue.length > 0) {
220
+ this.kick();
221
+ }
222
+ });
223
+ }
224
+ }
225
+ sortQueue() {
226
+ const { comparator, ranker } = this.opts;
227
+ if (comparator) {
228
+ this.queue.sort(comparator);
229
+ return;
230
+ }
231
+ const rankCache = /* @__PURE__ */ new Map();
232
+ const getRank = (t) => {
233
+ if (!ranker) return this.defaultRank(t);
234
+ if (!rankCache.has(t.id)) rankCache.set(t.id, ranker(t));
235
+ return rankCache.get(t.id);
236
+ };
237
+ this.queue.sort((a, b) => {
238
+ if (a.priority !== b.priority) return b.priority - a.priority;
239
+ const ar = getRank(a);
240
+ const br = getRank(b);
241
+ if (ar !== br) return br - ar;
242
+ return this.extractTime(a.id) - this.extractTime(b.id);
243
+ });
244
+ }
245
+ defaultRank(_task) {
246
+ return 0;
247
+ }
248
+ generateId() {
249
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
250
+ return crypto.randomUUID();
251
+ }
252
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
253
+ }
254
+ extractTime(id) {
255
+ const t = Number(id.split("-")[0]);
256
+ return Number.isFinite(t) ? t : 0;
257
+ }
258
+ }
259
+ const LOG_SOURCE = "PdfEngine";
260
+ const LOG_CATEGORY = "Orchestrator";
261
+ class PdfEngine {
262
+ constructor(executor, options) {
263
+ this.executor = executor;
264
+ this.logger = options.logger ?? new NoopLogger();
265
+ this.options = {
266
+ imageConverter: options.imageConverter,
267
+ fetcher: options.fetcher ?? (typeof fetch !== "undefined" ? (url, init) => fetch(url, init) : void 0),
268
+ logger: this.logger
269
+ };
270
+ this.workerQueue = new WorkerTaskQueue({
271
+ concurrency: 1,
272
+ autoStart: true,
273
+ logger: this.logger
274
+ });
275
+ this.logger.debug(LOG_SOURCE, LOG_CATEGORY, "PdfEngine orchestrator created");
276
+ }
277
+ /**
278
+ * Split an array into chunks of a given size
279
+ */
280
+ chunkArray(items, chunkSize) {
281
+ const chunks = [];
282
+ for (let i = 0; i < items.length; i += chunkSize) {
283
+ chunks.push(items.slice(i, i + chunkSize));
284
+ }
285
+ return chunks;
286
+ }
287
+ // ========== IPdfEngine Implementation ==========
288
+ isSupport(feature) {
289
+ const task = new Task();
290
+ task.resolve([
291
+ PdfEngineOperation.Create,
292
+ PdfEngineOperation.Read,
293
+ PdfEngineOperation.Update,
294
+ PdfEngineOperation.Delete
295
+ ]);
296
+ return task;
297
+ }
298
+ destroy() {
299
+ const task = new Task();
300
+ try {
301
+ this.executor.destroy();
302
+ task.resolve(true);
303
+ } catch (error) {
304
+ task.reject({ code: PdfErrorCode.Unknown, message: String(error) });
305
+ }
306
+ return task;
307
+ }
308
+ openDocumentUrl(file, options) {
309
+ const task = new Task();
310
+ (async () => {
311
+ try {
312
+ if (!this.options.fetcher) {
313
+ throw new Error("Fetcher is not set");
314
+ }
315
+ const response = await this.options.fetcher(file.url, options == null ? void 0 : options.requestOptions);
316
+ const arrayBuf = await response.arrayBuffer();
317
+ const pdfFile = {
318
+ id: file.id,
319
+ content: arrayBuf
320
+ };
321
+ this.openDocumentBuffer(pdfFile, {
322
+ password: options == null ? void 0 : options.password
323
+ }).wait(
324
+ (doc) => task.resolve(doc),
325
+ (error) => task.fail(error)
326
+ );
327
+ } catch (error) {
328
+ task.reject({ code: PdfErrorCode.Unknown, message: String(error) });
329
+ }
330
+ })();
331
+ return task;
332
+ }
333
+ openDocumentBuffer(file, options) {
334
+ return this.workerQueue.enqueue(
335
+ {
336
+ execute: () => this.executor.openDocumentBuffer(file, options),
337
+ meta: { docId: file.id, operation: "openDocumentBuffer" }
338
+ },
339
+ { priority: Priority.CRITICAL }
340
+ );
341
+ }
342
+ getMetadata(doc) {
343
+ return this.workerQueue.enqueue(
344
+ {
345
+ execute: () => this.executor.getMetadata(doc),
346
+ meta: { docId: doc.id, operation: "getMetadata" }
347
+ },
348
+ { priority: Priority.MEDIUM }
349
+ );
350
+ }
351
+ setMetadata(doc, metadata) {
352
+ return this.workerQueue.enqueue(
353
+ {
354
+ execute: () => this.executor.setMetadata(doc, metadata),
355
+ meta: { docId: doc.id, operation: "setMetadata" }
356
+ },
357
+ { priority: Priority.MEDIUM }
358
+ );
359
+ }
360
+ getDocPermissions(doc) {
361
+ return this.workerQueue.enqueue(
362
+ {
363
+ execute: () => this.executor.getDocPermissions(doc),
364
+ meta: { docId: doc.id, operation: "getDocPermissions" }
365
+ },
366
+ { priority: Priority.MEDIUM }
367
+ );
368
+ }
369
+ getDocUserPermissions(doc) {
370
+ return this.workerQueue.enqueue(
371
+ {
372
+ execute: () => this.executor.getDocUserPermissions(doc),
373
+ meta: { docId: doc.id, operation: "getDocUserPermissions" }
374
+ },
375
+ { priority: Priority.MEDIUM }
376
+ );
377
+ }
378
+ getSignatures(doc) {
379
+ return this.workerQueue.enqueue(
380
+ {
381
+ execute: () => this.executor.getSignatures(doc),
382
+ meta: { docId: doc.id, operation: "getSignatures" }
383
+ },
384
+ { priority: Priority.MEDIUM }
385
+ );
386
+ }
387
+ getBookmarks(doc) {
388
+ return this.workerQueue.enqueue(
389
+ {
390
+ execute: () => this.executor.getBookmarks(doc),
391
+ meta: { docId: doc.id, operation: "getBookmarks" }
392
+ },
393
+ { priority: Priority.MEDIUM }
394
+ );
395
+ }
396
+ setBookmarks(doc, bookmarks) {
397
+ return this.workerQueue.enqueue(
398
+ {
399
+ execute: () => this.executor.setBookmarks(doc, bookmarks),
400
+ meta: { docId: doc.id, operation: "setBookmarks" }
401
+ },
402
+ { priority: Priority.MEDIUM }
403
+ );
404
+ }
405
+ deleteBookmarks(doc) {
406
+ return this.workerQueue.enqueue(
407
+ {
408
+ execute: () => this.executor.deleteBookmarks(doc),
409
+ meta: { docId: doc.id, operation: "deleteBookmarks" }
410
+ },
411
+ { priority: Priority.MEDIUM }
412
+ );
413
+ }
414
+ // ========== Rendering with Encoding ==========
415
+ renderPage(doc, page, options) {
416
+ return this.renderWithEncoding(
417
+ () => this.executor.renderPageRaw(doc, page, options),
418
+ options,
419
+ doc.id,
420
+ page.index,
421
+ Priority.CRITICAL
422
+ );
423
+ }
424
+ renderPageRect(doc, page, rect, options) {
425
+ return this.renderWithEncoding(
426
+ () => this.executor.renderPageRect(doc, page, rect, options),
427
+ options,
428
+ doc.id,
429
+ page.index,
430
+ Priority.HIGH
431
+ );
432
+ }
433
+ renderThumbnail(doc, page, options) {
434
+ return this.renderWithEncoding(
435
+ () => this.executor.renderThumbnailRaw(doc, page, options),
436
+ options,
437
+ doc.id,
438
+ page.index,
439
+ Priority.MEDIUM
440
+ );
441
+ }
442
+ renderPageAnnotation(doc, page, annotation, options) {
443
+ return this.renderWithEncoding(
444
+ () => this.executor.renderPageAnnotationRaw(doc, page, annotation, options),
445
+ options,
446
+ doc.id,
447
+ page.index,
448
+ Priority.MEDIUM
449
+ );
450
+ }
451
+ /**
452
+ * Helper to render and encode in two stages with priority queue
453
+ */
454
+ renderWithEncoding(renderFn, options, docId, pageIndex, priority = Priority.CRITICAL) {
455
+ const resultTask = new Task();
456
+ const renderHandle = this.workerQueue.enqueue(
457
+ {
458
+ execute: () => renderFn(),
459
+ meta: { docId, pageIndex, operation: "render" }
460
+ },
461
+ { priority }
462
+ );
463
+ const originalAbort = resultTask.abort.bind(resultTask);
464
+ resultTask.abort = (reason) => {
465
+ renderHandle.abort(reason);
466
+ originalAbort(reason);
467
+ };
468
+ renderHandle.wait(
469
+ (rawImageData) => {
470
+ if (resultTask.state.stage !== 0) {
471
+ return;
472
+ }
473
+ this.encodeImage(rawImageData, options, resultTask);
474
+ },
475
+ (error) => {
476
+ if (resultTask.state.stage === 0) {
477
+ resultTask.fail(error);
478
+ }
479
+ }
480
+ );
481
+ return resultTask;
482
+ }
483
+ /**
484
+ * Encode image using encoder pool or inline
485
+ */
486
+ encodeImage(rawImageData, options, resultTask) {
487
+ const imageType = (options == null ? void 0 : options.imageType) ?? "image/webp";
488
+ const quality = options == null ? void 0 : options.quality;
489
+ const plainImageData = {
490
+ data: new Uint8ClampedArray(rawImageData.data),
491
+ width: rawImageData.width,
492
+ height: rawImageData.height
493
+ };
494
+ this.options.imageConverter(() => plainImageData, imageType, quality).then((result) => resultTask.resolve(result)).catch((error) => resultTask.reject({ code: PdfErrorCode.Unknown, message: String(error) }));
495
+ }
496
+ // ========== Annotations ==========
497
+ getPageAnnotations(doc, page) {
498
+ return this.workerQueue.enqueue(
499
+ {
500
+ execute: () => this.executor.getPageAnnotations(doc, page),
501
+ meta: { docId: doc.id, pageIndex: page.index, operation: "getPageAnnotations" }
502
+ },
503
+ { priority: Priority.MEDIUM }
504
+ );
505
+ }
506
+ createPageAnnotation(doc, page, annotation, context) {
507
+ return this.workerQueue.enqueue(
508
+ {
509
+ execute: () => this.executor.createPageAnnotation(doc, page, annotation, context),
510
+ meta: { docId: doc.id, pageIndex: page.index, operation: "createPageAnnotation" }
511
+ },
512
+ { priority: Priority.MEDIUM }
513
+ );
514
+ }
515
+ updatePageAnnotation(doc, page, annotation) {
516
+ return this.workerQueue.enqueue(
517
+ {
518
+ execute: () => this.executor.updatePageAnnotation(doc, page, annotation),
519
+ meta: { docId: doc.id, pageIndex: page.index, operation: "updatePageAnnotation" }
520
+ },
521
+ { priority: Priority.MEDIUM }
522
+ );
523
+ }
524
+ removePageAnnotation(doc, page, annotation) {
525
+ return this.workerQueue.enqueue(
526
+ {
527
+ execute: () => this.executor.removePageAnnotation(doc, page, annotation),
528
+ meta: { docId: doc.id, pageIndex: page.index, operation: "removePageAnnotation" }
529
+ },
530
+ { priority: Priority.MEDIUM }
531
+ );
532
+ }
533
+ /**
534
+ * Get all annotations across all pages
535
+ * Uses batched operations to reduce queue overhead
536
+ */
537
+ getAllAnnotations(doc) {
538
+ const chunks = this.chunkArray(doc.pages, 500);
539
+ this.logger.debug(
540
+ LOG_SOURCE,
541
+ LOG_CATEGORY,
542
+ `getAllAnnotations: ${doc.pages.length} pages in ${chunks.length} chunks`
543
+ );
544
+ const compound = new CompoundTask({
545
+ aggregate: (results) => Object.assign({}, ...results)
546
+ });
547
+ chunks.forEach((chunkPages, chunkIndex) => {
548
+ const batchTask = this.workerQueue.enqueue(
549
+ {
550
+ execute: () => this.executor.getAnnotationsBatch(doc, chunkPages),
551
+ meta: { docId: doc.id, operation: "getAnnotationsBatch", chunkSize: chunkPages.length }
552
+ },
553
+ { priority: Priority.LOW }
554
+ );
555
+ batchTask.onProgress((batchProgress) => {
556
+ compound.progress({
557
+ page: batchProgress.pageIndex,
558
+ result: batchProgress.result
559
+ });
560
+ });
561
+ compound.addChild(batchTask, chunkIndex);
562
+ });
563
+ compound.finalize();
564
+ return compound;
565
+ }
566
+ getPageTextRects(doc, page) {
567
+ return this.workerQueue.enqueue(
568
+ {
569
+ execute: () => this.executor.getPageTextRects(doc, page),
570
+ meta: { docId: doc.id, pageIndex: page.index, operation: "getPageTextRects" }
571
+ },
572
+ {
573
+ priority: Priority.MEDIUM
574
+ }
575
+ );
576
+ }
577
+ // ========== Search ==========
578
+ /**
579
+ * Search across all pages
580
+ * Uses batched operations to reduce queue overhead
581
+ */
582
+ searchAllPages(doc, keyword, options) {
583
+ const flags = Array.isArray(options == null ? void 0 : options.flags) ? options.flags.reduce((acc, flag) => acc | flag, 0) : (options == null ? void 0 : options.flags) ?? 0;
584
+ const chunks = this.chunkArray(doc.pages, 25);
585
+ this.logger.debug(
586
+ LOG_SOURCE,
587
+ LOG_CATEGORY,
588
+ `searchAllPages: ${doc.pages.length} pages in ${chunks.length} chunks`
589
+ );
590
+ const compound = new CompoundTask({
591
+ aggregate: (results) => {
592
+ const allResults = results.flatMap(
593
+ (batchResult) => Object.values(batchResult).flat()
594
+ );
595
+ return { results: allResults, total: allResults.length };
596
+ }
597
+ });
598
+ chunks.forEach((chunkPages, chunkIndex) => {
599
+ const batchTask = this.workerQueue.enqueue(
600
+ {
601
+ execute: () => this.executor.searchBatch(doc, chunkPages, keyword, flags),
602
+ meta: { docId: doc.id, operation: "searchBatch", chunkSize: chunkPages.length }
603
+ },
604
+ { priority: Priority.LOW }
605
+ );
606
+ batchTask.onProgress((batchProgress) => {
607
+ compound.progress({
608
+ page: batchProgress.pageIndex,
609
+ results: batchProgress.result
610
+ });
611
+ });
612
+ compound.addChild(batchTask, chunkIndex);
613
+ });
614
+ compound.finalize();
615
+ return compound;
616
+ }
617
+ // ========== Attachments ==========
618
+ getAttachments(doc) {
619
+ return this.workerQueue.enqueue(
620
+ {
621
+ execute: () => this.executor.getAttachments(doc),
622
+ meta: { docId: doc.id, operation: "getAttachments" }
623
+ },
624
+ { priority: Priority.MEDIUM }
625
+ );
626
+ }
627
+ addAttachment(doc, params) {
628
+ return this.workerQueue.enqueue(
629
+ {
630
+ execute: () => this.executor.addAttachment(doc, params),
631
+ meta: { docId: doc.id, operation: "addAttachment" }
632
+ },
633
+ { priority: Priority.MEDIUM }
634
+ );
635
+ }
636
+ removeAttachment(doc, attachment) {
637
+ return this.workerQueue.enqueue(
638
+ {
639
+ execute: () => this.executor.removeAttachment(doc, attachment),
640
+ meta: { docId: doc.id, operation: "removeAttachment" }
641
+ },
642
+ { priority: Priority.MEDIUM }
643
+ );
644
+ }
645
+ readAttachmentContent(doc, attachment) {
646
+ return this.workerQueue.enqueue(
647
+ {
648
+ execute: () => this.executor.readAttachmentContent(doc, attachment),
649
+ meta: { docId: doc.id, operation: "readAttachmentContent" }
650
+ },
651
+ { priority: Priority.MEDIUM }
652
+ );
653
+ }
654
+ // ========== Forms ==========
655
+ setFormFieldValue(doc, page, annotation, value) {
656
+ return this.workerQueue.enqueue(
657
+ {
658
+ execute: () => this.executor.setFormFieldValue(doc, page, annotation, value),
659
+ meta: { docId: doc.id, pageIndex: page.index, operation: "setFormFieldValue" }
660
+ },
661
+ { priority: Priority.MEDIUM }
662
+ );
663
+ }
664
+ flattenPage(doc, page, options) {
665
+ return this.workerQueue.enqueue(
666
+ {
667
+ execute: () => this.executor.flattenPage(doc, page, options),
668
+ meta: { docId: doc.id, pageIndex: page.index, operation: "flattenPage" }
669
+ },
670
+ { priority: Priority.MEDIUM }
671
+ );
672
+ }
673
+ // ========== Text Operations ==========
674
+ extractPages(doc, pageIndexes) {
675
+ return this.workerQueue.enqueue(
676
+ {
677
+ execute: () => this.executor.extractPages(doc, pageIndexes),
678
+ meta: { docId: doc.id, pageIndexes, operation: "extractPages" }
679
+ },
680
+ { priority: Priority.MEDIUM }
681
+ );
682
+ }
683
+ extractText(doc, pageIndexes) {
684
+ return this.workerQueue.enqueue(
685
+ {
686
+ execute: () => this.executor.extractText(doc, pageIndexes),
687
+ meta: { docId: doc.id, pageIndexes, operation: "extractText" }
688
+ },
689
+ { priority: Priority.MEDIUM }
690
+ );
691
+ }
692
+ redactTextInRects(doc, page, rects, options) {
693
+ return this.workerQueue.enqueue(
694
+ {
695
+ execute: () => this.executor.redactTextInRects(doc, page, rects, options),
696
+ meta: { docId: doc.id, pageIndex: page.index, operation: "redactTextInRects" }
697
+ },
698
+ { priority: Priority.MEDIUM }
699
+ );
700
+ }
701
+ getTextSlices(doc, slices) {
702
+ return this.workerQueue.enqueue(
703
+ {
704
+ execute: () => this.executor.getTextSlices(doc, slices),
705
+ meta: { docId: doc.id, slices, operation: "getTextSlices" }
706
+ },
707
+ { priority: Priority.MEDIUM }
708
+ );
709
+ }
710
+ getPageGlyphs(doc, page) {
711
+ return this.workerQueue.enqueue(
712
+ {
713
+ execute: () => this.executor.getPageGlyphs(doc, page),
714
+ meta: { docId: doc.id, pageIndex: page.index, operation: "getPageGlyphs" }
715
+ },
716
+ { priority: Priority.MEDIUM }
717
+ );
718
+ }
719
+ getPageGeometry(doc, page) {
720
+ return this.workerQueue.enqueue(
721
+ {
722
+ execute: () => this.executor.getPageGeometry(doc, page),
723
+ meta: { docId: doc.id, pageIndex: page.index, operation: "getPageGeometry" }
724
+ },
725
+ { priority: Priority.MEDIUM }
726
+ );
727
+ }
728
+ // ========== Document Operations ==========
729
+ merge(files) {
730
+ return this.workerQueue.enqueue(
731
+ {
732
+ execute: () => this.executor.merge(files),
733
+ meta: { docId: files.map((file) => file.id).join(","), operation: "merge" }
734
+ },
735
+ { priority: Priority.MEDIUM }
736
+ );
737
+ }
738
+ mergePages(mergeConfigs) {
739
+ return this.workerQueue.enqueue(
740
+ {
741
+ execute: () => this.executor.mergePages(mergeConfigs),
742
+ meta: {
743
+ docId: mergeConfigs.map((config) => config.docId).join(","),
744
+ operation: "mergePages"
745
+ }
746
+ },
747
+ { priority: Priority.MEDIUM }
748
+ );
749
+ }
750
+ preparePrintDocument(doc, options) {
751
+ return this.workerQueue.enqueue(
752
+ {
753
+ execute: () => this.executor.preparePrintDocument(doc, options),
754
+ meta: { docId: doc.id, operation: "preparePrintDocument" }
755
+ },
756
+ { priority: Priority.MEDIUM }
757
+ );
758
+ }
759
+ saveAsCopy(doc) {
760
+ return this.workerQueue.enqueue(
761
+ {
762
+ execute: () => this.executor.saveAsCopy(doc),
763
+ meta: { docId: doc.id, operation: "saveAsCopy" }
764
+ },
765
+ { priority: Priority.MEDIUM }
766
+ );
767
+ }
768
+ closeDocument(doc) {
769
+ return this.workerQueue.enqueue(
770
+ {
771
+ execute: () => this.executor.closeDocument(doc),
772
+ meta: { docId: doc.id, operation: "closeDocument" }
773
+ },
774
+ { priority: Priority.MEDIUM }
775
+ );
776
+ }
777
+ closeAllDocuments() {
778
+ return this.workerQueue.enqueue(
779
+ {
780
+ execute: () => this.executor.closeAllDocuments(),
781
+ meta: { operation: "closeAllDocuments" }
782
+ },
783
+ { priority: Priority.MEDIUM }
784
+ );
785
+ }
786
+ }
787
+ export {
788
+ PdfEngine as P
789
+ };
790
+ //# sourceMappingURL=pdf-engine-BVNF_Yo9.js.map