@pixldocs/canvas-renderer 0.5.497 → 0.5.499

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.
@@ -2665,7 +2665,7 @@ let sizeBaseSnapshot = null;
2665
2665
  const reflowPagesFromBase = (base, W, H) => {
2666
2666
  const sx = base.width ? W / base.width : 1;
2667
2667
  const sy = base.height ? H / base.height : 1;
2668
- const fscale = Math.sqrt(Math.max(0.01, sx * sy));
2668
+ const fscale = Math.max(0.01, Math.min(sx, sy));
2669
2669
  const adapt = layoutAdaptationFor(base.width, base.height, W, H);
2670
2670
  const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
2671
2671
  const scaleNode = (node) => scaleNodeForReflow(node, sx, sy, fscale);
@@ -3214,7 +3214,7 @@ const useEditorStore = zustand.create((set, get) => ({
3214
3214
  setCanvasSize: (width, height) => set((state) => {
3215
3215
  const oldW = state.canvas.width || width, oldH = state.canvas.height || height;
3216
3216
  const sx = oldW ? width / oldW : 1, sy = oldH ? height / oldH : 1;
3217
- const fscale = Math.sqrt(Math.max(0.01, sx * sy));
3217
+ const fscale = Math.max(0.01, Math.min(sx, sy));
3218
3218
  const n = (v) => typeof v === "number" && Number.isFinite(v) ? v : 0;
3219
3219
  const scaleNode = (node) => {
3220
3220
  const el = { ...node };
@@ -5870,6 +5870,26 @@ const setupFontLoadingListener = (canvas, afterRerender, options = {}) => {
5870
5870
  }
5871
5871
  };
5872
5872
  };
5873
+ const GLOBAL_KEY = "__PIXLDOCS_IMAGE_FAILURES__";
5874
+ const MAX_RECORDED = 50;
5875
+ function host() {
5876
+ return typeof globalThis === "undefined" ? null : globalThis;
5877
+ }
5878
+ function recordImageLoadFailure(failure) {
5879
+ try {
5880
+ const g = host();
5881
+ if (!g) return;
5882
+ const list = g[GLOBAL_KEY] ?? [];
5883
+ if (list.length >= MAX_RECORDED) return;
5884
+ list.push({
5885
+ id: String(failure.id ?? ""),
5886
+ url: String(failure.url ?? "").slice(0, 500),
5887
+ reason: String(failure.reason ?? "").slice(0, 300)
5888
+ });
5889
+ g[GLOBAL_KEY] = list;
5890
+ } catch {
5891
+ }
5892
+ }
5873
5893
  const EMPTY_IMAGE_PLACEHOLDER_DATA_URL = "data:image/png;base64,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";
5874
5894
  const svgTextCache = /* @__PURE__ */ new Map();
5875
5895
  const htmlImageCache = /* @__PURE__ */ new Map();
@@ -6565,6 +6585,11 @@ async function loadImageAsync(element, placeholder, fc, fabricRef, syncLockedRef
6565
6585
  proxiedUrl: getProxiedImageUrl(imageUrl).slice(0, 240),
6566
6586
  error: error instanceof Error ? error.message : String(error)
6567
6587
  });
6588
+ recordImageLoadFailure({
6589
+ id: String(element.id ?? ""),
6590
+ url: imageUrl,
6591
+ reason: error instanceof Error ? error.message : String(error)
6592
+ });
6568
6593
  if (fc.__pixldocsEditMode === true) {
6569
6594
  try {
6570
6595
  markPlaceholderAsBrokenImage(placeholder);
@@ -10412,10 +10437,10 @@ function textPathBoundsContainScenePoint(obj, point) {
10412
10437
  }
10413
10438
  function drawTextPathBounds(ctx, obj, bounds, hostCanvas) {
10414
10439
  var _a2, _b2, _c2;
10415
- const host = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
10416
- if (!host) return;
10417
- const retina = ((_b2 = host.getRetinaScaling) == null ? void 0 : _b2.call(host)) || ((_c2 = obj.getCanvasRetinaScaling) == null ? void 0 : _c2.call(obj)) || 1;
10418
- const matrix = fabric__namespace.util.multiplyTransformMatrices(host.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
10440
+ const host2 = hostCanvas || obj.canvas || ((_a2 = obj.group) == null ? void 0 : _a2.canvas);
10441
+ if (!host2) return;
10442
+ const retina = ((_b2 = host2.getRetinaScaling) == null ? void 0 : _b2.call(host2)) || ((_c2 = obj.getCanvasRetinaScaling) == null ? void 0 : _c2.call(obj)) || 1;
10443
+ const matrix = fabric__namespace.util.multiplyTransformMatrices(host2.viewportTransform || [1, 0, 0, 1, 0, 0], obj.calcTransformMatrix());
10419
10444
  const corners = [
10420
10445
  new fabric__namespace.Point(bounds.minX, bounds.minY),
10421
10446
  new fabric__namespace.Point(bounds.maxX, bounds.minY),
@@ -10666,11 +10691,11 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
10666
10691
  GroupProto.__pixldocsOrigRenderControls = GroupProto._renderControls;
10667
10692
  GroupProto._renderControls = function(ctx, styleOverride, childrenOverride) {
10668
10693
  var _a2;
10669
- const host = this.canvas;
10670
- const active = (_a2 = host == null ? void 0 : host.getActiveObject) == null ? void 0 : _a2.call(host);
10671
- const isActiveOrInActive = !!host && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
10694
+ const host2 = this.canvas;
10695
+ const active = (_a2 = host2 == null ? void 0 : host2.getActiveObject) == null ? void 0 : _a2.call(host2);
10696
+ const isActiveOrInActive = !!host2 && (active === this || !!active && typeof active.contains === "function" && active.contains(this, true));
10672
10697
  GroupProto.__pixldocsOrigRenderControls.call(this, ctx, styleOverride, childrenOverride);
10673
- if (!host || !isActiveOrInActive) return;
10698
+ if (!host2 || !isActiveOrInActive) return;
10674
10699
  const drawForDescendants = (parent) => {
10675
10700
  const kids = (parent == null ? void 0 : parent._objects) || [];
10676
10701
  for (const child of kids) {
@@ -10679,7 +10704,7 @@ if (GroupProto && typeof GroupProto._renderControls === "function" && !GroupProt
10679
10704
  }
10680
10705
  if (child && child.textPath && child.textPath.preset && child.textPath.preset !== "none") {
10681
10706
  const bounds = getTextPathHitBounds(child);
10682
- if (bounds) drawTextPathBounds(ctx, child, bounds, host);
10707
+ if (bounds) drawTextPathBounds(ctx, child, bounds, host2);
10683
10708
  }
10684
10709
  }
10685
10710
  };
@@ -26547,6 +26572,11 @@ const PageCanvas = react.forwardRef(
26547
26572
  url: (element.src || element.imageUrl || "").slice(0, 200),
26548
26573
  error: error instanceof Error ? error.message : String(error)
26549
26574
  });
26575
+ recordImageLoadFailure({
26576
+ id: String(element.id ?? ""),
26577
+ url: element.src || element.imageUrl || "",
26578
+ reason: error instanceof Error ? error.message : String(error)
26579
+ });
26550
26580
  const fcNow = fabricRef.current;
26551
26581
  if (fcNow && fcNow.__pixldocsEditMode === true) {
26552
26582
  try {
@@ -27878,6 +27908,7 @@ function PreviewCanvas({
27878
27908
  const pageSettings = react.useMemo(() => {
27879
27909
  var _a3, _b3;
27880
27910
  return {
27911
+ // design-drift-ignore: artifact paper colour, not chrome
27881
27912
  backgroundColor: ((_a3 = page == null ? void 0 : page.settings) == null ? void 0 : _a3.backgroundColor) || "#ffffff",
27882
27913
  backgroundGradient: (_b3 = page == null ? void 0 : page.settings) == null ? void 0 : _b3.backgroundGradient
27883
27914
  };
@@ -32500,11 +32531,31 @@ async function resolveTemplateData(options) {
32500
32531
  ...formData ?? {}
32501
32532
  };
32502
32533
  const dynamicFields = config.dynamicFields;
32503
- if (!Array.isArray(dynamicFields) || dynamicFields.length === 0) {
32534
+ const hasBoundTable = (() => {
32535
+ let found = false;
32536
+ const walk = (nodes) => {
32537
+ var _a2, _b2;
32538
+ for (const n of nodes || []) {
32539
+ if (found) return;
32540
+ 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)) {
32541
+ found = true;
32542
+ return;
32543
+ }
32544
+ walk(n == null ? void 0 : n.children);
32545
+ }
32546
+ };
32547
+ for (const p of config.pages || []) walk(p.children);
32548
+ return found;
32549
+ })();
32550
+ const hasDynamicFields = Array.isArray(dynamicFields) && dynamicFields.length > 0;
32551
+ if (!hasDynamicFields && (hasBoundTable || repeatableSectionsInput.length > 0)) {
32552
+ console.log("[resolveTemplateData] no dynamicFields; binding via bound table / repeatable sections");
32553
+ }
32554
+ if (!hasDynamicFields && !hasBoundTable && repeatableSectionsInput.length === 0) {
32504
32555
  return { config: applyThemeIfNeeded(config), templateName: template.name || "Untitled", templateId, price: template.price ?? 0 };
32505
32556
  }
32506
32557
  const mappings = [];
32507
- for (const f of dynamicFields) {
32558
+ for (const f of dynamicFields || []) {
32508
32559
  for (const m of f.mappings || []) {
32509
32560
  mappings.push({
32510
32561
  field_key: f.id,
@@ -34340,9 +34391,22 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
34340
34391
  }
34341
34392
  return svgString;
34342
34393
  }
34343
- const resolvedPackageVersion = "0.5.497";
34394
+ const resolvedPackageVersion = "0.5.499";
34344
34395
  const PACKAGE_VERSION = resolvedPackageVersion;
34345
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.497";
34396
+ async function crPhase(name, fn) {
34397
+ const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
34398
+ const t0 = now();
34399
+ try {
34400
+ return await fn();
34401
+ } finally {
34402
+ const g = globalThis;
34403
+ const bag = g.__CR_PHASES__ || (g.__CR_PHASES__ = {});
34404
+ const cur = bag[name] || (bag[name] = { count: 0, ms: 0 });
34405
+ cur.count += 1;
34406
+ cur.ms += Math.round(now() - t0);
34407
+ }
34408
+ }
34409
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.499";
34346
34410
  const roundParityValue = (value) => {
34347
34411
  if (typeof value !== "number") return value;
34348
34412
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -35141,7 +35205,7 @@ class PixldocsRenderer {
35141
35205
  containers.push(container);
35142
35206
  const root = client.createRoot(container);
35143
35207
  roots.push(root);
35144
- await new Promise((resolve, reject) => {
35208
+ await crPhase("pdf_mount", () => new Promise((resolve, reject) => {
35145
35209
  const timer = setTimeout(() => reject(new Error(`PreviewCanvas onReady timeout for page ${i}`)), 3e4);
35146
35210
  root.render(
35147
35211
  react.createElement(PreviewCanvas2, {
@@ -35159,15 +35223,15 @@ class PixldocsRenderer {
35159
35223
  }
35160
35224
  })
35161
35225
  );
35162
- });
35163
- await this.waitForCanvasScene(container, cloned, i);
35226
+ }));
35227
+ await crPhase("pdf_scene1", () => this.waitForCanvasScene(container, cloned, i));
35164
35228
  const expected = this.getExpectedImageIds(cloned, i);
35165
- await this.waitForCanvasImages(container, expected);
35166
- await this.waitForStableTextMetrics(container, cloned, { clearGlobalCharCache: false });
35167
- await this.waitForCanvasScene(container, cloned, i);
35229
+ await crPhase("pdf_images", () => this.waitForCanvasImages(container, expected));
35230
+ await crPhase("pdf_text_metrics", () => this.waitForStableTextMetrics(container, cloned, { clearGlobalCharCache: false }));
35231
+ await crPhase("pdf_scene2", () => this.waitForCanvasScene(container, cloned, i));
35168
35232
  }
35169
35233
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
35170
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-De8UFmDy.cjs"));
35234
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-D_CxvBL-.cjs"));
35171
35235
  const prepared = preparePagesForExport(
35172
35236
  cloned.pages,
35173
35237
  canvasWidth,
@@ -35345,8 +35409,14 @@ class PixldocsRenderer {
35345
35409
  }
35346
35410
  const sceneSettled = fabricReady && allDomLoaded && canvasReady && fabricObjects.length > 0;
35347
35411
  const idleFor = Date.now() - lastProgressAt;
35348
- if (!strictById && sceneSettled && actualImageCount < expectedImageCount && idleFor >= earlyExitMs) {
35349
- if (debug) {
35412
+ const strictIdleMs = Math.max(earlyExitMs, 4e3);
35413
+ const stalled = strictById ? missingImageIds.length > 0 : actualImageCount < expectedImageCount;
35414
+ if (sceneSettled && stalled && idleFor >= (strictById ? strictIdleMs : earlyExitMs)) {
35415
+ if (strictById) {
35416
+ console.warn(
35417
+ `[canvas-renderer][asset-wait] early-exit after ${elapsed}ms with unresolved image id(s): ${missingImageIds.join(", ")} (idle=${idleFor}ms, ${summary})`
35418
+ );
35419
+ } else if (debug) {
35350
35420
  console.log(
35351
35421
  `[canvas-renderer][asset-wait] early-exit after ${elapsed}ms (idle=${idleFor}ms, ${summary})`
35352
35422
  );
@@ -35565,6 +35635,8 @@ class PixldocsRenderer {
35565
35635
  });
35566
35636
  }
35567
35637
  return new Promise((resolve, reject) => {
35638
+ const mountStartedAt = typeof performance !== "undefined" ? performance.now() : Date.now();
35639
+ let mountRecorded = false;
35568
35640
  const container = document.createElement("div");
35569
35641
  container.style.cssText = `
35570
35642
  position: fixed; left: -99999px; top: -99999px;
@@ -35629,13 +35701,22 @@ class PixldocsRenderer {
35629
35701
  });
35630
35702
  };
35631
35703
  const onReady = () => {
35632
- this.waitForCanvasScene(container, renderConfig, pageIndex).then(async () => {
35704
+ if (!mountRecorded) {
35705
+ mountRecorded = true;
35706
+ const now = typeof performance !== "undefined" ? performance.now() : Date.now();
35707
+ const g = globalThis;
35708
+ const bag = g.__CR_PHASES__ || (g.__CR_PHASES__ = {});
35709
+ const cur = bag.raster_mount || (bag.raster_mount = { count: 0, ms: 0 });
35710
+ cur.count += 1;
35711
+ cur.ms += Math.round(now - mountStartedAt);
35712
+ }
35713
+ crPhase("raster_scene1", () => this.waitForCanvasScene(container, renderConfig, pageIndex)).then(async () => {
35633
35714
  try {
35634
35715
  const fabricInstance = this.getFabricCanvasFromContainer(container);
35635
35716
  const expectedImageIds = this.getExpectedImageIds(renderConfig, pageIndex);
35636
- await this.waitForCanvasImages(container, expectedImageIds);
35637
- await this.waitForStableTextMetrics(container, renderConfig);
35638
- await this.waitForCanvasScene(container, renderConfig, pageIndex);
35717
+ await crPhase("raster_images", () => this.waitForCanvasImages(container, expectedImageIds));
35718
+ await crPhase("raster_text_metrics", () => this.waitForStableTextMetrics(container, renderConfig));
35719
+ await crPhase("raster_scene2", () => this.waitForCanvasScene(container, renderConfig, pageIndex));
35639
35720
  firstMountSettled = true;
35640
35721
  if (hasAutoShrink && lateFontSettleDetected) {
35641
35722
  console.log("[canvas-renderer][parity] late font-settle detected — remounting for auto-shrink reflow");
@@ -37518,7 +37599,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
37518
37599
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
37519
37600
  sanitizeSvgTreeForPdf(svgToDraw);
37520
37601
  try {
37521
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-De8UFmDy.cjs"));
37602
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-D_CxvBL-.cjs"));
37522
37603
  try {
37523
37604
  await logTextMeasurementDiagnostic(svgToDraw);
37524
37605
  } catch {
@@ -37622,7 +37703,7 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
37622
37703
  format: [firstPage.width, firstPage.height],
37623
37704
  compress: true
37624
37705
  });
37625
- if (title) pdf.setProperties({ title, creator: "Pixldocs" });
37706
+ if (title) pdf.setProperties({ title, creator: "PixlDocs" });
37626
37707
  const fontBaseUrl = options.fontBaseUrl ?? (typeof window !== "undefined" ? window.location.origin + "/fonts/" : "/fonts/");
37627
37708
  const { extractFontFamiliesFromSvgs: extractFontFamiliesFromSvgs2 } = await Promise.resolve().then(() => pdfFonts);
37628
37709
  const fontFamilies = extractFontFamiliesFromSvgs2(svgResults.map((s) => s.svg));
@@ -37772,8 +37853,8 @@ const DEFAULT_WATERMARK_FONT_SIZE = 18;
37772
37853
  const DEFAULT_WATERMARK_ANGLE = -30;
37773
37854
  function getWatermarkText() {
37774
37855
  try {
37775
- const host = window.location.hostname;
37776
- if (host.includes("biomaker")) return "biomaker.app";
37856
+ const host2 = window.location.hostname;
37857
+ if (host2.includes("biomaker")) return "biomaker.app";
37777
37858
  } catch {
37778
37859
  }
37779
37860
  return "pixldocs.com";
@@ -37957,4 +38038,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
37957
38038
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
37958
38039
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
37959
38040
  exports.warmTemplateFromForm = warmTemplateFromForm;
37960
- //# sourceMappingURL=index-CZm1oVfa.cjs.map
38041
+ //# sourceMappingURL=index-BgLKkRdm.cjs.map