canvu-react 0.4.70 → 0.4.72

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.d.cts CHANGED
@@ -2,8 +2,8 @@ import { C as Camera2D } from './shape-builders-DzhCOuzo.cjs';
2
2
  export { a as Camera2DOptions, D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, b as applyStrokeToItem, c as buildArchitecturalCloudPathD, d as buildArchitecturalCloudSvg, e as buildArrowSvg, f as buildDrawDotSvg, g as buildEllipseSvg, h as buildFreehandPathSvg, i as buildLineSvg, j as buildRectSvg, k as computeFreehandSvgPayload, l as createArchitecturalCloudItem, m as createDrawDotItem, n as createEllipseItem, o as createFreehandStrokeItem, p as createImageFromVectorTrace, q as createImageItem, r as createLineItem, s as createRectangleItem, t as createShapeId, u as createTextItem, v as lineEndpointsToLocal, w as rebuildItemSvg, x as resolveStrokeStyle } from './shape-builders-DzhCOuzo.cjs';
3
3
  import { V as VectorSceneItem, A as ArrowEndpointBinding, C as CustomShapeResizeHandles, R as Rect } from './types-fJNwEnHf.cjs';
4
4
  export { a as ArrowBindings, b as ResizeHandleId, c as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-fJNwEnHf.cjs';
5
- export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-D2xaUoAT.cjs';
6
- import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-nK9kM9UJ.cjs';
5
+ export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-6swZ6ciN.cjs';
6
+ import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-ByaCKEVw.cjs';
7
7
  export { C as CanvuLinkData, D as DEFAULT_LINK_CARD_SIZE, L as LINK_PLUGIN_KEY, b as buildLinkCardSvg, c as createLinkItem, g as getLinkData, i as isLinkItem } from './link-item-BMV3VUCr.cjs';
8
8
 
9
9
  type EncodeCanvasToBlobOptions = {
package/dist/index.d.ts CHANGED
@@ -2,8 +2,8 @@ import { C as Camera2D } from './shape-builders-xG3A66sv.js';
2
2
  export { a as Camera2DOptions, D as DEFAULT_STROKE_STYLE, F as FreehandSvgPayload, S as StrokeStyle, b as applyStrokeToItem, c as buildArchitecturalCloudPathD, d as buildArchitecturalCloudSvg, e as buildArrowSvg, f as buildDrawDotSvg, g as buildEllipseSvg, h as buildFreehandPathSvg, i as buildLineSvg, j as buildRectSvg, k as computeFreehandSvgPayload, l as createArchitecturalCloudItem, m as createDrawDotItem, n as createEllipseItem, o as createFreehandStrokeItem, p as createImageFromVectorTrace, q as createImageItem, r as createLineItem, s as createRectangleItem, t as createShapeId, u as createTextItem, v as lineEndpointsToLocal, w as rebuildItemSvg, x as resolveStrokeStyle } from './shape-builders-xG3A66sv.js';
3
3
  import { V as VectorSceneItem, A as ArrowEndpointBinding, C as CustomShapeResizeHandles, R as Rect } from './types-fJNwEnHf.js';
4
4
  export { a as ArrowBindings, b as ResizeHandleId, c as VectorPathPoint, n as normalizeRect, r as rectsIntersect } from './types-fJNwEnHf.js';
5
- export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-D9eThWse.js';
6
- import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-CCOmB4NY.js';
5
+ export { H as HydratedSceneItemsWithAssetsResult, h as hydrateSceneItemsWithAssets } from './asset-hydration-P0M5hn-p.js';
6
+ import { R as RasterImageCanvasRenderingOptions } from './raster-image-canvas-D3ZrySjr.js';
7
7
  export { C as CanvuLinkData, D as DEFAULT_LINK_CARD_SIZE, L as LINK_PLUGIN_KEY, b as buildLinkCardSvg, c as createLinkItem, g as getLinkData, i as isLinkItem } from './link-item-COoNNvCu.js';
8
8
 
9
9
  type EncodeCanvasToBlobOptions = {
package/dist/index.js CHANGED
@@ -218,7 +218,8 @@ function getPdfJs() {
218
218
  }
219
219
  return pdfjsPromise;
220
220
  }
221
- async function renderPageToCanvas(page, scale) {
221
+ async function renderPageToCanvas(page, scale, signal) {
222
+ throwIfAborted(signal);
222
223
  const raw = page.getViewport({ scale: 1 });
223
224
  const adjustedScale = Math.round(raw.width * scale) / raw.width;
224
225
  const viewport = page.getViewport({ scale: adjustedScale });
@@ -231,22 +232,48 @@ async function renderPageToCanvas(page, scale) {
231
232
  if (!ctx) throw new Error("Canvas 2D context unavailable");
232
233
  ctx.imageSmoothingEnabled = true;
233
234
  ctx.imageSmoothingQuality = "high";
234
- await page.render({ canvas, viewport }).promise;
235
+ const renderTask = page.render({ canvas, viewport });
236
+ if (signal) {
237
+ const abortRender = () => {
238
+ renderTask.cancel();
239
+ };
240
+ signal.addEventListener("abort", abortRender, { once: true });
241
+ try {
242
+ await renderTask.promise;
243
+ } catch (error) {
244
+ if (signal.aborted) throw createAbortError();
245
+ throw error;
246
+ } finally {
247
+ signal.removeEventListener("abort", abortRender);
248
+ }
249
+ } else {
250
+ await renderTask.promise;
251
+ }
252
+ throwIfAborted(signal);
235
253
  return { canvas, width: w, height: h };
236
254
  }
255
+ function createAbortError() {
256
+ return new DOMException("Aborted", "AbortError");
257
+ }
258
+ function throwIfAborted(signal) {
259
+ if (signal?.aborted) {
260
+ throw createAbortError();
261
+ }
262
+ }
237
263
  function normalizePdfPageNumbers(pageNumbers, pageCount) {
238
264
  if (!pageNumbers || pageNumbers.length === 0) {
239
265
  return Array.from({ length: pageCount }, (_, index) => index + 1);
240
266
  }
241
267
  return [...new Set(pageNumbers)].filter((pageNumber) => pageNumber >= 1 && pageNumber <= pageCount).sort((left, right) => left - right);
242
268
  }
243
- async function runWithConcurrency(items, concurrency, execute) {
269
+ async function runWithConcurrency(items, concurrency, execute, signal) {
244
270
  const results = new Array(items.length);
245
271
  let nextIndex = 0;
246
272
  const workerCount = Math.max(1, Math.min(concurrency, items.length));
247
273
  await Promise.all(
248
274
  Array.from({ length: workerCount }, async () => {
249
275
  while (nextIndex < items.length) {
276
+ throwIfAborted(signal);
250
277
  const currentIndex = nextIndex;
251
278
  nextIndex += 1;
252
279
  const item = items[currentIndex];
@@ -254,6 +281,7 @@ async function runWithConcurrency(items, concurrency, execute) {
254
281
  continue;
255
282
  }
256
283
  results[currentIndex] = await execute(item);
284
+ throwIfAborted(signal);
257
285
  }
258
286
  })
259
287
  );
@@ -263,9 +291,49 @@ async function loadPdfToStore(file, store, options) {
263
291
  const scale = options?.scale ?? 1.5;
264
292
  const pageConcurrency = options?.pageConcurrency ?? 2;
265
293
  const storeThumbnails = options?.storeThumbnails ?? false;
294
+ const signal = options?.signal;
295
+ throwIfAborted(signal);
266
296
  const pdfjs = await getPdfJs();
297
+ throwIfAborted(signal);
267
298
  const arrayBuffer = await file.arrayBuffer();
268
- const pdf = await pdfjs.getDocument({ data: arrayBuffer }).promise;
299
+ throwIfAborted(signal);
300
+ const loadingTask = pdfjs.getDocument({ data: arrayBuffer });
301
+ if (signal) {
302
+ const abortLoading = () => {
303
+ void loadingTask.destroy();
304
+ };
305
+ signal.addEventListener("abort", abortLoading, { once: true });
306
+ try {
307
+ const pdf2 = await loadingTask.promise;
308
+ signal.removeEventListener("abort", abortLoading);
309
+ return await loadPdfDocumentToStore(pdf2, store, {
310
+ scale,
311
+ pageNumbers: options?.pageNumbers,
312
+ pageConcurrency,
313
+ storeThumbnails,
314
+ signal,
315
+ onPageStored: options?.onPageStored
316
+ });
317
+ } catch (error) {
318
+ if (signal.aborted) throw createAbortError();
319
+ throw error;
320
+ } finally {
321
+ signal.removeEventListener("abort", abortLoading);
322
+ }
323
+ }
324
+ const pdf = await loadingTask.promise;
325
+ return await loadPdfDocumentToStore(pdf, store, {
326
+ scale,
327
+ pageNumbers: options?.pageNumbers,
328
+ pageConcurrency,
329
+ storeThumbnails,
330
+ onPageStored: options?.onPageStored
331
+ });
332
+ }
333
+ async function loadPdfDocumentToStore(pdf, store, options) {
334
+ const { pageConcurrency, scale, signal } = options;
335
+ const storeThumbnails = options.storeThumbnails ?? false;
336
+ throwIfAborted(signal);
269
337
  const pageNumbers = normalizePdfPageNumbers(options?.pageNumbers, pdf.numPages);
270
338
  const bufferedResults = /* @__PURE__ */ new Map();
271
339
  let nextEmitIndex = 0;
@@ -280,7 +348,9 @@ async function loadPdfToStore(file, store, options) {
280
348
  if (!bufferedResult) break;
281
349
  bufferedResults.delete(nextPageNumber);
282
350
  nextEmitIndex += 1;
351
+ throwIfAborted(signal);
283
352
  await options?.onPageStored?.(bufferedResult);
353
+ throwIfAborted(signal);
284
354
  }
285
355
  };
286
356
  const nextChain = emitChain.then(run, run);
@@ -292,11 +362,20 @@ async function loadPdfToStore(file, store, options) {
292
362
  pageNumbers,
293
363
  pageConcurrency,
294
364
  async (pageNumber) => {
365
+ throwIfAborted(signal);
295
366
  const page = await pdf.getPage(pageNumber);
296
- const { canvas, width, height } = await renderPageToCanvas(page, scale);
367
+ throwIfAborted(signal);
368
+ const { canvas, width, height } = await renderPageToCanvas(
369
+ page,
370
+ scale,
371
+ signal
372
+ );
373
+ throwIfAborted(signal);
297
374
  const mime = "image/png";
298
375
  const pageBlob = await encodeCanvasToBlob(canvas, { mimeType: mime });
376
+ throwIfAborted(signal);
299
377
  const blobId = await store.storeOriginal(pageBlob);
378
+ throwIfAborted(signal);
300
379
  const thumbnailBlobId = storeThumbnails ? await (async () => {
301
380
  const thumbScale = Math.min(1, 256 / Math.max(width, height));
302
381
  const tw = Math.max(1, Math.round(width * thumbScale));
@@ -313,6 +392,7 @@ async function loadPdfToStore(file, store, options) {
313
392
  const thumbBlob = await encodeCanvasToBlob(thumbCanvas, {
314
393
  mimeType: mime
315
394
  });
395
+ throwIfAborted(signal);
316
396
  return await store.storeThumbnail(thumbBlob);
317
397
  })() : "";
318
398
  const pageResult = {
@@ -324,7 +404,8 @@ async function loadPdfToStore(file, store, options) {
324
404
  };
325
405
  await queuePageEmission(pageResult);
326
406
  return pageResult;
327
- }
407
+ },
408
+ signal
328
409
  );
329
410
  }
330
411
 
@@ -2581,6 +2662,7 @@ function resolveRasterImageCanvasRenderingOptions(options) {
2581
2662
  return {
2582
2663
  resolveSourceSize: options.resolveSourceSize,
2583
2664
  resolveRenderTarget: options.resolveRenderTarget,
2665
+ resolveCanvasSource: options.resolveCanvasSource,
2584
2666
  devicePixelRatio: toPositiveFiniteNumber(
2585
2667
  options.devicePixelRatio,
2586
2668
  fallbackDevicePixelRatio
@@ -2845,6 +2927,36 @@ function loadImageElement(href, signal) {
2845
2927
  image.src = href;
2846
2928
  });
2847
2929
  }
2930
+ function normalizeDecodedRasterImageSource(source) {
2931
+ if (!source) return null;
2932
+ const width = Math.max(1, Math.round(source.width));
2933
+ const height = Math.max(1, Math.round(source.height));
2934
+ if (!Number.isFinite(width) || !Number.isFinite(height)) return null;
2935
+ return {
2936
+ width,
2937
+ height,
2938
+ draw: source.draw,
2939
+ close: source.close ?? (() => {
2940
+ })
2941
+ };
2942
+ }
2943
+ async function resolveDecodedRasterImageSource({
2944
+ options,
2945
+ request,
2946
+ width,
2947
+ height,
2948
+ signal
2949
+ }) {
2950
+ if (options?.resolveCanvasSource) {
2951
+ const source = await options.resolveCanvasSource({
2952
+ ...request,
2953
+ signal
2954
+ });
2955
+ const decoded = normalizeDecodedRasterImageSource(source);
2956
+ if (decoded) return decoded;
2957
+ }
2958
+ return decodeRasterImage(request.targetHref, width, height, signal);
2959
+ }
2848
2960
  var SvgVectorRenderer = class {
2849
2961
  container;
2850
2962
  scene;
@@ -3077,7 +3189,20 @@ var SvgVectorRenderer = class {
3077
3189
  }
3078
3190
  const request = {
3079
3191
  itemHref: item.imageRasterHref,
3080
- target
3192
+ target,
3193
+ sourceRequest: {
3194
+ item,
3195
+ href: item.imageRasterHref,
3196
+ intrinsicSize: item.imageIntrinsicSize,
3197
+ sourceSize,
3198
+ contentRect: target.contentRect,
3199
+ targetSize: target.targetSize,
3200
+ viewportSize,
3201
+ cameraZoom: this.camera.zoom,
3202
+ devicePixelRatio: options.devicePixelRatio,
3203
+ targetHref: target.href,
3204
+ sourceKey: target.sourceKey
3205
+ }
3081
3206
  };
3082
3207
  if (rasterCanvas.abortController) {
3083
3208
  if (rasterCanvas.loadingItemHref !== item.imageRasterHref) {
@@ -3167,7 +3292,13 @@ var SvgVectorRenderer = class {
3167
3292
  rasterCanvas.loadingWidth = width;
3168
3293
  rasterCanvas.loadingHeight = height;
3169
3294
  rasterCanvas.queuedTarget = null;
3170
- decodeRasterImage(target.href, width, height, abortController.signal).then((decoded) => {
3295
+ resolveDecodedRasterImageSource({
3296
+ options: this.rasterImageCanvasRendering,
3297
+ request: request.sourceRequest,
3298
+ width,
3299
+ height,
3300
+ signal: abortController.signal
3301
+ }).then((decoded) => {
3171
3302
  if (abortController.signal.aborted || rasterCanvas.loadSequence !== sequence) {
3172
3303
  decoded.close();
3173
3304
  return;