@pixldocs/canvas-renderer 0.5.497 → 0.5.498

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.
@@ -2647,7 +2647,7 @@ let sizeBaseSnapshot = null;
2647
2647
  const reflowPagesFromBase = (base, W, H) => {
2648
2648
  const sx = base.width ? W / base.width : 1;
2649
2649
  const sy = base.height ? H / base.height : 1;
2650
- const fscale = Math.sqrt(Math.max(0.01, sx * sy));
2650
+ const fscale = Math.max(0.01, Math.min(sx, sy));
2651
2651
  const adapt = layoutAdaptationFor(base.width, base.height, W, H);
2652
2652
  const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
2653
2653
  const scaleNode = (node) => scaleNodeForReflow(node, sx, sy, fscale);
@@ -3196,7 +3196,7 @@ const useEditorStore = create((set, get) => ({
3196
3196
  setCanvasSize: (width, height) => set((state) => {
3197
3197
  const oldW = state.canvas.width || width, oldH = state.canvas.height || height;
3198
3198
  const sx = oldW ? width / oldW : 1, sy = oldH ? height / oldH : 1;
3199
- const fscale = Math.sqrt(Math.max(0.01, sx * sy));
3199
+ const fscale = Math.max(0.01, Math.min(sx, sy));
3200
3200
  const n = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
3201
3201
  const scaleNode = (node) => {
3202
3202
  const el = { ...node };
@@ -5852,6 +5852,26 @@ const setupFontLoadingListener = (canvas, afterRerender, options = {}) => {
5852
5852
  }
5853
5853
  };
5854
5854
  };
5855
+ const GLOBAL_KEY = "__PIXLDOCS_IMAGE_FAILURES__";
5856
+ const MAX_RECORDED = 50;
5857
+ function host() {
5858
+ return typeof globalThis === "undefined" ? null : globalThis;
5859
+ }
5860
+ function recordImageLoadFailure(failure) {
5861
+ try {
5862
+ const g = host();
5863
+ if (!g) return;
5864
+ const list = g[GLOBAL_KEY] ?? [];
5865
+ if (list.length >= MAX_RECORDED) return;
5866
+ list.push({
5867
+ id: String(failure.id ?? ""),
5868
+ url: String(failure.url ?? "").slice(0, 500),
5869
+ reason: String(failure.reason ?? "").slice(0, 300)
5870
+ });
5871
+ g[GLOBAL_KEY] = list;
5872
+ } catch {
5873
+ }
5874
+ }
5855
5875
  const EMPTY_IMAGE_PLACEHOLDER_DATA_URL = "data:image/png;base64,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";
5856
5876
  const svgTextCache = /* @__PURE__ */ new Map();
5857
5877
  const htmlImageCache = /* @__PURE__ */ new Map();
@@ -6547,6 +6567,11 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
6547
6567
  proxiedUrl: getProxiedImageUrl(imageUrl).slice(0, 240),
6548
6568
  error: error instanceof Error ? error.message : String(error)
6549
6569
  });
6570
+ recordImageLoadFailure({
6571
+ id: String(element.id ?? ""),
6572
+ url: imageUrl,
6573
+ reason: error instanceof Error ? error.message : String(error)
6574
+ });
6550
6575
  if (fc.__pixldocsEditMode === true) {
6551
6576
  try {
6552
6577
  markPlaceholderAsBrokenImage(placeholder);
@@ -10394,10 +10419,10 @@ function textPathBoundsContainScenePoint(obj, point) {
10394
10419
  }
10395
10420
  function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
10396
10421
  var _a2, _b2, _c2;
10397
- const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
10398
- if (!host) return;
10399
- const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c2 = obj.getCanvasRetinaScaling) == null ? void 0 : _c2.call(obj)) || 1;
10400
- const matrix = fabric.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
10422
+ const host2 = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
10423
+ if (!host2) return;
10424
+ const retina = ((_b2 = host2.getRetinaScaling) == null ? void 0 : _b2.call(host2)) || ((_c2 = obj.getCanvasRetinaScaling) == null ? void 0 : _c2.call(obj)) || 1;
10425
+ const matrix = fabric.util.multiplyTransformMatrices(host2.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
10401
10426
  const corners = [
10402
10427
  new fabric.Point(bounds.minX, bounds.minY),
10403
10428
  new fabric.Point(bounds.maxX, bounds.minY),
@@ -10648,11 +10673,11 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
10648
10673
  GroupProto.__pixldocsOrigRenderControls = GroupProto._renderControls;
10649
10674
  GroupProto._renderControls = function(ctx, styleOverride, childrenOverride) {
10650
10675
  var _a2;
10651
- const host = this.canvas;
10652
- const active = (_a2 = host == null ? void 0 : host.getActiveObject) == null ? void 0 : _a2.call(host);
10653
- const isActiveOrInActive = !!host && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
10676
+ const host2 = this.canvas;
10677
+ const active = (_a2 = host2 == null ? void 0 : host2.getActiveObject) == null ? void 0 : _a2.call(host2);
10678
+ const isActiveOrInActive = !!host2 && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
10654
10679
  GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
10655
- if (!host || !isActiveOrInActive) return;
10680
+ if (!host2 || !isActiveOrInActive) return;
10656
10681
  const drawForDescendants = (parent) => {
10657
10682
  const kids = (parent == null ? void 0 : parent._objects) || [];
10658
10683
  for (const child of kids) {
@@ -10661,7 +10686,7 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
10661
10686
  }
10662
10687
  if (child && child.textPath && child.textPath.preset && child.textPath.preset !== "none") {
10663
10688
  const bounds = getTextPathHitBounds(child);
10664
- if (bounds) drawTextPathBounds(ctx, child, bounds, host);
10689
+ if (bounds) drawTextPathBounds(ctx, child, bounds, host2);
10665
10690
  }
10666
10691
  }
10667
10692
  };
@@ -26529,6 +26554,11 @@ const PageCanvas = forwardRef(
26529
26554
  url: (element.src || element.imageUrl || "").slice(0, 200),
26530
26555
  error: error instanceof Error ? error.message : String(error)
26531
26556
  });
26557
+ recordImageLoadFailure({
26558
+ id: String(element.id ?? ""),
26559
+ url: element.src || element.imageUrl || "",
26560
+ reason: error instanceof Error ? error.message : String(error)
26561
+ });
26532
26562
  const fcNow = fabricRef.current;
26533
26563
  if (fcNow && fcNow.__pixldocsEditMode === true) {
26534
26564
  try {
@@ -27860,6 +27890,7 @@ function PreviewCanvas({
27860
27890
  const pageSettings = useMemo(() => {
27861
27891
  var _a3, _b3;
27862
27892
  return {
27893
+ // design-drift-ignore: artifact paper colour, not chrome
27863
27894
  backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
27864
27895
  backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
27865
27896
  };
@@ -32482,11 +32513,31 @@ async function resolveTemplateData(options) {
32482
32513
  ...formData ?? {}
32483
32514
  };
32484
32515
  const dynamicFields = config.dynamicFields;
32485
- if (!Array.isArray(dynamicFields) || dynamicFields.length === 0) {
32516
+ const hasBoundTable = (() => {
32517
+ let found = false;
32518
+ const walk = (nodes) => {
32519
+ var _a2, _b2;
32520
+ for (const n of nodes || []) {
32521
+ if (found) return;
32522
+ if ((n == null ? void 0 : n.type) === "table" && ((_b2 = (_a2 = n == null ? void 0 : n.tableData) == null ? void 0 : _a2.repeat) == null ? void 0 : _b2.from)) {
32523
+ found = true;
32524
+ return;
32525
+ }
32526
+ walk(n == null ? void 0 : n.children);
32527
+ }
32528
+ };
32529
+ for (const p of config.pages || []) walk(p.children);
32530
+ return found;
32531
+ })();
32532
+ const hasDynamicFields = Array.isArray(dynamicFields) && dynamicFields.length > 0;
32533
+ if (!hasDynamicFields && (hasBoundTable || repeatableSectionsInput.length > 0)) {
32534
+ console.log("[resolveTemplateData] no dynamicFields; binding via bound table / repeatable sections");
32535
+ }
32536
+ if (!hasDynamicFields && !hasBoundTable && repeatableSectionsInput.length === 0) {
32486
32537
  return { config: applyThemeIfNeeded(config), templateName: template.name || "Untitled", templateId, price: template.price ?? 0 };
32487
32538
  }
32488
32539
  const mappings = [];
32489
- for (const f of dynamicFields) {
32540
+ for (const f of dynamicFields || []) {
32490
32541
  for (const m of f.mappings || []) {
32491
32542
  mappings.push({
32492
32543
  field_key: f.id,
@@ -34322,9 +34373,22 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
34322
34373
  }
34323
34374
  return svgString;
34324
34375
  }
34325
- const resolvedPackageVersion = "0.5.497";
34376
+ const resolvedPackageVersion = "0.5.498";
34326
34377
  const PACKAGE_VERSION = resolvedPackageVersion;
34327
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.497";
34378
+ async function crPhase(name, fn) {
34379
+ const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
34380
+ const t0 = now();
34381
+ try {
34382
+ return await fn();
34383
+ } finally {
34384
+ const g = globalThis;
34385
+ const bag = g.__CR_PHASES__ || (g.__CR_PHASES__ = {});
34386
+ const cur = bag[name] || (bag[name] = { count: 0, ms: 0 });
34387
+ cur.count += 1;
34388
+ cur.ms += Math.round(now() - t0);
34389
+ }
34390
+ }
34391
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.498";
34328
34392
  const roundParityValue = (value) => {
34329
34393
  if (typeof value !== "number") return value;
34330
34394
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -35123,7 +35187,7 @@ class PixldocsRenderer {
35123
35187
  containers.push(container);
35124
35188
  const root = createRoot(container);
35125
35189
  roots.push(root);
35126
- await new Promise((resolve, reject) => {
35190
+ await crPhase("pdf_mount", () => new Promise((resolve, reject) => {
35127
35191
  const timer = setTimeout(() => reject(new Error(`PreviewCanvas onReady timeout for page ${i}`)), 3e4);
35128
35192
  root.render(
35129
35193
  createElement(PreviewCanvas2, {
@@ -35141,15 +35205,15 @@ class PixldocsRenderer {
35141
35205
  }
35142
35206
  })
35143
35207
  );
35144
- });
35145
- await this.waitForCanvasScene(container, cloned, i);
35208
+ }));
35209
+ await crPhase("pdf_scene1", () => this.waitForCanvasScene(container, cloned, i));
35146
35210
  const expected = this.getExpectedImageIds(cloned, i);
35147
- await this.waitForCanvasImages(container, expected);
35148
- await this.waitForStableTextMetrics(container, cloned, { clearGlobalCharCache: false });
35149
- await this.waitForCanvasScene(container, cloned, i);
35211
+ await crPhase("pdf_images", () => this.waitForCanvasImages(container, expected));
35212
+ await crPhase("pdf_text_metrics", () => this.waitForStableTextMetrics(container, cloned, { clearGlobalCharCache: false }));
35213
+ await crPhase("pdf_scene2", () => this.waitForCanvasScene(container, cloned, i));
35150
35214
  }
35151
35215
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
35152
- const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-DV-TJwjP.js");
35216
+ const { exportMultiPagePdf, preparePagesForExport } = await import("./vectorPdfExport-D8iQi9WT.js");
35153
35217
  const prepared = preparePagesForExport(
35154
35218
  cloned.pages,
35155
35219
  canvasWidth,
@@ -35327,8 +35391,14 @@ class PixldocsRenderer {
35327
35391
  }
35328
35392
  const sceneSettled = fabricReady && allDomLoaded && canvasReady && fabricObjects.length > 0;
35329
35393
  const idleFor = Date.now() - lastProgressAt;
35330
- if (!strictById && sceneSettled && actualImageCount < expectedImageCount && idleFor >= earlyExitMs) {
35331
- if (debug) {
35394
+ const strictIdleMs = Math.max(earlyExitMs, 4e3);
35395
+ const stalled = strictById ? missingImageIds.length > 0 : actualImageCount < expectedImageCount;
35396
+ if (sceneSettled && stalled && idleFor >= (strictById ? strictIdleMs : earlyExitMs)) {
35397
+ if (strictById) {
35398
+ console.warn(
35399
+ `[canvas-renderer][asset-wait] early-exit after ${elapsed}ms with unresolved image id(s): ${missingImageIds.join(", ")} (idle=${idleFor}ms, ${summary})`
35400
+ );
35401
+ } else if (debug) {
35332
35402
  console.log(
35333
35403
  `[canvas-renderer][asset-wait] early-exit after ${elapsed}ms (idle=${idleFor}ms, ${summary})`
35334
35404
  );
@@ -35547,6 +35617,8 @@ class PixldocsRenderer {
35547
35617
  });
35548
35618
  }
35549
35619
  return new Promise((resolve, reject) => {
35620
+ const mountStartedAt = typeof performance !== "undefined" ? performance.now() : Date.now();
35621
+ let mountRecorded = false;
35550
35622
  const container = document.createElement("div");
35551
35623
  container.style.cssText = `
35552
35624
  position: fixed; left: -99999px; top: -99999px;
@@ -35611,13 +35683,22 @@ class PixldocsRenderer {
35611
35683
  });
35612
35684
  };
35613
35685
  const onReady = () => {
35614
- this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
35686
+ if (!mountRecorded) {
35687
+ mountRecorded = true;
35688
+ const now = typeof performance !== "undefined" ? performance.now() : Date.now();
35689
+ const g = globalThis;
35690
+ const bag = g.__CR_PHASES__ || (g.__CR_PHASES__ = {});
35691
+ const cur = bag.raster_mount || (bag.raster_mount = { count: 0, ms: 0 });
35692
+ cur.count += 1;
35693
+ cur.ms += Math.round(now - mountStartedAt);
35694
+ }
35695
+ crPhase("raster_scene1", () => this.waitForCanvasScene(container, renderConfig, pageIndex)).then(async () => {
35615
35696
  try {
35616
35697
  const fabricInstance = this.getFabricCanvasFromContainer(container);
35617
35698
  const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
35618
- await this.waitForCanvasImages(container, expectedImageIds);
35619
- await this.waitForStableTextMetrics(container, renderConfig);
35620
- await this.waitForCanvasScene(container, renderConfig, pageIndex);
35699
+ await crPhase("raster_images", () => this.waitForCanvasImages(container, expectedImageIds));
35700
+ await crPhase("raster_text_metrics", () => this.waitForStableTextMetrics(container, renderConfig));
35701
+ await crPhase("raster_scene2", () => this.waitForCanvasScene(container, renderConfig, pageIndex));
35621
35702
  firstMountSettled = true;
35622
35703
  if (hasAutoShrink && lateFontSettleDetected) {
35623
35704
  console.log("[canvas-renderer][parity] late font-settle detected — remounting for auto-shrink reflow");
@@ -37500,7 +37581,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
37500
37581
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
37501
37582
  sanitizeSvgTreeForPdf(svgToDraw);
37502
37583
  try {
37503
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-DV-TJwjP.js");
37584
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await import("./vectorPdfExport-D8iQi9WT.js");
37504
37585
  try {
37505
37586
  await logTextMeasurementDiagnostic(svgToDraw);
37506
37587
  } catch {
@@ -37754,8 +37835,8 @@ const DEFAULT_WATERMARK_FONT_SIZE = 18;
37754
37835
  const DEFAULT_WATERMARK_ANGLE = -30;
37755
37836
  function getWatermarkText() {
37756
37837
  try {
37757
- const host = window.location.hostname;
37758
- if (host.includes("biomaker")) return "biomaker.app";
37838
+ const host2 = window.location.hostname;
37839
+ if (host2.includes("biomaker")) return "biomaker.app";
37759
37840
  } catch {
37760
37841
  }
37761
37842
  return "pixldocs.com";
@@ -37942,4 +38023,4 @@ export {
37942
38023
  awaitFontsForConfig as y,
37943
38024
  buildTeaserBlurFlatKeys as z
37944
38025
  };
37945
- //# sourceMappingURL=index-CKhnRi3S.js.map
38026
+ //# sourceMappingURL=index-lbU-Xs_t.js.map