canvu-react 0.4.75 → 0.4.76
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 +40 -414
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +40 -414
- 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/react.js
CHANGED
|
@@ -1186,342 +1186,6 @@ async function createThumbnailBlobUrlFromStore(store, thumbnailBlobId) {
|
|
|
1186
1186
|
return URL.createObjectURL(blob);
|
|
1187
1187
|
}
|
|
1188
1188
|
|
|
1189
|
-
// src/image/pdf-worker-renderer.ts
|
|
1190
|
-
var PDF_WORKER_SOURCE = `
|
|
1191
|
-
let pdfjsPromise = null;
|
|
1192
|
-
|
|
1193
|
-
const loadPdfJs = async (pdfjsModuleCandidates) => {
|
|
1194
|
-
if (!pdfjsPromise) {
|
|
1195
|
-
pdfjsPromise = (async () => {
|
|
1196
|
-
let lastError;
|
|
1197
|
-
for (const candidate of pdfjsModuleCandidates) {
|
|
1198
|
-
try {
|
|
1199
|
-
const pdfjs = await import(candidate.moduleUrl);
|
|
1200
|
-
if (pdfjs.GlobalWorkerOptions) {
|
|
1201
|
-
pdfjs.GlobalWorkerOptions.workerSrc = candidate.workerUrl;
|
|
1202
|
-
}
|
|
1203
|
-
return pdfjs;
|
|
1204
|
-
} catch (error) {
|
|
1205
|
-
lastError = error;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
throw lastError ?? new Error("Unable to load pdfjs-dist");
|
|
1209
|
-
})();
|
|
1210
|
-
}
|
|
1211
|
-
return await pdfjsPromise;
|
|
1212
|
-
};
|
|
1213
|
-
|
|
1214
|
-
const createErrorPayload = (error) => ({
|
|
1215
|
-
message: error instanceof Error ? error.message : String(error),
|
|
1216
|
-
name: error instanceof Error ? error.name : "Error",
|
|
1217
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
1218
|
-
});
|
|
1219
|
-
|
|
1220
|
-
const normalizePdfPageNumbers = (pageNumbers, pageCount) => {
|
|
1221
|
-
if (!Array.isArray(pageNumbers) || pageNumbers.length === 0) {
|
|
1222
|
-
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
1223
|
-
}
|
|
1224
|
-
return [...new Set(pageNumbers)]
|
|
1225
|
-
.filter((pageNumber) => pageNumber >= 1 && pageNumber <= pageCount)
|
|
1226
|
-
.sort((left, right) => left - right);
|
|
1227
|
-
};
|
|
1228
|
-
|
|
1229
|
-
const runWithConcurrency = async (items, concurrency, execute) => {
|
|
1230
|
-
const results = new Array(items.length);
|
|
1231
|
-
let nextIndex = 0;
|
|
1232
|
-
const safeConcurrency = Number.isFinite(concurrency) && concurrency > 0
|
|
1233
|
-
? Math.round(concurrency)
|
|
1234
|
-
: 1;
|
|
1235
|
-
const workerCount = Math.max(1, Math.min(safeConcurrency, items.length));
|
|
1236
|
-
await Promise.all(
|
|
1237
|
-
Array.from({ length: workerCount }, async () => {
|
|
1238
|
-
while (nextIndex < items.length) {
|
|
1239
|
-
const currentIndex = nextIndex;
|
|
1240
|
-
nextIndex += 1;
|
|
1241
|
-
const item = items[currentIndex];
|
|
1242
|
-
if (item === undefined) {
|
|
1243
|
-
continue;
|
|
1244
|
-
}
|
|
1245
|
-
results[currentIndex] = await execute(item);
|
|
1246
|
-
}
|
|
1247
|
-
}),
|
|
1248
|
-
);
|
|
1249
|
-
return results;
|
|
1250
|
-
};
|
|
1251
|
-
|
|
1252
|
-
const renderPageToBlob = async (page, scale, storeThumbnails) => {
|
|
1253
|
-
const raw = page.getViewport({ scale: 1 });
|
|
1254
|
-
const adjustedScale = Math.round(raw.width * scale) / raw.width;
|
|
1255
|
-
const viewport = page.getViewport({ scale: adjustedScale });
|
|
1256
|
-
const width = Math.round(viewport.width);
|
|
1257
|
-
const height = Math.round(viewport.height);
|
|
1258
|
-
const canvas = new OffscreenCanvas(width, height);
|
|
1259
|
-
const canvasContext = canvas.getContext("2d");
|
|
1260
|
-
if (!canvasContext) {
|
|
1261
|
-
throw new Error("OffscreenCanvas 2D context unavailable");
|
|
1262
|
-
}
|
|
1263
|
-
canvasContext.imageSmoothingEnabled = true;
|
|
1264
|
-
canvasContext.imageSmoothingQuality = "high";
|
|
1265
|
-
await page.render({ canvasContext, viewport }).promise;
|
|
1266
|
-
const blob = await canvas.convertToBlob({ type: "image/png" });
|
|
1267
|
-
let thumbnailBlob;
|
|
1268
|
-
if (storeThumbnails) {
|
|
1269
|
-
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
1270
|
-
const thumbnailWidth = Math.max(1, Math.round(width * thumbScale));
|
|
1271
|
-
const thumbnailHeight = Math.max(1, Math.round(height * thumbScale));
|
|
1272
|
-
const thumbnailCanvas = new OffscreenCanvas(thumbnailWidth, thumbnailHeight);
|
|
1273
|
-
const thumbnailContext = thumbnailCanvas.getContext("2d");
|
|
1274
|
-
if (thumbnailContext) {
|
|
1275
|
-
thumbnailContext.imageSmoothingEnabled = true;
|
|
1276
|
-
thumbnailContext.imageSmoothingQuality = "high";
|
|
1277
|
-
thumbnailContext.drawImage(canvas, 0, 0, thumbnailWidth, thumbnailHeight);
|
|
1278
|
-
}
|
|
1279
|
-
thumbnailBlob = await thumbnailCanvas.convertToBlob({ type: "image/png" });
|
|
1280
|
-
}
|
|
1281
|
-
return { blob, height, thumbnailBlob, width };
|
|
1282
|
-
};
|
|
1283
|
-
|
|
1284
|
-
self.onmessage = async (event) => {
|
|
1285
|
-
const message = event.data;
|
|
1286
|
-
if (!message || message.type !== "render") {
|
|
1287
|
-
return;
|
|
1288
|
-
}
|
|
1289
|
-
try {
|
|
1290
|
-
const pdfjs = await loadPdfJs(message.pdfjsModuleCandidates);
|
|
1291
|
-
const pdf = await pdfjs.getDocument({
|
|
1292
|
-
data: new Uint8Array(message.pdfData),
|
|
1293
|
-
disableWorker: true,
|
|
1294
|
-
}).promise;
|
|
1295
|
-
try {
|
|
1296
|
-
const pageNumbers = normalizePdfPageNumbers(message.pageNumbers, pdf.numPages);
|
|
1297
|
-
const bufferedPages = new Map();
|
|
1298
|
-
let nextEmitIndex = 0;
|
|
1299
|
-
let emitChain = Promise.resolve();
|
|
1300
|
-
const emitPageInOrder = async (pageNumber, renderedPage) => {
|
|
1301
|
-
bufferedPages.set(pageNumber, renderedPage);
|
|
1302
|
-
const flush = () => {
|
|
1303
|
-
while (nextEmitIndex < pageNumbers.length) {
|
|
1304
|
-
const nextPageNumber = pageNumbers[nextEmitIndex];
|
|
1305
|
-
if (nextPageNumber == null) break;
|
|
1306
|
-
const nextPage = bufferedPages.get(nextPageNumber);
|
|
1307
|
-
if (!nextPage) break;
|
|
1308
|
-
bufferedPages.delete(nextPageNumber);
|
|
1309
|
-
nextEmitIndex += 1;
|
|
1310
|
-
self.postMessage({
|
|
1311
|
-
type: "page",
|
|
1312
|
-
page: {
|
|
1313
|
-
...nextPage,
|
|
1314
|
-
pageNumber: nextPageNumber,
|
|
1315
|
-
},
|
|
1316
|
-
});
|
|
1317
|
-
}
|
|
1318
|
-
};
|
|
1319
|
-
const nextChain = emitChain.then(flush, flush);
|
|
1320
|
-
emitChain = nextChain.catch(() => {});
|
|
1321
|
-
await nextChain;
|
|
1322
|
-
};
|
|
1323
|
-
await runWithConcurrency(
|
|
1324
|
-
pageNumbers,
|
|
1325
|
-
message.pageConcurrency,
|
|
1326
|
-
async (pageNumber) => {
|
|
1327
|
-
const page = await pdf.getPage(pageNumber);
|
|
1328
|
-
try {
|
|
1329
|
-
const renderedPage = await renderPageToBlob(
|
|
1330
|
-
page,
|
|
1331
|
-
message.scale,
|
|
1332
|
-
message.storeThumbnails,
|
|
1333
|
-
);
|
|
1334
|
-
await emitPageInOrder(pageNumber, renderedPage);
|
|
1335
|
-
} finally {
|
|
1336
|
-
page.cleanup();
|
|
1337
|
-
}
|
|
1338
|
-
},
|
|
1339
|
-
);
|
|
1340
|
-
await emitChain;
|
|
1341
|
-
} finally {
|
|
1342
|
-
await pdf.destroy();
|
|
1343
|
-
}
|
|
1344
|
-
self.postMessage({ type: "done" });
|
|
1345
|
-
} catch (error) {
|
|
1346
|
-
self.postMessage({ type: "error", error: createErrorPayload(error) });
|
|
1347
|
-
}
|
|
1348
|
-
};
|
|
1349
|
-
`;
|
|
1350
|
-
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
1351
|
-
var hasObjectMembers = (value) => (typeof value === "object" || typeof value === "function") && value !== null;
|
|
1352
|
-
var isOffscreenCanvasCandidate = (value) => typeof value === "function";
|
|
1353
|
-
var getEnvironmentRecord = (environment) => isRecord(environment) ? environment : null;
|
|
1354
|
-
var canUsePdfWorkerRenderer = (environment = globalThis) => {
|
|
1355
|
-
const candidateEnvironment = getEnvironmentRecord(environment);
|
|
1356
|
-
if (!candidateEnvironment) return false;
|
|
1357
|
-
if (typeof candidateEnvironment.Worker !== "function") return false;
|
|
1358
|
-
if (typeof candidateEnvironment.Blob !== "function") return false;
|
|
1359
|
-
if (!isOffscreenCanvasCandidate(candidateEnvironment.OffscreenCanvas)) {
|
|
1360
|
-
return false;
|
|
1361
|
-
}
|
|
1362
|
-
const urlCandidate = candidateEnvironment.URL;
|
|
1363
|
-
if (!hasObjectMembers(urlCandidate)) return false;
|
|
1364
|
-
if (typeof urlCandidate.createObjectURL !== "function") return false;
|
|
1365
|
-
if (typeof urlCandidate.revokeObjectURL !== "function") return false;
|
|
1366
|
-
try {
|
|
1367
|
-
const canvas = new candidateEnvironment.OffscreenCanvas(1, 1);
|
|
1368
|
-
return typeof canvas.getContext === "function" && typeof canvas.convertToBlob === "function";
|
|
1369
|
-
} catch {
|
|
1370
|
-
return false;
|
|
1371
|
-
}
|
|
1372
|
-
};
|
|
1373
|
-
var createAbortError = () => new DOMException("Aborted", "AbortError");
|
|
1374
|
-
var throwIfAborted = (signal) => {
|
|
1375
|
-
if (signal?.aborted) {
|
|
1376
|
-
throw createAbortError();
|
|
1377
|
-
}
|
|
1378
|
-
};
|
|
1379
|
-
var createPdfWorker = () => {
|
|
1380
|
-
const workerBlob = new Blob([PDF_WORKER_SOURCE], {
|
|
1381
|
-
type: "text/javascript"
|
|
1382
|
-
});
|
|
1383
|
-
const workerUrl = URL.createObjectURL(workerBlob);
|
|
1384
|
-
try {
|
|
1385
|
-
const worker = new Worker(workerUrl, {
|
|
1386
|
-
name: "canvu-pdf-renderer",
|
|
1387
|
-
type: "module"
|
|
1388
|
-
});
|
|
1389
|
-
return {
|
|
1390
|
-
release: () => URL.revokeObjectURL(workerUrl),
|
|
1391
|
-
worker
|
|
1392
|
-
};
|
|
1393
|
-
} catch (error) {
|
|
1394
|
-
URL.revokeObjectURL(workerUrl);
|
|
1395
|
-
throw error;
|
|
1396
|
-
}
|
|
1397
|
-
};
|
|
1398
|
-
var createWorkerError = (message) => {
|
|
1399
|
-
const error = new Error(message.error.message);
|
|
1400
|
-
error.name = message.error.name;
|
|
1401
|
-
error.stack = message.error.stack;
|
|
1402
|
-
return error;
|
|
1403
|
-
};
|
|
1404
|
-
var PACKAGED_PDFJS_MODULE_FILE = "./pdf.mjs";
|
|
1405
|
-
var PACKAGED_PDFJS_WORKER_FILE = "./pdf.worker.mjs";
|
|
1406
|
-
var resolveRelativeAssetUrl = (path, baseUrl) => new URL(path, baseUrl).toString();
|
|
1407
|
-
var resolvePackagedPdfJsModuleCandidate = (baseUrl = import.meta.url) => ({
|
|
1408
|
-
moduleUrl: resolveRelativeAssetUrl(PACKAGED_PDFJS_MODULE_FILE, baseUrl),
|
|
1409
|
-
workerUrl: resolveRelativeAssetUrl(PACKAGED_PDFJS_WORKER_FILE, baseUrl)
|
|
1410
|
-
});
|
|
1411
|
-
var resolveBundledPdfJsModuleCandidate = () => ({
|
|
1412
|
-
moduleUrl: new URL("pdfjs-dist/build/pdf.min.mjs", import.meta.url).toString(),
|
|
1413
|
-
workerUrl: new URL(
|
|
1414
|
-
"pdfjs-dist/build/pdf.worker.min.mjs",
|
|
1415
|
-
import.meta.url
|
|
1416
|
-
).toString()
|
|
1417
|
-
});
|
|
1418
|
-
var resolvePdfJsModuleCandidates = () => [
|
|
1419
|
-
resolvePackagedPdfJsModuleCandidate(),
|
|
1420
|
-
resolveBundledPdfJsModuleCandidate()
|
|
1421
|
-
];
|
|
1422
|
-
var loadPdfToStoreWithWorker = async (file, store, options) => {
|
|
1423
|
-
throwIfAborted(options.signal);
|
|
1424
|
-
const arrayBuffer = await file.arrayBuffer();
|
|
1425
|
-
throwIfAborted(options.signal);
|
|
1426
|
-
return await new Promise((resolve, reject) => {
|
|
1427
|
-
const { release, worker } = createPdfWorker();
|
|
1428
|
-
const pageResults = [];
|
|
1429
|
-
let storeChain = Promise.resolve();
|
|
1430
|
-
let cleanedUp = false;
|
|
1431
|
-
let settled = false;
|
|
1432
|
-
const cleanup = () => {
|
|
1433
|
-
if (cleanedUp) return;
|
|
1434
|
-
cleanedUp = true;
|
|
1435
|
-
options.signal?.removeEventListener("abort", abortWorker);
|
|
1436
|
-
worker.onmessage = null;
|
|
1437
|
-
worker.onerror = null;
|
|
1438
|
-
worker.terminate();
|
|
1439
|
-
release();
|
|
1440
|
-
};
|
|
1441
|
-
const rejectOnce = (error) => {
|
|
1442
|
-
if (settled) return;
|
|
1443
|
-
settled = true;
|
|
1444
|
-
cleanup();
|
|
1445
|
-
reject(error);
|
|
1446
|
-
};
|
|
1447
|
-
const rejectAfterQueuedStores = (error) => {
|
|
1448
|
-
if (settled) return;
|
|
1449
|
-
cleanup();
|
|
1450
|
-
storeChain.then(() => {
|
|
1451
|
-
if (settled) return;
|
|
1452
|
-
settled = true;
|
|
1453
|
-
reject(error);
|
|
1454
|
-
}).catch(rejectOnce);
|
|
1455
|
-
};
|
|
1456
|
-
function abortWorker() {
|
|
1457
|
-
rejectOnce(createAbortError());
|
|
1458
|
-
}
|
|
1459
|
-
const storePage = (message) => {
|
|
1460
|
-
try {
|
|
1461
|
-
options.onPageReceived?.({ pageNumber: message.page.pageNumber });
|
|
1462
|
-
} catch (error) {
|
|
1463
|
-
rejectOnce(error);
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
storeChain = storeChain.then(async () => {
|
|
1467
|
-
throwIfAborted(options.signal);
|
|
1468
|
-
const blobId = await store.storeOriginal(message.page.blob);
|
|
1469
|
-
throwIfAborted(options.signal);
|
|
1470
|
-
const thumbnailBlobId = options.storeThumbnails && message.page.thumbnailBlob ? await store.storeThumbnail(message.page.thumbnailBlob) : "";
|
|
1471
|
-
throwIfAborted(options.signal);
|
|
1472
|
-
const pageResult = {
|
|
1473
|
-
blobId,
|
|
1474
|
-
height: message.page.height,
|
|
1475
|
-
pageNumber: message.page.pageNumber,
|
|
1476
|
-
thumbnailBlobId,
|
|
1477
|
-
width: message.page.width
|
|
1478
|
-
};
|
|
1479
|
-
pageResults.push(pageResult);
|
|
1480
|
-
await options.onPageStored?.(pageResult);
|
|
1481
|
-
throwIfAborted(options.signal);
|
|
1482
|
-
});
|
|
1483
|
-
void storeChain.catch(rejectOnce);
|
|
1484
|
-
};
|
|
1485
|
-
worker.onmessage = (event) => {
|
|
1486
|
-
const message = event.data;
|
|
1487
|
-
if (message.type === "page") {
|
|
1488
|
-
storePage(message);
|
|
1489
|
-
return;
|
|
1490
|
-
}
|
|
1491
|
-
if (message.type === "error") {
|
|
1492
|
-
rejectAfterQueuedStores(createWorkerError(message));
|
|
1493
|
-
return;
|
|
1494
|
-
}
|
|
1495
|
-
storeChain.then(() => {
|
|
1496
|
-
if (settled) return;
|
|
1497
|
-
settled = true;
|
|
1498
|
-
cleanup();
|
|
1499
|
-
resolve(pageResults);
|
|
1500
|
-
}).catch(rejectOnce);
|
|
1501
|
-
};
|
|
1502
|
-
worker.onerror = (event) => {
|
|
1503
|
-
rejectAfterQueuedStores(event.error ?? new Error(event.message));
|
|
1504
|
-
};
|
|
1505
|
-
options.signal?.addEventListener("abort", abortWorker, { once: true });
|
|
1506
|
-
try {
|
|
1507
|
-
worker.postMessage(
|
|
1508
|
-
{
|
|
1509
|
-
pdfData: arrayBuffer,
|
|
1510
|
-
pdfjsModuleCandidates: resolvePdfJsModuleCandidates(),
|
|
1511
|
-
pageNumbers: options.pageNumbers ? [...options.pageNumbers] : void 0,
|
|
1512
|
-
pageConcurrency: options.pageConcurrency,
|
|
1513
|
-
scale: options.scale,
|
|
1514
|
-
storeThumbnails: options.storeThumbnails,
|
|
1515
|
-
type: "render"
|
|
1516
|
-
},
|
|
1517
|
-
[arrayBuffer]
|
|
1518
|
-
);
|
|
1519
|
-
} catch (error) {
|
|
1520
|
-
rejectOnce(error);
|
|
1521
|
-
}
|
|
1522
|
-
});
|
|
1523
|
-
};
|
|
1524
|
-
|
|
1525
1189
|
// src/image/pdf-loader.ts
|
|
1526
1190
|
var pdfjsPromise = null;
|
|
1527
1191
|
function getPdfJs() {
|
|
@@ -1538,7 +1202,7 @@ function getPdfJs() {
|
|
|
1538
1202
|
return pdfjsPromise;
|
|
1539
1203
|
}
|
|
1540
1204
|
async function renderPageToCanvas(page, scale, signal) {
|
|
1541
|
-
|
|
1205
|
+
throwIfAborted(signal);
|
|
1542
1206
|
const raw = page.getViewport({ scale: 1 });
|
|
1543
1207
|
const adjustedScale = Math.round(raw.width * scale) / raw.width;
|
|
1544
1208
|
const viewport = page.getViewport({ scale: adjustedScale });
|
|
@@ -1560,7 +1224,7 @@ async function renderPageToCanvas(page, scale, signal) {
|
|
|
1560
1224
|
try {
|
|
1561
1225
|
await renderTask.promise;
|
|
1562
1226
|
} catch (error) {
|
|
1563
|
-
if (signal.aborted) throw
|
|
1227
|
+
if (signal.aborted) throw createAbortError();
|
|
1564
1228
|
throw error;
|
|
1565
1229
|
} finally {
|
|
1566
1230
|
signal.removeEventListener("abort", abortRender);
|
|
@@ -1568,15 +1232,15 @@ async function renderPageToCanvas(page, scale, signal) {
|
|
|
1568
1232
|
} else {
|
|
1569
1233
|
await renderTask.promise;
|
|
1570
1234
|
}
|
|
1571
|
-
|
|
1235
|
+
throwIfAborted(signal);
|
|
1572
1236
|
return { canvas, width: w, height: h };
|
|
1573
1237
|
}
|
|
1574
|
-
function
|
|
1238
|
+
function createAbortError() {
|
|
1575
1239
|
return new DOMException("Aborted", "AbortError");
|
|
1576
1240
|
}
|
|
1577
|
-
function
|
|
1241
|
+
function throwIfAborted(signal) {
|
|
1578
1242
|
if (signal?.aborted) {
|
|
1579
|
-
throw
|
|
1243
|
+
throw createAbortError();
|
|
1580
1244
|
}
|
|
1581
1245
|
}
|
|
1582
1246
|
function normalizePdfPageNumbers(pageNumbers, pageCount) {
|
|
@@ -1592,7 +1256,7 @@ async function runWithConcurrency(items, concurrency, execute, signal) {
|
|
|
1592
1256
|
await Promise.all(
|
|
1593
1257
|
Array.from({ length: workerCount }, async () => {
|
|
1594
1258
|
while (nextIndex < items.length) {
|
|
1595
|
-
|
|
1259
|
+
throwIfAborted(signal);
|
|
1596
1260
|
const currentIndex = nextIndex;
|
|
1597
1261
|
nextIndex += 1;
|
|
1598
1262
|
const item = items[currentIndex];
|
|
@@ -1600,7 +1264,7 @@ async function runWithConcurrency(items, concurrency, execute, signal) {
|
|
|
1600
1264
|
continue;
|
|
1601
1265
|
}
|
|
1602
1266
|
results[currentIndex] = await execute(item);
|
|
1603
|
-
|
|
1267
|
+
throwIfAborted(signal);
|
|
1604
1268
|
}
|
|
1605
1269
|
})
|
|
1606
1270
|
);
|
|
@@ -1611,52 +1275,11 @@ async function loadPdfToStore(file, store, options) {
|
|
|
1611
1275
|
const pageConcurrency = options?.pageConcurrency ?? 2;
|
|
1612
1276
|
const storeThumbnails = options?.storeThumbnails ?? false;
|
|
1613
1277
|
const signal = options?.signal;
|
|
1614
|
-
|
|
1615
|
-
if (canUsePdfWorkerRenderer()) {
|
|
1616
|
-
let workerPageCount = 0;
|
|
1617
|
-
try {
|
|
1618
|
-
return await loadPdfToStoreWithWorker(file, store, {
|
|
1619
|
-
scale,
|
|
1620
|
-
pageNumbers: options?.pageNumbers,
|
|
1621
|
-
pageConcurrency,
|
|
1622
|
-
storeThumbnails,
|
|
1623
|
-
signal,
|
|
1624
|
-
onPageReceived: () => {
|
|
1625
|
-
workerPageCount += 1;
|
|
1626
|
-
},
|
|
1627
|
-
onPageStored: async (page) => {
|
|
1628
|
-
await options?.onPageStored?.(page);
|
|
1629
|
-
}
|
|
1630
|
-
});
|
|
1631
|
-
} catch (error) {
|
|
1632
|
-
if (signal?.aborted || workerPageCount > 0) {
|
|
1633
|
-
throw error;
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
}
|
|
1637
|
-
return await loadPdfToStoreOnMainThread(file, store, {
|
|
1638
|
-
scale,
|
|
1639
|
-
pageNumbers: options?.pageNumbers,
|
|
1640
|
-
pageConcurrency,
|
|
1641
|
-
storeThumbnails,
|
|
1642
|
-
signal,
|
|
1643
|
-
onPageStored: options?.onPageStored
|
|
1644
|
-
});
|
|
1645
|
-
}
|
|
1646
|
-
async function loadPdfToStoreOnMainThread(file, store, options) {
|
|
1647
|
-
const {
|
|
1648
|
-
pageConcurrency,
|
|
1649
|
-
scale,
|
|
1650
|
-
signal,
|
|
1651
|
-
storeThumbnails,
|
|
1652
|
-
onPageStored,
|
|
1653
|
-
pageNumbers
|
|
1654
|
-
} = options;
|
|
1655
|
-
throwIfAborted2(signal);
|
|
1278
|
+
throwIfAborted(signal);
|
|
1656
1279
|
const pdfjs = await getPdfJs();
|
|
1657
|
-
|
|
1280
|
+
throwIfAborted(signal);
|
|
1658
1281
|
const arrayBuffer = await file.arrayBuffer();
|
|
1659
|
-
|
|
1282
|
+
throwIfAborted(signal);
|
|
1660
1283
|
const loadingTask = pdfjs.getDocument({ data: arrayBuffer });
|
|
1661
1284
|
if (signal) {
|
|
1662
1285
|
const abortLoading = () => {
|
|
@@ -1668,14 +1291,14 @@ async function loadPdfToStoreOnMainThread(file, store, options) {
|
|
|
1668
1291
|
signal.removeEventListener("abort", abortLoading);
|
|
1669
1292
|
return await loadPdfDocumentToStore(pdf2, store, {
|
|
1670
1293
|
scale,
|
|
1671
|
-
pageNumbers,
|
|
1294
|
+
pageNumbers: options?.pageNumbers,
|
|
1672
1295
|
pageConcurrency,
|
|
1673
1296
|
storeThumbnails,
|
|
1674
1297
|
signal,
|
|
1675
|
-
onPageStored
|
|
1298
|
+
onPageStored: options?.onPageStored
|
|
1676
1299
|
});
|
|
1677
1300
|
} catch (error) {
|
|
1678
|
-
if (signal.aborted) throw
|
|
1301
|
+
if (signal.aborted) throw createAbortError();
|
|
1679
1302
|
throw error;
|
|
1680
1303
|
} finally {
|
|
1681
1304
|
signal.removeEventListener("abort", abortLoading);
|
|
@@ -1684,16 +1307,16 @@ async function loadPdfToStoreOnMainThread(file, store, options) {
|
|
|
1684
1307
|
const pdf = await loadingTask.promise;
|
|
1685
1308
|
return await loadPdfDocumentToStore(pdf, store, {
|
|
1686
1309
|
scale,
|
|
1687
|
-
pageNumbers,
|
|
1310
|
+
pageNumbers: options?.pageNumbers,
|
|
1688
1311
|
pageConcurrency,
|
|
1689
1312
|
storeThumbnails,
|
|
1690
|
-
onPageStored
|
|
1313
|
+
onPageStored: options?.onPageStored
|
|
1691
1314
|
});
|
|
1692
1315
|
}
|
|
1693
1316
|
async function loadPdfDocumentToStore(pdf, store, options) {
|
|
1694
1317
|
const { pageConcurrency, scale, signal } = options;
|
|
1695
1318
|
const storeThumbnails = options.storeThumbnails ?? false;
|
|
1696
|
-
|
|
1319
|
+
throwIfAborted(signal);
|
|
1697
1320
|
const pageNumbers = normalizePdfPageNumbers(options?.pageNumbers, pdf.numPages);
|
|
1698
1321
|
const bufferedResults = /* @__PURE__ */ new Map();
|
|
1699
1322
|
let nextEmitIndex = 0;
|
|
@@ -1708,9 +1331,9 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
1708
1331
|
if (!bufferedResult) break;
|
|
1709
1332
|
bufferedResults.delete(nextPageNumber);
|
|
1710
1333
|
nextEmitIndex += 1;
|
|
1711
|
-
|
|
1334
|
+
throwIfAborted(signal);
|
|
1712
1335
|
await options?.onPageStored?.(bufferedResult);
|
|
1713
|
-
|
|
1336
|
+
throwIfAborted(signal);
|
|
1714
1337
|
}
|
|
1715
1338
|
};
|
|
1716
1339
|
const nextChain = emitChain.then(run, run);
|
|
@@ -1722,20 +1345,20 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
1722
1345
|
pageNumbers,
|
|
1723
1346
|
pageConcurrency,
|
|
1724
1347
|
async (pageNumber) => {
|
|
1725
|
-
|
|
1348
|
+
throwIfAborted(signal);
|
|
1726
1349
|
const page = await pdf.getPage(pageNumber);
|
|
1727
|
-
|
|
1350
|
+
throwIfAborted(signal);
|
|
1728
1351
|
const { canvas, width, height } = await renderPageToCanvas(
|
|
1729
1352
|
page,
|
|
1730
1353
|
scale,
|
|
1731
1354
|
signal
|
|
1732
1355
|
);
|
|
1733
|
-
|
|
1356
|
+
throwIfAborted(signal);
|
|
1734
1357
|
const mime = "image/png";
|
|
1735
1358
|
const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
|
|
1736
|
-
|
|
1359
|
+
throwIfAborted(signal);
|
|
1737
1360
|
const blobId = await store.storeOriginal(pageBlob);
|
|
1738
|
-
|
|
1361
|
+
throwIfAborted(signal);
|
|
1739
1362
|
const thumbnailBlobId = storeThumbnails ? await (async () => {
|
|
1740
1363
|
const thumbScale = Math.min(1, 256 / Math.max(width, height));
|
|
1741
1364
|
const tw = Math.max(1, Math.round(width * thumbScale));
|
|
@@ -1752,7 +1375,7 @@ async function loadPdfDocumentToStore(pdf, store, options) {
|
|
|
1752
1375
|
const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
|
|
1753
1376
|
mimeType: mime
|
|
1754
1377
|
});
|
|
1755
|
-
|
|
1378
|
+
throwIfAborted(signal);
|
|
1756
1379
|
return await store.storeThumbnail(thumbBlob);
|
|
1757
1380
|
})() : "";
|
|
1758
1381
|
const pageResult = {
|
|
@@ -2106,22 +1729,22 @@ function finalizeIngestedItem(item, context, uploadResult, decorateItem) {
|
|
|
2106
1729
|
const itemWithAssetData = applyAssetUploadResultToItem(item, uploadResult);
|
|
2107
1730
|
return decorateItem ? decorateItem(itemWithAssetData, context) : itemWithAssetData;
|
|
2108
1731
|
}
|
|
2109
|
-
function
|
|
1732
|
+
function createAbortError2() {
|
|
2110
1733
|
return new DOMException("Aborted", "AbortError");
|
|
2111
1734
|
}
|
|
2112
|
-
function
|
|
1735
|
+
function throwIfAborted2(signal) {
|
|
2113
1736
|
if (signal?.aborted) {
|
|
2114
|
-
throw
|
|
1737
|
+
throw createAbortError2();
|
|
2115
1738
|
}
|
|
2116
1739
|
}
|
|
2117
1740
|
function isAbortError(error) {
|
|
2118
1741
|
return (error instanceof DOMException || error instanceof Error) && error.name === "AbortError";
|
|
2119
1742
|
}
|
|
2120
1743
|
async function uploadAssetIfNeeded(assetStore, file, kind, signal) {
|
|
2121
|
-
|
|
1744
|
+
throwIfAborted2(signal);
|
|
2122
1745
|
if (!assetStore) return null;
|
|
2123
1746
|
const result = await assetStore.upload({ file, kind, signal });
|
|
2124
|
-
|
|
1747
|
+
throwIfAborted2(signal);
|
|
2125
1748
|
return result ?? null;
|
|
2126
1749
|
}
|
|
2127
1750
|
async function ingestAssetFilesToSceneItems(options) {
|
|
@@ -2144,7 +1767,7 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
2144
1767
|
const errors = [];
|
|
2145
1768
|
let occupiedBottomY = existingItems.length > 0 ? Math.max(...existingItems.map((item) => item.bounds.y + item.bounds.height)) : null;
|
|
2146
1769
|
for (const file of files) {
|
|
2147
|
-
|
|
1770
|
+
throwIfAborted2(signal);
|
|
2148
1771
|
const kind = getAssetKindForFile(file);
|
|
2149
1772
|
if (!kind) {
|
|
2150
1773
|
const error = {
|
|
@@ -2170,10 +1793,10 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
2170
1793
|
storeThumbnails: false,
|
|
2171
1794
|
signal,
|
|
2172
1795
|
onPageStored: async (page) => {
|
|
2173
|
-
|
|
1796
|
+
throwIfAborted2(signal);
|
|
2174
1797
|
const uploadResult2 = await uploadResultPromise;
|
|
2175
1798
|
const fullUrl2 = await createBlobUrlFromStore(imageStore, page.blobId);
|
|
2176
|
-
|
|
1799
|
+
throwIfAborted2(signal);
|
|
2177
1800
|
const naturalTopY2 = worldCenter.y - page.height / 2;
|
|
2178
1801
|
const stackedTopY2 = occupiedBottomY == null ? naturalTopY2 : occupiedBottomY + gapWorld;
|
|
2179
1802
|
const bounds2 = {
|
|
@@ -2213,18 +1836,18 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
2213
1836
|
);
|
|
2214
1837
|
items.push(item2);
|
|
2215
1838
|
occupiedBottomY = bounds2.y + page.height;
|
|
2216
|
-
|
|
1839
|
+
throwIfAborted2(signal);
|
|
2217
1840
|
onItemsReady?.([item2], { file, kind });
|
|
2218
1841
|
}
|
|
2219
1842
|
});
|
|
2220
1843
|
continue;
|
|
2221
1844
|
}
|
|
2222
|
-
|
|
1845
|
+
throwIfAborted2(signal);
|
|
2223
1846
|
const [uploadResult, storedImage] = await Promise.all([
|
|
2224
1847
|
uploadAssetIfNeeded(assetStore, file, kind, signal),
|
|
2225
1848
|
loadImageToStore(file, imageStore)
|
|
2226
1849
|
]);
|
|
2227
|
-
|
|
1850
|
+
throwIfAborted2(signal);
|
|
2228
1851
|
const { blobId, thumbnailBlobId, width, height } = storedImage;
|
|
2229
1852
|
const fullUrl = await createBlobUrlFromStore(imageStore, blobId);
|
|
2230
1853
|
const thumbBlob = await imageStore.getThumbnail(thumbnailBlobId);
|
|
@@ -2262,7 +1885,7 @@ async function ingestAssetFilesToSceneItems(options) {
|
|
|
2262
1885
|
decorateItem
|
|
2263
1886
|
);
|
|
2264
1887
|
items.push(item);
|
|
2265
|
-
|
|
1888
|
+
throwIfAborted2(signal);
|
|
2266
1889
|
onItemsReady?.([item], { file, kind });
|
|
2267
1890
|
occupiedBottomY = occupiedBottomY == null ? bounds.y + height : Math.max(occupiedBottomY, bounds.y + height);
|
|
2268
1891
|
} catch (error) {
|
|
@@ -7539,6 +7162,9 @@ function shouldRedrawRasterImageCanvas({
|
|
|
7539
7162
|
if (currentSourceKey !== nextSourceKey && safeCurrentWidth === safeNextWidth && safeCurrentHeight === safeNextHeight) {
|
|
7540
7163
|
return true;
|
|
7541
7164
|
}
|
|
7165
|
+
if (currentSourceKey !== nextSourceKey && (safeNextWidth < safeCurrentWidth || safeNextHeight < safeCurrentHeight)) {
|
|
7166
|
+
return true;
|
|
7167
|
+
}
|
|
7542
7168
|
return safeNextWidth > safeCurrentWidth * upscaleRedrawRatio || safeNextHeight > safeCurrentHeight * upscaleRedrawRatio;
|
|
7543
7169
|
}
|
|
7544
7170
|
function toPositiveFiniteNumber(value, fallback) {
|