@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.
@@ -6,6 +6,28 @@ import { Paragraph, Table, TableOfContents, Textbox } from 'docx';
6
6
  import { ComponentDefinition, RenderContext } from '../types';
7
7
  import { ThemeConfig } from '../styles';
8
8
  import { MemoryCache } from '../cache';
9
+ /** Why a component type is never cached (see renderComponentWithCache). */
10
+ export type ComponentBypassReason = 'dynamic-context' | 'bookmark-id' | 'revision-ids';
11
+ export interface ComponentBypassStats {
12
+ /** Component type name. */
13
+ type: string;
14
+ /** Renders that skipped the cache by design. */
15
+ renders: number;
16
+ /** The (first observed) reason this type bypasses the cache. */
17
+ reason: ComponentBypassReason;
18
+ }
19
+ /**
20
+ * Get per-type "uncached by design" render counters.
21
+ */
22
+ export declare function getComponentBypassStats(): ComponentBypassStats[];
23
+ /**
24
+ * True when the serialized props/children reference a registered placeholder
25
+ * whose output can vary with the generation date. Components without one
26
+ * render identically across dates, so their cache keys must not embed the
27
+ * per-render timestamp — that's what made cross-render hits impossible for
28
+ * date-less documents (#156).
29
+ */
30
+ export declare function usesDateSensitivePlaceholder(serialized: string): boolean;
9
31
  /**
10
32
  * Initialize the component cache
11
33
  */
@@ -32,9 +54,25 @@ export declare function warmComponentCache(components: Array<{
32
54
  context: RenderContext;
33
55
  }>): Promise<void>;
34
56
  /**
35
- * Get component cache statistics
57
+ * Get component cache statistics, extended with per-type "uncached by
58
+ * design" render counters (#156). The bypass counters exist even before the
59
+ * cache is initialized — a document full of bypassed types never triggers
60
+ * initialization, yet its renders are exactly what needs surfacing.
36
61
  */
37
- export declare function getComponentCacheStats(): import("@json-to-office/shared/cache").CacheStatistics | null;
62
+ export declare function getComponentCacheStats(): {
63
+ bypassedComponents: ComponentBypassStats[];
64
+ } | {
65
+ bypassedComponents: ComponentBypassStats[];
66
+ entries: number;
67
+ totalSize: number;
68
+ hitRate: number;
69
+ missRate: number;
70
+ totalHits: number;
71
+ totalMisses: number;
72
+ avgResponseTime: number;
73
+ evictions: number;
74
+ componentStats: Map<string, import("@json-to-office/shared/cache").ComponentStatistics>;
75
+ } | null;
38
76
  /**
39
77
  * Export component cache for persistence
40
78
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cached-render.d.ts","sourceRoot":"","sources":["../../src/core/cached-render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,WAAW,EAIZ,MAAM,UAAU,CAAC;AAoBlB;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CA4BlE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAIzD;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,WAAW,UAAQ,GAClB,OAAO,CAAC,CAAC,SAAS,GAAG,KAAK,GAAG,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC,CAyG5D;AAKD;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,KAAK,CAAC;IAChB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC,GACD,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;GAEG;AACH,wBAAgB,sBAAsB,kEAMrC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,GAAG,CACvD,MAAM,EACN,OAAO,CACR,GAAG,IAAI,CAAC,CAgBR;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GACzB,OAAO,CAAC,IAAI,CAAC,CAQf"}
1
+ {"version":3,"file":"cached-render.d.ts","sourceRoot":"","sources":["../../src/core/cached-render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,WAAW,EAIZ,MAAM,UAAU,CAAC;AAWlB,2EAA2E;AAC3E,MAAM,MAAM,qBAAqB,GAC7B,iBAAiB,GACjB,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,oBAAoB;IACnC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,EAAE,qBAAqB,CAAC;CAC/B;AAwBD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,EAAE,CAMhE;AAUD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CASxE;AAYD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CA4BlE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,GAAG,IAAI,CAEtD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKzD;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,WAAW,UAAQ,GAClB,OAAO,CAAC,CAAC,SAAS,GAAG,KAAK,GAAG,eAAe,GAAG,OAAO,CAAC,EAAE,CAAC,CAuH5D;AAKD;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,KAAK,CAAC;IAChB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC,GACD,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB;;;;;;;;;;;;;SAOrC;AAED;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,GAAG,CACvD,MAAM,EACN,OAAO,CACR,GAAG,IAAI,CAAC,CAgBR;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GACzB,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -23,6 +23,22 @@ export interface PrerasterizeOptions {
23
23
  /** Max concurrent per-visual fallback rasterizations (default 4). */
24
24
  concurrency?: number;
25
25
  }
26
+ /** Cumulative pre-pass counters for cache observability (#156). */
27
+ export interface VisualPrepassStats {
28
+ /** Documents that entered the pre-pass with at least one visual. */
29
+ documents: number;
30
+ /** Enabled visuals collected across those documents. */
31
+ collected: number;
32
+ /** Unique rasterization units after dedupe (identical content+dpi). */
33
+ unique: number;
34
+ }
35
+ /**
36
+ * Get cumulative per-document pre-pass counters. `collected - unique` is the
37
+ * work the dedupe saved — the `visual` cache benefit the component cache
38
+ * stats can never show, since `visual` bypasses that cache by design.
39
+ */
40
+ export declare function getVisualPrepassStats(): VisualPrepassStats;
41
+ export declare function resetVisualPrepassStats(): void;
26
42
  /**
27
43
  * Collect the props of every enabled `visual` component reachable from
28
44
  * `root`. The walk is generic — every array element and object value is
@@ -1 +1 @@
1
- {"version":3,"file":"prerasterizeVisuals.d.ts","sourceRoot":"","sources":["../../src/core/prerasterizeVisuals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EAEtB,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAkB/D,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,EAAE,CA4B/D;AAsDD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,iBAAiB,GAAG,SAAS,EAC5C,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC,CAmJrD"}
1
+ {"version":3,"file":"prerasterizeVisuals.d.ts","sourceRoot":"","sources":["../../src/core/prerasterizeVisuals.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAIL,KAAK,iBAAiB,EAEtB,KAAK,6BAA6B,EACnC,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAkB/D,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mEAAmE;AACnE,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,SAAS,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;CAChB;AAQD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,kBAAkB,CAE1D;AAED,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AASD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,EAAE,CA4B/D;AAsDD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,iBAAiB,GAAG,SAAS,EAC5C,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC,CAuJrD"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,8 @@ export declare function getCoreVersion(): string;
2
2
  export { generateDocument, generateFromConfig, generateDocumentFromJson, generateDocumentFromFile, generateBufferFromJson, generateBufferFromFile, generateAndSaveFromJson, generateAndSaveFromFile, validateJsonSchema, isReportComponentDefinition, saveDocument, generateAndSave, DocumentGenerator as CoreDocumentGenerator, } from './core/generator';
3
3
  export { flattenVisuals, type FlattenVisualsOptions, } from './core/flattenVisuals';
4
4
  export { MemoryCache, CacheKeyGenerator, DEFAULT_CACHE_CONFIG, getCacheConfigFromEnv, mergeConfigs, ComponentCacheAnalytics, type CacheConfiguration, type CachedComponent, type CacheStatistics, type CacheKeyOptions, type CacheEvents, type CacheAnalyticsReport, type ComponentPerformanceMetrics, type ComponentCacheTrends, type CacheOptimizationRecommendation, type TimeSeriesPoint, } from './cache/index';
5
- export { initializeComponentCache, getComponentCache, clearComponentCache, getComponentCacheStats, warmComponentCache, } from './core/cached-render';
5
+ export { initializeComponentCache, getComponentCache, clearComponentCache, getComponentCacheStats, getComponentBypassStats, warmComponentCache, type ComponentBypassReason, type ComponentBypassStats, } from './core/cached-render';
6
+ export { getVisualPrepassStats, resetVisualPrepassStats, type VisualPrepassStats, } from './core/prerasterizeVisuals';
6
7
  export { isReportComponent, isSectionComponent, isHeadingComponent, isParagraphComponent, isColumnsComponent, isImageComponent, isStatisticComponent, isTableComponent, isListComponent, isHighchartsComponent, isVisualComponent, } from './types/index';
7
8
  export type { ImageContent, StatisticContent, TableData, SectionProperties, ColumnSettings, PageSizeOptions, PageMarginOptions, PageNumberOptions, PageBorderOptions, RenderContext, } from './types/index';
8
9
  export * from './utils/formatters';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4271,6 +4271,33 @@ function componentHasRevision(component) {
4271
4271
  import { createHash as createHash3 } from "crypto";
4272
4272
  var componentCache = null;
4273
4273
  var cacheKeyGen = null;
4274
+ var bypassStats = /* @__PURE__ */ new Map();
4275
+ function recordBypass(type, reason) {
4276
+ const entry = bypassStats.get(type);
4277
+ if (entry) {
4278
+ entry.renders++;
4279
+ } else {
4280
+ bypassStats.set(type, { renders: 1, reason });
4281
+ }
4282
+ }
4283
+ function getComponentBypassStats() {
4284
+ return Array.from(bypassStats.entries()).map(([type, s]) => ({
4285
+ type,
4286
+ renders: s.renders,
4287
+ reason: s.reason
4288
+ }));
4289
+ }
4290
+ var DATE_INDEPENDENT_PLACEHOLDERS = /* @__PURE__ */ new Set(["PAGE", "TOTAL_PAGES"]);
4291
+ function usesDateSensitivePlaceholder(serialized) {
4292
+ const placeholderRegex = /\{([^}{]+)\}/g;
4293
+ let match;
4294
+ while ((match = placeholderRegex.exec(serialized)) !== null) {
4295
+ const name = match[1].toUpperCase();
4296
+ if (DATE_INDEPENDENT_PLACEHOLDERS.has(name)) continue;
4297
+ if (PlaceholderRegistry.has(name)) return true;
4298
+ }
4299
+ return false;
4300
+ }
4274
4301
  function createThemeHash(theme) {
4275
4302
  const themeString = JSON.stringify(theme);
4276
4303
  return createHash3("sha256").update(themeString).digest("hex").substring(0, 8);
@@ -4312,24 +4339,34 @@ async function clearComponentCache() {
4312
4339
  if (componentCache) {
4313
4340
  await componentCache.clear();
4314
4341
  }
4342
+ bypassStats.clear();
4315
4343
  }
4316
4344
  async function renderComponentWithCache(component, theme, themeName, context, bypassCache = false) {
4317
- const forceBypassForType = component.name === "toc" || component.name === "section" || component.name === "visual" || component.name === "heading" || // Both explicit lists and markdown-list paragraphs register numbering in
4318
- // the current document scope. Cached paragraphs can otherwise reference
4319
- // definitions that only existed in a previous render.
4320
- component.name === "list" || component.name === "paragraph" || "id" in component || componentHasRevision(component);
4345
+ const bypassReason = componentHasRevision(
4346
+ component
4347
+ ) ? "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
4348
+ // numbering in the current document scope. Cached paragraphs can
4349
+ // otherwise reference definitions that only existed in a previous
4350
+ // render.
4351
+ component.name === "list" || component.name === "paragraph" ? "dynamic-context" : null;
4321
4352
  if (!componentCache) {
4322
4353
  initializeComponentCache();
4323
4354
  }
4324
- if (!componentCache || bypassCache || forceBypassForType || !componentCache.getConfig().enabled) {
4355
+ if (bypassReason !== null) {
4356
+ recordBypass(component.name, bypassReason);
4357
+ return renderComponent(component, theme, themeName, context);
4358
+ }
4359
+ if (!componentCache || bypassCache || !componentCache.getConfig().enabled) {
4325
4360
  return renderComponent(component, theme, themeName, context);
4326
4361
  }
4327
4362
  const componentProps = JSON.stringify(component.props || {});
4328
4363
  const themeHash = createThemeHash(theme);
4329
4364
  const contextKey = context?.section ? `${context.section.currentLayout}:${context.section.columnCount}` : "no-section";
4330
- const generationDateKey = getGenerationDate().toISOString();
4331
4365
  const baseDirKey = getBaseDir() ?? "";
4332
4366
  const childrenKey = "children" in component && component.children ? `:children:${JSON.stringify(component.children)}` : "";
4367
+ const generationDateKey = usesDateSensitivePlaceholder(
4368
+ componentProps + childrenKey
4369
+ ) ? getGenerationDate().toISOString() : "no-date";
4333
4370
  const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${baseDirKey}:${componentProps}${childrenKey}`;
4334
4371
  const cached = await componentCache.get(cacheKey);
4335
4372
  if (cached) {
@@ -4372,10 +4409,11 @@ async function warmComponentCache(components) {
4372
4409
  await Promise.all(warmingPromises);
4373
4410
  }
4374
4411
  function getComponentCacheStats() {
4412
+ const bypassedComponents = getComponentBypassStats();
4375
4413
  if (!componentCache) {
4376
- return null;
4414
+ return bypassedComponents.length > 0 ? { bypassedComponents } : null;
4377
4415
  }
4378
- return componentCache.getStats();
4416
+ return { ...componentCache.getStats(), bypassedComponents };
4379
4417
  }
4380
4418
 
4381
4419
  // src/core/content.ts
@@ -7229,6 +7267,19 @@ function createLimiter(max) {
7229
7267
  var DEFAULT_FALLBACK_CONCURRENCY = 4;
7230
7268
  var BATCH_TIMEOUT_BASE_MS = 3e4;
7231
7269
  var BATCH_TIMEOUT_PER_SLIDE_MS = 1e4;
7270
+ var prepassStats = {
7271
+ documents: 0,
7272
+ collected: 0,
7273
+ unique: 0
7274
+ };
7275
+ function getVisualPrepassStats() {
7276
+ return { ...prepassStats };
7277
+ }
7278
+ function resetVisualPrepassStats() {
7279
+ prepassStats.documents = 0;
7280
+ prepassStats.collected = 0;
7281
+ prepassStats.unique = 0;
7282
+ }
7232
7283
  function collectVisualProps(root) {
7233
7284
  const found = [];
7234
7285
  const seen = /* @__PURE__ */ new WeakSet();
@@ -7305,6 +7356,9 @@ async function prerasterizeVisuals(root, serviceConfig, options = {}) {
7305
7356
  }
7306
7357
  }
7307
7358
  if (targets.size === 0) return map;
7359
+ prepassStats.documents++;
7360
+ prepassStats.collected += visuals.length;
7361
+ prepassStats.unique += targets.size;
7308
7362
  const unique = [...targets.values()];
7309
7363
  const limit = createLimiter(
7310
7364
  Math.max(1, options.concurrency ?? DEFAULT_FALLBACK_CONCURRENCY)
@@ -9297,11 +9351,13 @@ export {
9297
9351
  generatePluginDocumentSchema,
9298
9352
  generateWarningsDocument,
9299
9353
  export_getCacheConfigFromEnv as getCacheConfigFromEnv,
9354
+ getComponentBypassStats,
9300
9355
  getComponentCache,
9301
9356
  getComponentCacheStats,
9302
9357
  getCoreVersion,
9303
9358
  getExample,
9304
9359
  getExampleNames,
9360
+ getVisualPrepassStats,
9305
9361
  hasNodeBuiltins,
9306
9362
  initializeComponentCache,
9307
9363
  isColumnsComponent,
@@ -9325,6 +9381,7 @@ export {
9325
9381
  minimalTheme,
9326
9382
  modernTheme,
9327
9383
  parseTextWithDecorators,
9384
+ resetVisualPrepassStats,
9328
9385
  runExample,
9329
9386
  saveDocument,
9330
9387
  themes,