@pixldocs/canvas-renderer 0.5.187 → 0.5.188

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/README.md CHANGED
@@ -556,3 +556,13 @@ const exportConfig = injectPreviewBlur(resolvedConfig, {
556
556
 
557
557
  Same resolution path as the live preview — so the on-screen overlay and
558
558
  the downloaded PNG/PDF blur exactly the same elements.
559
+
560
+ #### Parity note
561
+
562
+ The pixldocs.com **Use page** (the in-app paid-template preview, including
563
+ the Biodata preset's 🔒 per-field checkboxes) and external consumers
564
+ (BioMaker, etc.) both call **the same `resolveBlurElementExactIdsFromFlatFormKeys`**
565
+ function — there is now exactly one resolver shared across the entire
566
+ stack. Anything that blurs correctly in one place blurs identically in
567
+ the other; visual/UX bugs introduced in one pipeline cannot diverge
568
+ silently from the other.
@@ -16133,10 +16133,122 @@ async function getTemplateForm(options) {
16133
16133
  initialSectionState
16134
16134
  };
16135
16135
  }
16136
+ const OVERLAY_ID_PREFIX = "__pb_";
16137
+ function getNumber(v, fallback = 0) {
16138
+ return typeof v === "number" && Number.isFinite(v) ? v : fallback;
16139
+ }
16140
+ function resolveSize(node, key) {
16141
+ const v = node == null ? void 0 : node[key];
16142
+ if (typeof v === "number" && Number.isFinite(v)) return v;
16143
+ return 0;
16144
+ }
16145
+ function collectOverlays(node, parentLeft, parentTop, inheritedBlur, extraBaseIds, extraExactIds, out) {
16146
+ if (!node || typeof node !== "object") return;
16147
+ const matchesBase = !!(extraBaseIds && typeof node.id === "string" && extraBaseIds.has(baseId(node.id)));
16148
+ const matchesExact = !!(extraExactIds && typeof node.id === "string" && extraExactIds.has(node.id));
16149
+ const isBlurred = inheritedBlur || node.previewBlur === true || matchesBase || matchesExact;
16150
+ const absLeft = parentLeft + getNumber(node.left, 0);
16151
+ const absTop = parentTop + getNumber(node.top, 0);
16152
+ if (node.type === "group") {
16153
+ const children = node.children || node.elements;
16154
+ if (Array.isArray(children)) {
16155
+ for (const child of children) {
16156
+ collectOverlays(child, absLeft, absTop, isBlurred, extraBaseIds, extraExactIds, out);
16157
+ }
16158
+ }
16159
+ return;
16160
+ }
16161
+ if (!isBlurred) return;
16162
+ const scaleX = getNumber(node.scaleX, 1) || 1;
16163
+ const scaleY = getNumber(node.scaleY, 1) || 1;
16164
+ const w = Math.max(4, resolveSize(node, "width") * scaleX);
16165
+ const h = Math.max(4, resolveSize(node, "height") * scaleY);
16166
+ out.push({
16167
+ left: absLeft,
16168
+ top: absTop,
16169
+ width: w,
16170
+ height: h,
16171
+ hintFill: typeof node.fill === "string" ? node.fill : void 0
16172
+ });
16173
+ }
16174
+ function parseColor$1(c) {
16175
+ if (!c) return null;
16176
+ const s = c.trim();
16177
+ const hex = s.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
16178
+ if (hex) {
16179
+ let h = hex[1];
16180
+ if (h.length === 3) h = h.split("").map((x) => x + x).join("");
16181
+ return {
16182
+ r: parseInt(h.slice(0, 2), 16),
16183
+ g: parseInt(h.slice(2, 4), 16),
16184
+ b: parseInt(h.slice(4, 6), 16)
16185
+ };
16186
+ }
16187
+ const rgb = s.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
16188
+ if (rgb) return { r: +rgb[1], g: +rgb[2], b: +rgb[3] };
16189
+ return null;
16190
+ }
16191
+ function buildOverlay(b, idx) {
16192
+ const c = parseColor$1(b.hintFill);
16193
+ const lum = c ? (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) / 255 : 0.2;
16194
+ const isLightGlass = lum < 0.5;
16195
+ const baseFill = isLightGlass ? "rgba(245,245,245,0.68)" : "rgba(30,30,30,0.62)";
16196
+ return {
16197
+ id: `${OVERLAY_ID_PREFIX}${idx}`,
16198
+ type: "shape",
16199
+ shapeType: "rounded-rect",
16200
+ left: b.left,
16201
+ top: b.top,
16202
+ width: b.width,
16203
+ height: b.height,
16204
+ cornerRadius: 0,
16205
+ fill: baseFill,
16206
+ stroke: "transparent",
16207
+ strokeWidth: 0,
16208
+ opacity: 1,
16209
+ selectable: false,
16210
+ locked: true,
16211
+ visible: true,
16212
+ scaleX: 1,
16213
+ scaleY: 1
16214
+ };
16215
+ }
16216
+ function injectPreviewBlur(config, options) {
16217
+ const cloned = typeof structuredClone === "function" ? structuredClone(config) : JSON.parse(JSON.stringify(config));
16218
+ const extraBase = (options == null ? void 0 : options.extraElementBaseIds) && options.extraElementBaseIds.size > 0 ? options.extraElementBaseIds : void 0;
16219
+ const extraExact = (options == null ? void 0 : options.extraElementExactIds) && options.extraElementExactIds.size > 0 ? options.extraElementExactIds : void 0;
16220
+ let idx = 0;
16221
+ for (const page of cloned.pages || []) {
16222
+ const children = page.children || page.elements;
16223
+ if (!Array.isArray(children)) continue;
16224
+ const overlays = [];
16225
+ for (const child of children) {
16226
+ collectOverlays(child, 0, 0, false, extraBase, extraExact, overlays);
16227
+ }
16228
+ if (overlays.length === 0) continue;
16229
+ for (const b of overlays) {
16230
+ children.push(buildOverlay(b, idx++));
16231
+ }
16232
+ }
16233
+ return cloned;
16234
+ }
16235
+ function hasAnyPreviewBlur(config) {
16236
+ function walk(node) {
16237
+ if (!node || typeof node !== "object") return false;
16238
+ if (node.previewBlur === true) return true;
16239
+ const children = node.children || node.elements;
16240
+ if (Array.isArray(children)) {
16241
+ for (const c of children) if (walk(c)) return true;
16242
+ }
16243
+ return false;
16244
+ }
16245
+ for (const page of config.pages || []) if (walk(page)) return true;
16246
+ return false;
16247
+ }
16136
16248
  function stripFieldPrefix(s) {
16137
16249
  return s.startsWith("field_") ? s.slice("field_".length) : s;
16138
16250
  }
16139
- function addAll(val, out) {
16251
+ function addAllToSet(val, out) {
16140
16252
  if (!val) return false;
16141
16253
  if (Array.isArray(val)) {
16142
16254
  for (const v of val) out.add(v);
@@ -16165,12 +16277,18 @@ function resolveBlurElementExactIdsFromFlatFormKeys(config, flatFormKeys, option
16165
16277
  }
16166
16278
  for (const k of candidates) {
16167
16279
  if (k in cloneIdMap) {
16168
- if (addAll(cloneIdMap[k], out)) break;
16280
+ if (addAllToSet(cloneIdMap[k], out)) break;
16169
16281
  }
16170
16282
  }
16171
16283
  }
16172
16284
  return Array.from(out);
16173
16285
  }
16286
+ const previewBlur = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
16287
+ __proto__: null,
16288
+ hasAnyPreviewBlur,
16289
+ injectPreviewBlur,
16290
+ resolveBlurElementExactIdsFromFlatFormKeys
16291
+ }, Symbol.toStringTag, { value: "Module" }));
16174
16292
  const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
16175
16293
  function computeFontSignature(config) {
16176
16294
  var _a;
@@ -16651,9 +16769,9 @@ function captureFabricCanvasSvgForPdf(fabricInstance, canvasWidth, canvasHeight)
16651
16769
  }
16652
16770
  return svgString;
16653
16771
  }
16654
- const resolvedPackageVersion = "0.5.187";
16772
+ const resolvedPackageVersion = "0.5.188";
16655
16773
  const PACKAGE_VERSION = resolvedPackageVersion;
16656
- const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.187";
16774
+ const DEPLOYMENT_VERSION_MARKER = "__PIXLDOCS_CANVAS_RENDERER_VERSION__:0.5.188";
16657
16775
  const roundParityValue = (value) => {
16658
16776
  if (typeof value !== "number") return value;
16659
16777
  return Number.isFinite(value) ? Number(value.toFixed(3)) : value;
@@ -17161,7 +17279,7 @@ class PixldocsRenderer {
17161
17279
  await this.waitForCanvasScene(container, cloned, i);
17162
17280
  }
17163
17281
  console.log(`[canvas-renderer][pdf-unified] mounted ${cloned.pages.length} page(s), handing off to client exportMultiPagePdf`);
17164
- const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-BknzMTNP.cjs"));
17282
+ const { exportMultiPagePdf, preparePagesForExport } = await Promise.resolve().then(() => require("./vectorPdfExport-B2Cf-9eT.cjs"));
17165
17283
  const prepared = preparePagesForExport(
17166
17284
  cloned.pages,
17167
17285
  canvasWidth,
@@ -18003,7 +18121,7 @@ function collectFontSpecsFromMarkup(markup) {
18003
18121
  }
18004
18122
  return Array.from(specs);
18005
18123
  }
18006
- function parseColor$1(color) {
18124
+ function parseColor(color) {
18007
18125
  if (!color) return null;
18008
18126
  const raw = color.trim().toLowerCase();
18009
18127
  if (!raw || raw === "transparent" || raw === "none") return null;
@@ -18556,7 +18674,7 @@ function stripSuspiciousFullPageOverlayNodes(svg) {
18556
18674
  if (!(pageWidth > 0 && pageHeight > 0)) return;
18557
18675
  const isNear = (a, b, tolerance = 0.75) => Math.abs(a - b) <= tolerance;
18558
18676
  const isDarkPaint = (value) => {
18559
- const rgb = value ? parseColor$1(value) : null;
18677
+ const rgb = value ? parseColor(value) : null;
18560
18678
  return rgb ? rgb.r <= 32 && rgb.g <= 32 && rgb.b <= 32 : false;
18561
18679
  };
18562
18680
  const removeIfSuspicious = (el) => {
@@ -18669,13 +18787,13 @@ function inlineComputedStyles(svg) {
18669
18787
  const fill = cs.fill;
18670
18788
  const stroke = cs.stroke;
18671
18789
  if (fill && fill !== "none" && fill !== "rgba(0, 0, 0, 0)") {
18672
- const parsed = parseColor$1(fill);
18790
+ const parsed = parseColor(fill);
18673
18791
  if (parsed) el.setAttribute("fill", rgbToHex(parsed.r, parsed.g, parsed.b));
18674
18792
  } else if (fill === "rgba(0, 0, 0, 0)" || fill === "transparent") {
18675
18793
  el.setAttribute("fill", "none");
18676
18794
  }
18677
18795
  if (stroke && stroke !== "none" && stroke !== "rgba(0, 0, 0, 0)") {
18678
- const parsed = parseColor$1(stroke);
18796
+ const parsed = parseColor(stroke);
18679
18797
  if (parsed) el.setAttribute("stroke", rgbToHex(parsed.r, parsed.g, parsed.b));
18680
18798
  }
18681
18799
  }
@@ -18823,7 +18941,7 @@ function setPdfColorFromSvg(pdf, svg, _elementId) {
18823
18941
  const { fill, stroke } = getFirstExplicitColorFromSvg(svg);
18824
18942
  const setColor = (hex, setter) => {
18825
18943
  if (!hex) return;
18826
- const c = parseColor$1(hex);
18944
+ const c = parseColor(hex);
18827
18945
  if (c) pdf[setter](c.r, c.g, c.b);
18828
18946
  };
18829
18947
  setColor(fill, "setFillColor");
@@ -19306,7 +19424,7 @@ async function prepareLiveCanvasSvgForPdf(rawSvg, pageWidth, pageHeight, pageKey
19306
19424
  if (options == null ? void 0 : options.stripPageBackground) stripRootPageBackgroundFromSvg(svgToDraw);
19307
19425
  sanitizeSvgTreeForPdf(svgToDraw);
19308
19426
  try {
19309
- const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-BknzMTNP.cjs"));
19427
+ const { bakeTextAnchorPositionsFromLiveSvg, logTextMeasurementDiagnostic } = await Promise.resolve().then(() => require("./vectorPdfExport-B2Cf-9eT.cjs"));
19310
19428
  try {
19311
19429
  await logTextMeasurementDiagnostic(svgToDraw);
19312
19430
  } catch {
@@ -19326,7 +19444,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
19326
19444
  if (backgroundGradient && ((_a = backgroundGradient.stops) == null ? void 0 : _a.length) >= 2) {
19327
19445
  const grad = backgroundGradient;
19328
19446
  const colorStops = grad.stops.map((s) => {
19329
- const c = parseColor$1(s.color);
19447
+ const c = parseColor(s.color);
19330
19448
  return {
19331
19449
  offset: Math.max(0, Math.min(1, Number(s.offset))),
19332
19450
  color: c ? [c.r, c.g, c.b] : [0, 0, 0]
@@ -19382,7 +19500,7 @@ function drawPageBackground(pdf, pageIndex, pageWidth, pageHeight, backgroundCol
19382
19500
  pdf.rect(0, 0, pageWidth, pageHeight, "F");
19383
19501
  }
19384
19502
  } else {
19385
- const bgColor = parseColor$1(backgroundColor && backgroundColor !== "transparent" ? backgroundColor : "#ffffff");
19503
+ const bgColor = parseColor(backgroundColor && backgroundColor !== "transparent" ? backgroundColor : "#ffffff");
19386
19504
  if (bgColor) {
19387
19505
  pdf.setFillColor(bgColor.r, bgColor.g, bgColor.b);
19388
19506
  pdf.rect(0, 0, pageWidth, pageHeight, "F");
@@ -19505,123 +19623,6 @@ async function assemblePdfFromSvgs(svgResults, options = {}) {
19505
19623
  pages: svgResults.map((p) => ({ width: p.width, height: p.height }))
19506
19624
  };
19507
19625
  }
19508
- const OVERLAY_ID_PREFIX = "__pb_";
19509
- function getNumber(v, fallback = 0) {
19510
- return typeof v === "number" && Number.isFinite(v) ? v : fallback;
19511
- }
19512
- function resolveSize(node, key) {
19513
- const v = node == null ? void 0 : node[key];
19514
- if (typeof v === "number" && Number.isFinite(v)) return v;
19515
- return 0;
19516
- }
19517
- function collectOverlays(node, parentLeft, parentTop, inheritedBlur, extraBaseIds, extraExactIds, out) {
19518
- if (!node || typeof node !== "object") return;
19519
- const matchesBase = !!(extraBaseIds && typeof node.id === "string" && extraBaseIds.has(baseId(node.id)));
19520
- const matchesExact = !!(extraExactIds && typeof node.id === "string" && extraExactIds.has(node.id));
19521
- const isBlurred = inheritedBlur || node.previewBlur === true || matchesBase || matchesExact;
19522
- const absLeft = parentLeft + getNumber(node.left, 0);
19523
- const absTop = parentTop + getNumber(node.top, 0);
19524
- if (node.type === "group") {
19525
- const children = node.children || node.elements;
19526
- if (Array.isArray(children)) {
19527
- for (const child of children) {
19528
- collectOverlays(child, absLeft, absTop, isBlurred, extraBaseIds, extraExactIds, out);
19529
- }
19530
- }
19531
- return;
19532
- }
19533
- if (!isBlurred) return;
19534
- const scaleX = getNumber(node.scaleX, 1) || 1;
19535
- const scaleY = getNumber(node.scaleY, 1) || 1;
19536
- const w = Math.max(4, resolveSize(node, "width") * scaleX);
19537
- const h = Math.max(4, resolveSize(node, "height") * scaleY);
19538
- out.push({
19539
- left: absLeft,
19540
- top: absTop,
19541
- width: w,
19542
- height: h,
19543
- hintFill: typeof node.fill === "string" ? node.fill : void 0
19544
- });
19545
- }
19546
- function parseColor(c) {
19547
- if (!c) return null;
19548
- const s = c.trim();
19549
- const hex = s.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
19550
- if (hex) {
19551
- let h = hex[1];
19552
- if (h.length === 3) h = h.split("").map((x) => x + x).join("");
19553
- return {
19554
- r: parseInt(h.slice(0, 2), 16),
19555
- g: parseInt(h.slice(2, 4), 16),
19556
- b: parseInt(h.slice(4, 6), 16)
19557
- };
19558
- }
19559
- const rgb = s.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
19560
- if (rgb) return { r: +rgb[1], g: +rgb[2], b: +rgb[3] };
19561
- return null;
19562
- }
19563
- function buildOverlay(b, idx) {
19564
- const c = parseColor(b.hintFill);
19565
- const lum = c ? (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) / 255 : 0.2;
19566
- const isLightGlass = lum < 0.5;
19567
- const baseFill = isLightGlass ? "rgba(245,245,245,0.68)" : "rgba(30,30,30,0.62)";
19568
- return {
19569
- id: `${OVERLAY_ID_PREFIX}${idx}`,
19570
- type: "shape",
19571
- shapeType: "rounded-rect",
19572
- left: b.left,
19573
- top: b.top,
19574
- width: b.width,
19575
- height: b.height,
19576
- cornerRadius: 0,
19577
- fill: baseFill,
19578
- stroke: "transparent",
19579
- strokeWidth: 0,
19580
- opacity: 1,
19581
- selectable: false,
19582
- locked: true,
19583
- visible: true,
19584
- scaleX: 1,
19585
- scaleY: 1
19586
- };
19587
- }
19588
- function injectPreviewBlur(config, options) {
19589
- const cloned = typeof structuredClone === "function" ? structuredClone(config) : JSON.parse(JSON.stringify(config));
19590
- const extraBase = (options == null ? void 0 : options.extraElementBaseIds) && options.extraElementBaseIds.size > 0 ? options.extraElementBaseIds : void 0;
19591
- const extraExact = (options == null ? void 0 : options.extraElementExactIds) && options.extraElementExactIds.size > 0 ? options.extraElementExactIds : void 0;
19592
- let idx = 0;
19593
- for (const page of cloned.pages || []) {
19594
- const children = page.children || page.elements;
19595
- if (!Array.isArray(children)) continue;
19596
- const overlays = [];
19597
- for (const child of children) {
19598
- collectOverlays(child, 0, 0, false, extraBase, extraExact, overlays);
19599
- }
19600
- if (overlays.length === 0) continue;
19601
- for (const b of overlays) {
19602
- children.push(buildOverlay(b, idx++));
19603
- }
19604
- }
19605
- return cloned;
19606
- }
19607
- function hasAnyPreviewBlur(config) {
19608
- function walk(node) {
19609
- if (!node || typeof node !== "object") return false;
19610
- if (node.previewBlur === true) return true;
19611
- const children = node.children || node.elements;
19612
- if (Array.isArray(children)) {
19613
- for (const c of children) if (walk(c)) return true;
19614
- }
19615
- return false;
19616
- }
19617
- for (const page of config.pages || []) if (walk(page)) return true;
19618
- return false;
19619
- }
19620
- const previewBlur = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
19621
- __proto__: null,
19622
- hasAnyPreviewBlur,
19623
- injectPreviewBlur
19624
- }, Symbol.toStringTag, { value: "Module" }));
19625
19626
  const SELECT_COLUMNS = "id,name,description,category,thumbnail_url,preview_images,price,download_count,workspace_id,sort_order,created_at,updated_at";
19626
19627
  async function listPublishedTemplates(options) {
19627
19628
  const { workspaceId, supabaseUrl, supabaseAnonKey, category, limit = 200, offset = 0 } = options;
@@ -19819,4 +19820,4 @@ exports.setAutoShrinkDebug = setAutoShrinkDebug;
19819
19820
  exports.setBundledAssetPrefixes = setBundledAssetPrefixes;
19820
19821
  exports.warmResolvedTemplateForPreview = warmResolvedTemplateForPreview;
19821
19822
  exports.warmTemplateFromForm = warmTemplateFromForm;
19822
- //# sourceMappingURL=index-DgMi1JSR.cjs.map
19823
+ //# sourceMappingURL=index-0rk-MRGy.cjs.map