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