@pixldocs/canvas-renderer 0.5.15 → 0.5.16

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.ts CHANGED
@@ -91,8 +91,7 @@ export declare function embedFontsForConfig(pdf: jsPDF, config: any, fontBaseUrl
91
91
  export declare function embedFontsInPdf(pdf: jsPDF, fontFamilies: Set<string>, fontBaseUrl: string): Promise<Set<string>>;
92
92
 
93
93
  /**
94
- * Ensure all fonts required by a fully-resolved TemplateConfig are loaded
95
- * and available to Fabric/Canvas before rendering.
94
+ * Start loading all fonts required by a fully-resolved TemplateConfig.
96
95
  *
97
96
  * This is the **single API** consumers (and the renderer internally) should
98
97
  * call to guarantee font parity with EC2 `/render-from-form`.
@@ -101,8 +100,8 @@ export declare function embedFontsInPdf(pdf: jsPDF, fontFamilies: Set<string>, f
101
100
  * 1. Walks ALL text nodes (including clones/repeatables) collecting
102
101
  * fontFamily + fontWeight + fontStyle.
103
102
  * 2. Loads each unique family via Google Fonts CSS v1 (idempotent).
104
- * 3. Explicitly loads each weight+style combo via `document.fonts.load()`.
105
- * 4. Awaits `document.fonts.ready` so Fabric never paints with fallback faces.
103
+ * 3. Kicks off each weight+style combo via `document.fonts.load()` without
104
+ * blocking render completion; late font load reflow handles final metrics.
106
105
  *
107
106
  * Idempotent — safe to call multiple times for the same config.
108
107
  */
package/dist/index.js CHANGED
@@ -2684,12 +2684,10 @@ const waitForFontsReady = async () => {
2684
2684
  if (!document.fonts) return;
2685
2685
  await withFontTimeout(document.fonts.ready, 2500);
2686
2686
  };
2687
- const DEFAULT_FONT_CHECK_TIMEOUT_MS = 3500;
2688
- const FONT_CHECK_POLL_MS = 60;
2689
2687
  const waitUntilFontsAvailable = async (fontFamilies, options) => {
2690
2688
  if (!document.fonts || fontFamilies.length === 0) return;
2691
- const timeoutMs = (options == null ? void 0 : options.timeoutMs) ?? DEFAULT_FONT_CHECK_TIMEOUT_MS;
2692
- const pollMs = (options == null ? void 0 : options.pollIntervalMs) ?? FONT_CHECK_POLL_MS;
2689
+ const timeoutMs = options == null ? void 0 : options.timeoutMs;
2690
+ const pollMs = options == null ? void 0 : options.pollIntervalMs;
2693
2691
  const deadline = Date.now() + timeoutMs;
2694
2692
  const check = () => fontFamilies.every(
2695
2693
  (f) => document.fonts.check(`16px "${f}"`) && document.fonts.check(`bold 16px "${f}"`)
@@ -11688,18 +11686,16 @@ function normalizeFontFamily(fontStack) {
11688
11686
  }
11689
11687
  const loadedFonts = /* @__PURE__ */ new Set();
11690
11688
  const loadingPromises = /* @__PURE__ */ new Map();
11691
- async function withTimeout(promise, timeoutMs = 4e3) {
11689
+ function withTimeout(promise, timeoutMs = 4e3) {
11692
11690
  let timeoutId;
11693
- try {
11694
- return await Promise.race([
11695
- promise,
11696
- new Promise((resolve) => {
11697
- timeoutId = setTimeout(resolve, timeoutMs);
11698
- })
11699
- ]);
11700
- } finally {
11691
+ return Promise.race([
11692
+ promise,
11693
+ new Promise((resolve) => {
11694
+ timeoutId = setTimeout(resolve, timeoutMs);
11695
+ })
11696
+ ]).finally(() => {
11701
11697
  if (timeoutId) clearTimeout(timeoutId);
11702
- }
11698
+ });
11703
11699
  }
11704
11700
  async function loadGoogleFontCSS(rawFontFamily) {
11705
11701
  if (!rawFontFamily || typeof document === "undefined") return;
@@ -11721,10 +11717,6 @@ async function loadGoogleFontCSS(rawFontFamily) {
11721
11717
  link.onerror = () => reject(new Error(`Failed to load font: ${fontFamily}`));
11722
11718
  document.head.appendChild(link);
11723
11719
  });
11724
- if (document.fonts) {
11725
- await withTimeout(document.fonts.load(`16px "${fontFamily}"`), 2500);
11726
- await withTimeout(document.fonts.ready, 2500);
11727
- }
11728
11720
  loadedFonts.add(fontFamily);
11729
11721
  } catch (e) {
11730
11722
  console.warn(`[@pixldocs/canvas-renderer] Font load failed: ${fontFamily}`, e);
@@ -11836,17 +11828,15 @@ async function ensureFontsForResolvedConfig(config) {
11836
11828
  if (typeof document === "undefined") return;
11837
11829
  const descriptors = collectFontDescriptorsFromConfig(config);
11838
11830
  const families = new Set(descriptors.map((d) => d.family));
11839
- await withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 8e3);
11831
+ void withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 2500);
11840
11832
  if (document.fonts) {
11841
- const loadPromises = descriptors.map((d) => {
11833
+ descriptors.forEach((d) => {
11842
11834
  const stylePrefix = d.style === "italic" ? "italic " : "";
11843
11835
  const weightStr = String(d.weight);
11844
11836
  const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
11845
- return document.fonts.load(spec).catch(() => {
11837
+ document.fonts.load(spec).catch(() => {
11846
11838
  });
11847
11839
  });
11848
- await withTimeout(Promise.all(loadPromises), 8e3);
11849
- await withTimeout(document.fonts.ready, 2500);
11850
11840
  }
11851
11841
  }
11852
11842
  function PixldocsPreview(props) {
@@ -12630,14 +12620,8 @@ class PixldocsRenderer {
12630
12620
  return null;
12631
12621
  }
12632
12622
  async waitForStableTextMetrics(container, config) {
12633
- var _a;
12634
12623
  if (typeof document !== "undefined") {
12635
12624
  await ensureFontsForResolvedConfig(config);
12636
- await ((_a = document.fonts) == null ? void 0 : _a.ready);
12637
- const fontFamilies = [...collectFontsFromConfig(config)].filter(Boolean);
12638
- if (fontFamilies.length > 0) {
12639
- await waitUntilFontsAvailable(fontFamilies, { timeoutMs: 4e3, pollIntervalMs: 50 });
12640
- }
12641
12625
  }
12642
12626
  const fabricInstance = this.getFabricCanvasFromContainer(container);
12643
12627
  if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;
@@ -12647,9 +12631,9 @@ class PixldocsRenderer {
12647
12631
  clearMeasurementCache();
12648
12632
  };
12649
12633
  const reflowTextboxes = () => {
12650
- var _a2, _b, _c;
12634
+ var _a, _b, _c;
12651
12635
  const walk = (obj) => {
12652
- var _a3, _b2, _c2, _d;
12636
+ var _a2, _b2, _c2, _d;
12653
12637
  if (!obj) return;
12654
12638
  const children = Array.isArray(obj._objects) ? obj._objects : Array.isArray(obj.objects) ? obj.objects : [];
12655
12639
  if (children.length) children.forEach(walk);
@@ -12661,8 +12645,8 @@ class PixldocsRenderer {
12661
12645
  scaleY: obj.scaleY
12662
12646
  };
12663
12647
  const resetTextboxLayoutInternals = () => {
12664
- var _a4;
12665
- (_a4 = obj._clearCache) == null ? void 0 : _a4.call(obj);
12648
+ var _a3;
12649
+ (_a3 = obj._clearCache) == null ? void 0 : _a3.call(obj);
12666
12650
  obj.__charBounds = [];
12667
12651
  obj.__lineWidths = [];
12668
12652
  obj.__lineHeights = [];
@@ -12676,7 +12660,7 @@ class PixldocsRenderer {
12676
12660
  resetTextboxLayoutInternals();
12677
12661
  obj.initDimensions();
12678
12662
  if (saved.width != null) {
12679
- (_a3 = obj.set) == null ? void 0 : _a3.call(obj, {
12663
+ (_a2 = obj.set) == null ? void 0 : _a2.call(obj, {
12680
12664
  width: saved.width,
12681
12665
  scaleX: saved.scaleX,
12682
12666
  scaleY: saved.scaleY
@@ -12695,7 +12679,7 @@ class PixldocsRenderer {
12695
12679
  }
12696
12680
  };
12697
12681
  fabricInstance.getObjects().forEach(walk);
12698
- (_a2 = fabricInstance.calcOffset) == null ? void 0 : _a2.call(fabricInstance);
12682
+ (_a = fabricInstance.calcOffset) == null ? void 0 : _a.call(fabricInstance);
12699
12683
  (_b = fabricInstance.renderAll) == null ? void 0 : _b.call(fabricInstance);
12700
12684
  (_c = fabricInstance.requestRenderAll) == null ? void 0 : _c.call(fabricInstance);
12701
12685
  };