canvu-react 0.4.74 → 0.4.75
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/dist/index.cjs +402 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +402 -25
- package/dist/index.js.map +1 -1
- package/dist/pdf.mjs +28 -0
- package/dist/pdf.worker.mjs +31 -0
- package/dist/react.cjs +414 -37
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +414 -37
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -210,6 +210,342 @@ var IndexedDbImageStore = class {
|
|
|
210
210
|
}
|
|
211
211
|
};
|
|
212
212
|
|
|
213
|
+
// src/image/pdf-worker-renderer.ts
|
|
214
|
+
var PDF_WORKER_SOURCE = `
|
|
215
|
+
let pdfjsPromise = null;
|
|
216
|
+
|
|
217
|
+
const loadPdfJs = async (pdfjsModuleCandidates) => {
|
|
218
|
+
if (!pdfjsPromise) {
|
|
219
|
+
pdfjsPromise = (async () => {
|
|
220
|
+
let lastError;
|
|
221
|
+
for (const candidate of pdfjsModuleCandidates) {
|
|
222
|
+
try {
|
|
223
|
+
const pdfjs = await import(candidate.moduleUrl);
|
|
224
|
+
if (pdfjs.GlobalWorkerOptions) {
|
|
225
|
+
pdfjs.GlobalWorkerOptions.workerSrc = candidate.workerUrl;
|
|
226
|
+
}
|
|
227
|
+
return pdfjs;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
lastError = error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
throw lastError ?? new Error("Unable to load pdfjs-dist");
|
|
233
|
+
})();
|
|
234
|
+
}
|
|
235
|
+
return await pdfjsPromise;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
const createErrorPayload = (error) => ({
|
|
239
|
+
message: error instanceof Error ? error.message : String(error),
|
|
240
|
+
name: error instanceof Error ? error.name : "Error",
|
|
241
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const normalizePdfPageNumbers = (pageNumbers, pageCount) => {
|
|
245
|
+
if (!Array.isArray(pageNumbers) || pageNumbers.length === 0) {
|
|
246
|
+
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
247
|
+
}
|
|
248
|
+
return [...new Set(pageNumbers)]
|
|
249
|
+
.filter((pageNumber) => pageNumber >= 1 && pageNumber <= pageCount)
|
|
250
|
+
.sort((left, right) => left - right);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const runWithConcurrency = async (items, concurrency, execute) => {
|
|
254
|
+
const results = new Array(items.length);
|
|
255
|
+
let nextIndex = 0;
|
|
256
|
+
const safeConcurrency = Number.isFinite(concurrency) && concurrency > 0
|
|
257
|
+
? Math.round(concurrency)
|
|
258
|
+
: 1;
|
|
259
|
+
const workerCount = Math.max(1, Math.min(safeConcurrency, items.length));
|
|
260
|
+
await Promise.all(
|
|
261
|
+
Array.from({ length: workerCount }, async () => {
|
|
262
|
+
while (nextIndex < items.length) {
|
|
263
|
+
const currentIndex = nextIndex;
|
|
264
|
+
nextIndex += 1;
|
|
265
|
+
const item = items[currentIndex];
|
|
266
|
+
if (item === undefined) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
results[currentIndex] = await execute(item);
|
|
270
|
+
}
|
|
271
|
+
}),
|
|
272
|
+
);
|
|
273
|
+
return results;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const renderPageToBlob = async (page, scale, storeThumbnails) => {
|
|
277
|
+
const raw = page.getViewport({ scale: 1 });
|
|
278
|
+
const adjustedScale = Math.round(raw.width * scale) / raw.width;
|
|
279
|
+
const viewport = page.getViewport({ scale: adjustedScale });
|
|
280
|
+
const width = Math.round(viewport.width);
|
|
281
|
+
const height = Math.round(viewport.height);
|
|
282
|
+
const canvas = new OffscreenCanvas(width, height);
|
|
283
|
+
const canvasContext = canvas.getContext("2d");
|
|
284
|
+
if (!canvasContext) {
|
|
285
|
+
throw new Error("OffscreenCanvas 2D context unavailable");
|
|
286
|
+
}
|
|
287
|
+
canvasContext.imageSmoothingEnabled = true;
|
|
288
|
+
canvasContext.imageSmoothingQuality = "high";
|
|
289
|
+
await page.render({ canvasContext, viewport }).promise;
|
|
290
|
+
const blob = await canvas.convertToBlob({ type: "image/png" });
|
|
291
|
+
let thumbnailBlob;
|
|
292
|
+
if (storeThumbnails) {
|
|
293
|
+
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
294
|
+
const thumbnailWidth = Math.max(1, Math.round(width * thumbScale));
|
|
295
|
+
const thumbnailHeight = Math.max(1, Math.round(height * thumbScale));
|
|
296
|
+
const thumbnailCanvas = new OffscreenCanvas(thumbnailWidth, thumbnailHeight);
|
|
297
|
+
const thumbnailContext = thumbnailCanvas.getContext("2d");
|
|
298
|
+
if (thumbnailContext) {
|
|
299
|
+
thumbnailContext.imageSmoothingEnabled = true;
|
|
300
|
+
thumbnailContext.imageSmoothingQuality = "high";
|
|
301
|
+
thumbnailContext.drawImage(canvas, 0, 0, thumbnailWidth, thumbnailHeight);
|
|
302
|
+
}
|
|
303
|
+
thumbnailBlob = await thumbnailCanvas.convertToBlob({ type: "image/png" });
|
|
304
|
+
}
|
|
305
|
+
return { blob, height, thumbnailBlob, width };
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
self.onmessage = async (event) => {
|
|
309
|
+
const message = event.data;
|
|
310
|
+
if (!message || message.type !== "render") {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
try {
|
|
314
|
+
const pdfjs = await loadPdfJs(message.pdfjsModuleCandidates);
|
|
315
|
+
const pdf = await pdfjs.getDocument({
|
|
316
|
+
data: new Uint8Array(message.pdfData),
|
|
317
|
+
disableWorker: true,
|
|
318
|
+
}).promise;
|
|
319
|
+
try {
|
|
320
|
+
const pageNumbers = normalizePdfPageNumbers(message.pageNumbers, pdf.numPages);
|
|
321
|
+
const bufferedPages = new Map();
|
|
322
|
+
let nextEmitIndex = 0;
|
|
323
|
+
let emitChain = Promise.resolve();
|
|
324
|
+
const emitPageInOrder = async (pageNumber, renderedPage) => {
|
|
325
|
+
bufferedPages.set(pageNumber, renderedPage);
|
|
326
|
+
const flush = () => {
|
|
327
|
+
while (nextEmitIndex < pageNumbers.length) {
|
|
328
|
+
const nextPageNumber = pageNumbers[nextEmitIndex];
|
|
329
|
+
if (nextPageNumber == null) break;
|
|
330
|
+
const nextPage = bufferedPages.get(nextPageNumber);
|
|
331
|
+
if (!nextPage) break;
|
|
332
|
+
bufferedPages.delete(nextPageNumber);
|
|
333
|
+
nextEmitIndex += 1;
|
|
334
|
+
self.postMessage({
|
|
335
|
+
type: "page",
|
|
336
|
+
page: {
|
|
337
|
+
...nextPage,
|
|
338
|
+
pageNumber: nextPageNumber,
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
const nextChain = emitChain.then(flush, flush);
|
|
344
|
+
emitChain = nextChain.catch(() => {});
|
|
345
|
+
await nextChain;
|
|
346
|
+
};
|
|
347
|
+
await runWithConcurrency(
|
|
348
|
+
pageNumbers,
|
|
349
|
+
message.pageConcurrency,
|
|
350
|
+
async (pageNumber) => {
|
|
351
|
+
const page = await pdf.getPage(pageNumber);
|
|
352
|
+
try {
|
|
353
|
+
const renderedPage = await renderPageToBlob(
|
|
354
|
+
page,
|
|
355
|
+
message.scale,
|
|
356
|
+
message.storeThumbnails,
|
|
357
|
+
);
|
|
358
|
+
await emitPageInOrder(pageNumber, renderedPage);
|
|
359
|
+
} finally {
|
|
360
|
+
page.cleanup();
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
);
|
|
364
|
+
await emitChain;
|
|
365
|
+
} finally {
|
|
366
|
+
await pdf.destroy();
|
|
367
|
+
}
|
|
368
|
+
self.postMessage({ type: "done" });
|
|
369
|
+
} catch (error) {
|
|
370
|
+
self.postMessage({ type: "error", error: createErrorPayload(error) });
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
`;
|
|
374
|
+
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
375
|
+
var hasObjectMembers = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
376
|
+
var isOffscreenCanvasCandidate = (value) => typeof value === "function";
|
|
377
|
+
var getEnvironmentRecord = (environment) => isRecord(environment) ? environment : null;
|
|
378
|
+
var canUsePdfWorkerRenderer = (environment = globalThis) => {
|
|
379
|
+
const candidateEnvironment = getEnvironmentRecord(environment);
|
|
380
|
+
if (!candidateEnvironment) return false;
|
|
381
|
+
if (typeof candidateEnvironment.Worker !== "function") return false;
|
|
382
|
+
if (typeof candidateEnvironment.Blob !== "function") return false;
|
|
383
|
+
if (!isOffscreenCanvasCandidate(candidateEnvironment.OffscreenCanvas)) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
const urlCandidate = candidateEnvironment.URL;
|
|
387
|
+
if (!hasObjectMembers(urlCandidate)) return false;
|
|
388
|
+
if (typeof urlCandidate.createObjectURL !== "function") return false;
|
|
389
|
+
if (typeof urlCandidate.revokeObjectURL !== "function") return false;
|
|
390
|
+
try {
|
|
391
|
+
const canvas = new candidateEnvironment.OffscreenCanvas(1, 1);
|
|
392
|
+
return typeof canvas.getContext === "function" && typeof canvas.convertToBlob === "function";
|
|
393
|
+
} catch {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
var createAbortError = () => new DOMException("Aborted", "AbortError");
|
|
398
|
+
var throwIfAborted = (signal) => {
|
|
399
|
+
if (signal?.aborted) {
|
|
400
|
+
throw createAbortError();
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
var createPdfWorker = () => {
|
|
404
|
+
const workerBlob = new Blob([PDF_WORKER_SOURCE], {
|
|
405
|
+
type: "text/javascript"
|
|
406
|
+
});
|
|
407
|
+
const workerUrl = URL.createObjectURL(workerBlob);
|
|
408
|
+
try {
|
|
409
|
+
const worker = new Worker(workerUrl, {
|
|
410
|
+
name: "canvu-pdf-renderer",
|
|
411
|
+
type: "module"
|
|
412
|
+
});
|
|
413
|
+
return {
|
|
414
|
+
release: () => URL.revokeObjectURL(workerUrl),
|
|
415
|
+
worker
|
|
416
|
+
};
|
|
417
|
+
} catch (error) {
|
|
418
|
+
URL.revokeObjectURL(workerUrl);
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
var createWorkerError = (message) => {
|
|
423
|
+
const error = new Error(message.error.message);
|
|
424
|
+
error.name = message.error.name;
|
|
425
|
+
error.stack = message.error.stack;
|
|
426
|
+
return error;
|
|
427
|
+
};
|
|
428
|
+
var PACKAGED_PDFJS_MODULE_FILE = "./pdf.mjs";
|
|
429
|
+
var PACKAGED_PDFJS_WORKER_FILE = "./pdf.worker.mjs";
|
|
430
|
+
var resolveRelativeAssetUrl = (path, baseUrl) => new URL(path, baseUrl).toString();
|
|
431
|
+
var resolvePackagedPdfJsModuleCandidate = (baseUrl = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))) => ({
|
|
432
|
+
moduleUrl: resolveRelativeAssetUrl(PACKAGED_PDFJS_MODULE_FILE, baseUrl),
|
|
433
|
+
workerUrl: resolveRelativeAssetUrl(PACKAGED_PDFJS_WORKER_FILE, baseUrl)
|
|
434
|
+
});
|
|
435
|
+
var resolveBundledPdfJsModuleCandidate = () => ({
|
|
436
|
+
moduleUrl: new URL("pdfjs-dist/build/pdf.min.mjs", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))).toString(),
|
|
437
|
+
workerUrl: new URL(
|
|
438
|
+
"pdfjs-dist/build/pdf.worker.min.mjs",
|
|
439
|
+
(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))
|
|
440
|
+
).toString()
|
|
441
|
+
});
|
|
442
|
+
var resolvePdfJsModuleCandidates = () => [
|
|
443
|
+
resolvePackagedPdfJsModuleCandidate(),
|
|
444
|
+
resolveBundledPdfJsModuleCandidate()
|
|
445
|
+
];
|
|
446
|
+
var loadPdfToStoreWithWorker = async (file, store, options) => {
|
|
447
|
+
throwIfAborted(options.signal);
|
|
448
|
+
const arrayBuffer = await file.arrayBuffer();
|
|
449
|
+
throwIfAborted(options.signal);
|
|
450
|
+
return await new Promise((resolve, reject) => {
|
|
451
|
+
const { release, worker } = createPdfWorker();
|
|
452
|
+
const pageResults = [];
|
|
453
|
+
let storeChain = Promise.resolve();
|
|
454
|
+
let cleanedUp = false;
|
|
455
|
+
let settled = false;
|
|
456
|
+
const cleanup = () => {
|
|
457
|
+
if (cleanedUp) return;
|
|
458
|
+
cleanedUp = true;
|
|
459
|
+
options.signal?.removeEventListener("abort", abortWorker);
|
|
460
|
+
worker.onmessage = null;
|
|
461
|
+
worker.onerror = null;
|
|
462
|
+
worker.terminate();
|
|
463
|
+
release();
|
|
464
|
+
};
|
|
465
|
+
const rejectOnce = (error) => {
|
|
466
|
+
if (settled) return;
|
|
467
|
+
settled = true;
|
|
468
|
+
cleanup();
|
|
469
|
+
reject(error);
|
|
470
|
+
};
|
|
471
|
+
const rejectAfterQueuedStores = (error) => {
|
|
472
|
+
if (settled) return;
|
|
473
|
+
cleanup();
|
|
474
|
+
storeChain.then(() => {
|
|
475
|
+
if (settled) return;
|
|
476
|
+
settled = true;
|
|
477
|
+
reject(error);
|
|
478
|
+
}).catch(rejectOnce);
|
|
479
|
+
};
|
|
480
|
+
function abortWorker() {
|
|
481
|
+
rejectOnce(createAbortError());
|
|
482
|
+
}
|
|
483
|
+
const storePage = (message) => {
|
|
484
|
+
try {
|
|
485
|
+
options.onPageReceived?.({ pageNumber: message.page.pageNumber });
|
|
486
|
+
} catch (error) {
|
|
487
|
+
rejectOnce(error);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
storeChain = storeChain.then(async () => {
|
|
491
|
+
throwIfAborted(options.signal);
|
|
492
|
+
const blobId = await store.storeOriginal(message.page.blob);
|
|
493
|
+
throwIfAborted(options.signal);
|
|
494
|
+
const thumbnailBlobId = options.storeThumbnails && message.page.thumbnailBlob ? await store.storeThumbnail(message.page.thumbnailBlob) : "";
|
|
495
|
+
throwIfAborted(options.signal);
|
|
496
|
+
const pageResult = {
|
|
497
|
+
blobId,
|
|
498
|
+
height: message.page.height,
|
|
499
|
+
pageNumber: message.page.pageNumber,
|
|
500
|
+
thumbnailBlobId,
|
|
501
|
+
width: message.page.width
|
|
502
|
+
};
|
|
503
|
+
pageResults.push(pageResult);
|
|
504
|
+
await options.onPageStored?.(pageResult);
|
|
505
|
+
throwIfAborted(options.signal);
|
|
506
|
+
});
|
|
507
|
+
void storeChain.catch(rejectOnce);
|
|
508
|
+
};
|
|
509
|
+
worker.onmessage = (event) => {
|
|
510
|
+
const message = event.data;
|
|
511
|
+
if (message.type === "page") {
|
|
512
|
+
storePage(message);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (message.type === "error") {
|
|
516
|
+
rejectAfterQueuedStores(createWorkerError(message));
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
storeChain.then(() => {
|
|
520
|
+
if (settled) return;
|
|
521
|
+
settled = true;
|
|
522
|
+
cleanup();
|
|
523
|
+
resolve(pageResults);
|
|
524
|
+
}).catch(rejectOnce);
|
|
525
|
+
};
|
|
526
|
+
worker.onerror = (event) => {
|
|
527
|
+
rejectAfterQueuedStores(event.error ?? new Error(event.message));
|
|
528
|
+
};
|
|
529
|
+
options.signal?.addEventListener("abort", abortWorker, { once: true });
|
|
530
|
+
try {
|
|
531
|
+
worker.postMessage(
|
|
532
|
+
{
|
|
533
|
+
pdfData: arrayBuffer,
|
|
534
|
+
pdfjsModuleCandidates: resolvePdfJsModuleCandidates(),
|
|
535
|
+
pageNumbers: options.pageNumbers ? [...options.pageNumbers] : void 0,
|
|
536
|
+
pageConcurrency: options.pageConcurrency,
|
|
537
|
+
scale: options.scale,
|
|
538
|
+
storeThumbnails: options.storeThumbnails,
|
|
539
|
+
type: "render"
|
|
540
|
+
},
|
|
541
|
+
[arrayBuffer]
|
|
542
|
+
);
|
|
543
|
+
} catch (error) {
|
|
544
|
+
rejectOnce(error);
|
|
545
|
+
}
|
|
546
|
+
});
|
|
547
|
+
};
|
|
548
|
+
|
|
213
549
|
// src/image/pdf-loader.ts
|
|
214
550
|
var pdfjsPromise = null;
|
|
215
551
|
function getPdfJs() {
|
|
@@ -226,7 +562,7 @@ function getPdfJs() {
|
|
|
226
562
|
return pdfjsPromise;
|
|
227
563
|
}
|
|
228
564
|
async function renderPageToCanvas(page, scale, signal) {
|
|
229
|
-
|
|
565
|
+
throwIfAborted2(signal);
|
|
230
566
|
const raw = page.getViewport({ scale: 1 });
|
|
231
567
|
const adjustedScale = Math.round(raw.width * scale) / raw.width;
|
|
232
568
|
const viewport = page.getViewport({ scale: adjustedScale });
|
|
@@ -248,7 +584,7 @@ async function renderPageToCanvas(page, scale, signal) {
|
|
|
248
584
|
try {
|
|
249
585
|
await renderTask.promise;
|
|
250
586
|
} catch (error) {
|
|
251
|
-
if (signal.aborted) throw
|
|
587
|
+
if (signal.aborted) throw createAbortError2();
|
|
252
588
|
throw error;
|
|
253
589
|
} finally {
|
|
254
590
|
signal.removeEventListener("abort", abortRender);
|
|
@@ -256,15 +592,15 @@ async function renderPageToCanvas(page, scale, signal) {
|
|
|
256
592
|
} else {
|
|
257
593
|
await renderTask.promise;
|
|
258
594
|
}
|
|
259
|
-
|
|
595
|
+
throwIfAborted2(signal);
|
|
260
596
|
return { canvas, width: w, height: h };
|
|
261
597
|
}
|
|
262
|
-
function
|
|
598
|
+
function createAbortError2() {
|
|
263
599
|
return new DOMException("Aborted", "AbortError");
|
|
264
600
|
}
|
|
265
|
-
function
|
|
601
|
+
function throwIfAborted2(signal) {
|
|
266
602
|
if (signal?.aborted) {
|
|
267
|
-
throw
|
|
603
|
+
throw createAbortError2();
|
|
268
604
|
}
|
|
269
605
|
}
|
|
270
606
|
function normalizePdfPageNumbers(pageNumbers, pageCount) {
|
|
@@ -280,7 +616,7 @@ async function runWithConcurrency(items, concurrency, execute, signal) {
|
|
|
280
616
|
await Promise.all(
|
|
281
617
|
Array.from({ length: workerCount }, async () => {
|
|
282
618
|
while (nextIndex < items.length) {
|
|
283
|
-
|
|
619
|
+
throwIfAborted2(signal);
|
|
284
620
|
const currentIndex = nextIndex;
|
|
285
621
|
nextIndex += 1;
|
|
286
622
|
const item = items[currentIndex];
|
|
@@ -288,7 +624,7 @@ async function runWithConcurrency(items, concurrency, execute, signal) {
|
|
|
288
624
|
continue;
|
|
289
625
|
}
|
|
290
626
|
results[currentIndex] = await execute(item);
|
|
291
|
-
|
|
627
|
+
throwIfAborted2(signal);
|
|
292
628
|
}
|
|
293
629
|
})
|
|
294
630
|
);
|
|
@@ -299,11 +635,52 @@ async function loadPdfToStore(file, store, options) {
|
|
|
299
635
|
const pageConcurrency = options?.pageConcurrency ?? 2;
|
|
300
636
|
const storeThumbnails = options?.storeThumbnails ?? false;
|
|
301
637
|
const signal = options?.signal;
|
|
302
|
-
|
|
638
|
+
throwIfAborted2(signal);
|
|
639
|
+
if (canUsePdfWorkerRenderer()) {
|
|
640
|
+
let workerPageCount = 0;
|
|
641
|
+
try {
|
|
642
|
+
return await loadPdfToStoreWithWorker(file, store, {
|
|
643
|
+
scale,
|
|
644
|
+
pageNumbers: options?.pageNumbers,
|
|
645
|
+
pageConcurrency,
|
|
646
|
+
storeThumbnails,
|
|
647
|
+
signal,
|
|
648
|
+
onPageReceived: () => {
|
|
649
|
+
workerPageCount += 1;
|
|
650
|
+
},
|
|
651
|
+
onPageStored: async (page) => {
|
|
652
|
+
await options?.onPageStored?.(page);
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
} catch (error) {
|
|
656
|
+
if (signal?.aborted || workerPageCount > 0) {
|
|
657
|
+
throw error;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
return await loadPdfToStoreOnMainThread(file, store, {
|
|
662
|
+
scale,
|
|
663
|
+
pageNumbers: options?.pageNumbers,
|
|
664
|
+
pageConcurrency,
|
|
665
|
+
storeThumbnails,
|
|
666
|
+
signal,
|
|
667
|
+
onPageStored: options?.onPageStored
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
async function loadPdfToStoreOnMainThread(file, store, options) {
|
|
671
|
+
const {
|
|
672
|
+
pageConcurrency,
|
|
673
|
+
scale,
|
|
674
|
+
signal,
|
|
675
|
+
storeThumbnails,
|
|
676
|
+
onPageStored,
|
|
677
|
+
pageNumbers
|
|
678
|
+
} = options;
|
|
679
|
+
throwIfAborted2(signal);
|
|
303
680
|
const pdfjs = await getPdfJs();
|
|
304
|
-
|
|
681
|
+
throwIfAborted2(signal);
|
|
305
682
|
const arrayBuffer = await file.arrayBuffer();
|
|
306
|
-
|
|
683
|
+
throwIfAborted2(signal);
|
|
307
684
|
const loadingTask = pdfjs.getDocument({ data: arrayBuffer });
|
|
308
685
|
if (signal) {
|
|
309
686
|
const abortLoading = () => {
|
|
@@ -315,14 +692,14 @@ async function loadPdfToStore(file, store, options) {
|
|
|
315
692
|
signal.removeEventListener("abort", abortLoading);
|
|
316
693
|
return await loadPdfDocumentToStore(pdf2, store, {
|
|
317
694
|
scale,
|
|
318
|
-
pageNumbers
|
|
695
|
+
pageNumbers,
|
|
319
696
|
pageConcurrency,
|
|
320
697
|
storeThumbnails,
|
|
321
698
|
signal,
|
|
322
|
-
onPageStored
|
|
699
|
+
onPageStored
|
|
323
700
|
});
|
|
324
701
|
} catch (error) {
|
|
325
|
-
if (signal.aborted) throw
|
|
702
|
+
if (signal.aborted) throw createAbortError2();
|
|
326
703
|
throw error;
|
|
327
704
|
} finally {
|
|
328
705
|
signal.removeEventListener("abort", abortLoading);
|
|
@@ -331,16 +708,16 @@ async function loadPdfToStore(file, store, options) {
|
|
|
331
708
|
const pdf = await loadingTask.promise;
|
|
332
709
|
return await loadPdfDocumentToStore(pdf, store, {
|
|
333
710
|
scale,
|
|
334
|
-
pageNumbers
|
|
711
|
+
pageNumbers,
|
|
335
712
|
pageConcurrency,
|
|
336
713
|
storeThumbnails,
|
|
337
|
-
onPageStored
|
|
714
|
+
onPageStored
|
|
338
715
|
});
|
|
339
716
|
}
|
|
340
717
|
async function loadPdfDocumentToStore(pdf, store, options) {
|
|
341
718
|
const { pageConcurrency, scale, signal } = options;
|
|
342
719
|
const storeThumbnails = options.storeThumbnails ?? false;
|
|
343
|
-
|
|
720
|
+
throwIfAborted2(signal);
|
|
344
721
|
const pageNumbers = normalizePdfPageNumbers(options?.pageNumbers, pdf.numPages);
|
|
345
722
|
const bufferedResults = /* @__PURE__ */ new Map();
|
|
346
723
|
let nextEmitIndex = 0;
|
|
@@ -355,9 +732,9 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
355
732
|
if (!bufferedResult) break;
|
|
356
733
|
bufferedResults.delete(nextPageNumber);
|
|
357
734
|
nextEmitIndex += 1;
|
|
358
|
-
|
|
735
|
+
throwIfAborted2(signal);
|
|
359
736
|
await options?.onPageStored?.(bufferedResult);
|
|
360
|
-
|
|
737
|
+
throwIfAborted2(signal);
|
|
361
738
|
}
|
|
362
739
|
};
|
|
363
740
|
const nextChain = emitChain.then(run, run);
|
|
@@ -369,20 +746,20 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
369
746
|
pageNumbers,
|
|
370
747
|
pageConcurrency,
|
|
371
748
|
async (pageNumber) => {
|
|
372
|
-
|
|
749
|
+
throwIfAborted2(signal);
|
|
373
750
|
const page = await pdf.getPage(pageNumber);
|
|
374
|
-
|
|
751
|
+
throwIfAborted2(signal);
|
|
375
752
|
const { canvas, width, height } = await renderPageToCanvas(
|
|
376
753
|
page,
|
|
377
754
|
scale,
|
|
378
755
|
signal
|
|
379
756
|
);
|
|
380
|
-
|
|
757
|
+
throwIfAborted2(signal);
|
|
381
758
|
const mime = "image/png";
|
|
382
759
|
const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
|
|
383
|
-
|
|
760
|
+
throwIfAborted2(signal);
|
|
384
761
|
const blobId = await store.storeOriginal(pageBlob);
|
|
385
|
-
|
|
762
|
+
throwIfAborted2(signal);
|
|
386
763
|
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
387
764
|
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
388
765
|
const tw = Math.max(1, Math.round(width * thumbScale));
|
|
@@ -399,7 +776,7 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
399
776
|
const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
|
|
400
777
|
mimeType: mime
|
|
401
778
|
});
|
|
402
|
-
|
|
779
|
+
throwIfAborted2(signal);
|
|
403
780
|
return await store.storeThumbnail(thumbBlob);
|
|
404
781
|
})() : "";
|
|
405
782
|
const pageResult = {
|