@json-to-office/core-docx 0.30.0 → 0.31.0

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.
@@ -4442,6 +4442,26 @@ function componentHasRevision(component) {
4442
4442
  import { createHash as createHash3 } from "crypto";
4443
4443
  var componentCache = null;
4444
4444
  var cacheKeyGen = null;
4445
+ var bypassStats = /* @__PURE__ */ new Map();
4446
+ function recordBypass(type, reason) {
4447
+ const entry = bypassStats.get(type);
4448
+ if (entry) {
4449
+ entry.renders++;
4450
+ } else {
4451
+ bypassStats.set(type, { renders: 1, reason });
4452
+ }
4453
+ }
4454
+ var DATE_INDEPENDENT_PLACEHOLDERS = /* @__PURE__ */ new Set(["PAGE", "TOTAL_PAGES"]);
4455
+ function usesDateSensitivePlaceholder(serialized) {
4456
+ const placeholderRegex = /\{([^}{]+)\}/g;
4457
+ let match;
4458
+ while ((match = placeholderRegex.exec(serialized)) !== null) {
4459
+ const name = match[1].toUpperCase();
4460
+ if (DATE_INDEPENDENT_PLACEHOLDERS.has(name)) continue;
4461
+ if (PlaceholderRegistry.has(name)) return true;
4462
+ }
4463
+ return false;
4464
+ }
4445
4465
  function createThemeHash(theme) {
4446
4466
  const themeString = JSON.stringify(theme);
4447
4467
  return createHash3("sha256").update(themeString).digest("hex").substring(0, 8);
@@ -4477,22 +4497,31 @@ function initializeComponentCache(cache) {
4477
4497
  }
4478
4498
  }
4479
4499
  async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
4480
- const forceBypassForType = component.name === "toc" || component.name === "section" || component.name === "visual" || component.name === "heading" || // Both explicit lists and markdown-list paragraphs register numbering in
4481
- // the current document scope. Cached paragraphs can otherwise reference
4482
- // definitions that only existed in a previous render.
4483
- component.name === "list" || component.name === "paragraph" || "id" in component || componentHasRevision(component);
4500
+ const bypassReason = componentHasRevision(
4501
+ component
4502
+ ) ? "revision-ids" : "id" in component ? "bookmark-id" : component.name === "toc" || component.name === "section" || component.name === "visual" || component.name === "heading" || // Both explicit lists and markdown-list paragraphs register
4503
+ // numbering in the current document scope. Cached paragraphs can
4504
+ // otherwise reference definitions that only existed in a previous
4505
+ // render.
4506
+ component.name === "list" || component.name === "paragraph" ? "dynamic-context" : null;
4484
4507
  if (!componentCache) {
4485
4508
  initializeComponentCache();
4486
4509
  }
4487
- if (!componentCache || bypassCache || forceBypassForType || !componentCache.getConfig().enabled) {
4510
+ if (bypassReason !== null) {
4511
+ recordBypass(component.name, bypassReason);
4512
+ return renderComponent(component, theme, themeName, context);
4513
+ }
4514
+ if (!componentCache || bypassCache || !componentCache.getConfig().enabled) {
4488
4515
  return renderComponent(component, theme, themeName, context);
4489
4516
  }
4490
4517
  const componentProps = JSON.stringify(component.props || {});
4491
4518
  const themeHash = createThemeHash(theme);
4492
4519
  const contextKey = context?.section ? `${context.section.currentLayout}:${context.section.columnCount}` : "no-section";
4493
- const generationDateKey = getGenerationDate().toISOString();
4494
4520
  const baseDirKey = getBaseDir() ?? "";
4495
4521
  const childrenKey = "children" in component && component.children ? `:children:${JSON.stringify(component.children)}` : "";
4522
+ const generationDateKey = usesDateSensitivePlaceholder(
4523
+ componentProps + childrenKey
4524
+ ) ? getGenerationDate().toISOString() : "no-date";
4496
4525
  const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${baseDirKey}:${componentProps}${childrenKey}`;
4497
4526
  const cached = await componentCache.get(cacheKey);
4498
4527
  if (cached) {
@@ -7355,6 +7384,11 @@ function createLimiter(max) {
7355
7384
  var DEFAULT_FALLBACK_CONCURRENCY = 4;
7356
7385
  var BATCH_TIMEOUT_BASE_MS = 3e4;
7357
7386
  var BATCH_TIMEOUT_PER_SLIDE_MS = 1e4;
7387
+ var prepassStats = {
7388
+ documents: 0,
7389
+ collected: 0,
7390
+ unique: 0
7391
+ };
7358
7392
  function collectVisualProps(root) {
7359
7393
  const found = [];
7360
7394
  const seen = /* @__PURE__ */ new WeakSet();
@@ -7431,6 +7465,9 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
7431
7465
  }
7432
7466
  }
7433
7467
  if (targets.size === 0) return map;
7468
+ prepassStats.documents++;
7469
+ prepassStats.collected += visuals.length;
7470
+ prepassStats.unique += targets.size;
7434
7471
  const unique = [...targets.values()];
7435
7472
  const limit = createLimiter(
7436
7473
  Math.max(1, options.concurrency ?? DEFAULT_FALLBACK_CONCURRENCY)