@beyondwork/docx-react-component 1.0.128 → 1.0.130

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.
Files changed (108) hide show
  1. package/dist/api/public-types.cjs +809 -78
  2. package/dist/api/public-types.d.cts +2 -2
  3. package/dist/api/public-types.d.ts +2 -2
  4. package/dist/api/public-types.js +4 -4
  5. package/dist/api/v3.cjs +2059 -402
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +13 -13
  9. package/dist/{canonical-document-CXCFCbAz.d.cts → canonical-document-BMtONpgf.d.cts} +6 -0
  10. package/dist/{canonical-document-CXCFCbAz.d.ts → canonical-document-BMtONpgf.d.ts} +6 -0
  11. package/dist/{chunk-MWSBGJQO.js → chunk-35RHOE6I.js} +105 -4
  12. package/dist/{chunk-2QL5DAKF.js → chunk-3YCQM2RV.js} +6 -6
  13. package/dist/{chunk-ESJ2MES5.js → chunk-4YCWECLZ.js} +1 -1
  14. package/dist/{chunk-4EENH4FG.js → chunk-6TBLDBCL.js} +1 -1
  15. package/dist/{chunk-XRACP43Q.js → chunk-7G5GR3VV.js} +469 -32
  16. package/dist/{chunk-CXSYRB37.js → chunk-A3GSNB4G.js} +183 -55
  17. package/dist/{chunk-5DGKFNQT.js → chunk-A66ZVUAT.js} +150 -1
  18. package/dist/{chunk-YIYM4ZAP.js → chunk-CI2TD3T4.js} +1 -1
  19. package/dist/{chunk-TQDQU2E3.js → chunk-DGA7M77X.js} +2 -2
  20. package/dist/{chunk-EB6M3GE6.js → chunk-FM4K4XFJ.js} +100 -97
  21. package/dist/{chunk-D5HYZQTG.js → chunk-HYHCRMR7.js} +1 -1
  22. package/dist/{chunk-6F5QW44A.js → chunk-KNHMXKC6.js} +2 -2
  23. package/dist/{chunk-4YJVRIUB.js → chunk-M7YRJX6V.js} +61 -29
  24. package/dist/{chunk-KFCQYZXR.js → chunk-OVLZQ6FZ.js} +61 -0
  25. package/dist/{chunk-BYSRJ4FE.js → chunk-PHMWH23E.js} +1 -1
  26. package/dist/{chunk-ZDOAUP3V.js → chunk-Q7Y57KOK.js} +2 -2
  27. package/dist/{chunk-LZVBNDGU.js → chunk-QXKQPUOM.js} +3 -3
  28. package/dist/{chunk-CX42VC67.js → chunk-SYQWQ6FE.js} +1 -1
  29. package/dist/{chunk-KV435YXO.js → chunk-T5YYFDZB.js} +1 -1
  30. package/dist/{chunk-YHZHPXDB.js → chunk-THVM6EP5.js} +419 -24
  31. package/dist/{chunk-V6XVZFFH.js → chunk-VRKK2CSZ.js} +111 -90
  32. package/dist/{chunk-OL2UEHRP.js → chunk-WUDSNHWF.js} +1 -1
  33. package/dist/{chunk-LCYYR57Q.js → chunk-WZDKNF37.js} +666 -107
  34. package/dist/{chunk-6EROGFUF.js → chunk-YLL7MF5C.js} +444 -131
  35. package/dist/{chunk-YD2JE54B.js → chunk-ZVC23LKV.js} +1 -1
  36. package/dist/compare.cjs +100 -97
  37. package/dist/compare.d.cts +1 -1
  38. package/dist/compare.d.ts +1 -1
  39. package/dist/compare.js +3 -3
  40. package/dist/core/commands/formatting-commands.d.cts +2 -2
  41. package/dist/core/commands/formatting-commands.d.ts +2 -2
  42. package/dist/core/commands/image-commands.cjs +182 -54
  43. package/dist/core/commands/image-commands.d.cts +2 -2
  44. package/dist/core/commands/image-commands.d.ts +2 -2
  45. package/dist/core/commands/image-commands.js +5 -5
  46. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  47. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  48. package/dist/core/commands/style-commands.d.cts +2 -2
  49. package/dist/core/commands/style-commands.d.ts +2 -2
  50. package/dist/core/commands/table-structure-commands.cjs +182 -54
  51. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  52. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  53. package/dist/core/commands/table-structure-commands.js +4 -4
  54. package/dist/core/commands/text-commands.cjs +182 -54
  55. package/dist/core/commands/text-commands.d.cts +2 -2
  56. package/dist/core/commands/text-commands.d.ts +2 -2
  57. package/dist/core/commands/text-commands.js +5 -5
  58. package/dist/core/selection/mapping.d.cts +2 -2
  59. package/dist/core/selection/mapping.d.ts +2 -2
  60. package/dist/core/state/editor-state.d.cts +2 -2
  61. package/dist/core/state/editor-state.d.ts +2 -2
  62. package/dist/index.cjs +2765 -557
  63. package/dist/index.d.cts +5 -5
  64. package/dist/index.d.ts +5 -5
  65. package/dist/index.js +52 -28
  66. package/dist/io/docx-session.cjs +267 -211
  67. package/dist/io/docx-session.d.cts +4 -4
  68. package/dist/io/docx-session.d.ts +4 -4
  69. package/dist/io/docx-session.js +6 -6
  70. package/dist/legal.cjs +9 -20
  71. package/dist/legal.d.cts +1 -1
  72. package/dist/legal.d.ts +1 -1
  73. package/dist/legal.js +3 -3
  74. package/dist/{loader-19ct2Be0.d.ts → loader-B-aL5HGD.d.ts} +3 -3
  75. package/dist/{loader-CoXQ2wGd.d.cts → loader-DiY_ZgKl.d.cts} +3 -3
  76. package/dist/{measurement-backend-canvas-Q3MJMEYX.js → measurement-backend-canvas-F7ZYDACK.js} +1 -1
  77. package/dist/{public-types-B-CskQen.d.cts → public-types-DyqnxxO9.d.ts} +252 -2
  78. package/dist/{public-types-7KZsNGE2.d.ts → public-types-gvubspUI.d.cts} +252 -2
  79. package/dist/public-types.cjs +809 -78
  80. package/dist/public-types.d.cts +2 -2
  81. package/dist/public-types.d.ts +2 -2
  82. package/dist/public-types.js +4 -4
  83. package/dist/runtime/collab.d.cts +3 -3
  84. package/dist/runtime/collab.d.ts +3 -3
  85. package/dist/runtime/document-runtime.cjs +1887 -313
  86. package/dist/runtime/document-runtime.d.cts +2 -2
  87. package/dist/runtime/document-runtime.d.ts +2 -2
  88. package/dist/runtime/document-runtime.js +17 -17
  89. package/dist/{session-B5015J4v.d.cts → session-BUN6B-Vj.d.cts} +3 -3
  90. package/dist/{session-C2i8-d6v.d.ts → session-CDB0hohT.d.ts} +3 -3
  91. package/dist/session.cjs +267 -211
  92. package/dist/session.d.cts +5 -5
  93. package/dist/session.d.ts +5 -5
  94. package/dist/session.js +7 -7
  95. package/dist/tailwind.cjs +809 -78
  96. package/dist/tailwind.d.cts +2 -2
  97. package/dist/tailwind.d.ts +2 -2
  98. package/dist/tailwind.js +8 -8
  99. package/dist/{types-DNhN0WeN.d.cts → types-C4bz3kDU.d.cts} +2 -2
  100. package/dist/{types-yvrQuGX9.d.ts → types-VWH6CRvG.d.ts} +2 -2
  101. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  102. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  103. package/dist/ui-tailwind/editor-surface/search-plugin.js +5 -5
  104. package/dist/ui-tailwind.cjs +809 -78
  105. package/dist/ui-tailwind.d.cts +3 -3
  106. package/dist/ui-tailwind.d.ts +3 -3
  107. package/dist/ui-tailwind.js +8 -8
  108. package/package.json +1 -1
@@ -2,11 +2,12 @@ import {
2
2
  buildRunFormattingMap,
3
3
  calculateParagraphHeight,
4
4
  createEmpiricalBackend,
5
+ createLayoutReadyFormattingSnapshot,
5
6
  resolveBlockFormatting,
6
7
  resolveCharsPerLine,
7
8
  resolveNumberingPrefixLength,
8
9
  resolveTextWidth
9
- } from "./chunk-KFCQYZXR.js";
10
+ } from "./chunk-OVLZQ6FZ.js";
10
11
  import {
11
12
  parseTextStory
12
13
  } from "./chunk-QIO6V46H.js";
@@ -18,13 +19,13 @@ import {
18
19
  resolveSectionVariants,
19
20
  sectionSupportsStoryTarget,
20
21
  storyTargetKey
21
- } from "./chunk-CXSYRB37.js";
22
+ } from "./chunk-A3GSNB4G.js";
22
23
  import {
23
24
  createSelectionSnapshot
24
25
  } from "./chunk-OYGMRRR7.js";
25
26
  import {
26
27
  collectCanonicalLayoutInputs
27
- } from "./chunk-5DGKFNQT.js";
28
+ } from "./chunk-A66ZVUAT.js";
28
29
  import {
29
30
  MAIN_STORY_TARGET,
30
31
  createDetachedAnchor,
@@ -3692,6 +3693,14 @@ function paginateSectionBlocksWithSplits(section, blocks, layout, footnotes, mea
3692
3693
  pushPage(block.from);
3693
3694
  continue;
3694
3695
  }
3696
+ if (isStandalonePageBreakParagraph(block)) {
3697
+ if (columnHeight > 0) {
3698
+ pushPage(nextBoundary);
3699
+ } else {
3700
+ pageStart = Math.max(pageStart, Math.min(nextBoundary, section.end));
3701
+ }
3702
+ break;
3703
+ }
3695
3704
  const effectiveNoteHeight = estimateFootnoteReservation(
3696
3705
  block,
3697
3706
  footnotes,
@@ -3866,6 +3875,21 @@ function hasPageBreak(block) {
3866
3875
  }
3867
3876
  return nestedBlocks(block).some(hasPageBreak);
3868
3877
  }
3878
+ function isStandalonePageBreakParagraph(block) {
3879
+ if (block.kind !== "paragraph") return false;
3880
+ let sawPageBreak = false;
3881
+ for (const segment of block.segments) {
3882
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
3883
+ sawPageBreak = true;
3884
+ continue;
3885
+ }
3886
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
3887
+ continue;
3888
+ }
3889
+ return false;
3890
+ }
3891
+ return sawPageBreak;
3892
+ }
3869
3893
  function nestedBlocks(block) {
3870
3894
  if (block.kind === "sdt_block") {
3871
3895
  return block.children;
@@ -5350,6 +5374,9 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
5350
5374
  for (let blockIndex = 0; blockIndex < surface.blocks.length; blockIndex += 1) {
5351
5375
  const block = surface.blocks[blockIndex];
5352
5376
  const blockPath = `main/block[${blockIndex}]`;
5377
+ if (isStandalonePageBreakParagraph2(block)) {
5378
+ continue;
5379
+ }
5353
5380
  if (block.kind === "table") {
5354
5381
  const tableSliceList = splits?.tablesByBlockId.get(block.blockId);
5355
5382
  if (tableSliceList && tableSliceList.length > 1) {
@@ -5435,6 +5462,23 @@ function projectSurfaceBlocksToPageFragments(surface, pages, splits, columnByBlo
5435
5462
  }
5436
5463
  return byPage;
5437
5464
  }
5465
+ function isStandalonePageBreakParagraph2(block) {
5466
+ if (block.kind !== "paragraph") {
5467
+ return false;
5468
+ }
5469
+ let sawPageBreak = false;
5470
+ for (const segment of block.segments) {
5471
+ if (segment.kind === "opaque_inline" && segment.label === "Page break") {
5472
+ sawPageBreak = true;
5473
+ continue;
5474
+ }
5475
+ if (segment.kind === "text" && segment.text.trim().length === 0) {
5476
+ continue;
5477
+ }
5478
+ return false;
5479
+ }
5480
+ return sawPageBreak;
5481
+ }
5438
5482
  function projectLineBoxesForPageFragments(pages, fragmentsByPageIndex, fragmentMeasurementsByPageIndex, surface) {
5439
5483
  const byPage = /* @__PURE__ */ new Map();
5440
5484
  const blocksById = surface ? new Map(surface.blocks.map((block) => [block.blockId, block])) : /* @__PURE__ */ new Map();
@@ -5947,13 +5991,11 @@ function buildBookmarkRanges(targets) {
5947
5991
  }
5948
5992
  var EMPTY_NUMBERING_INPUT_INDEX = {
5949
5993
  byNumberingKey: /* @__PURE__ */ new Map(),
5950
- byBlockPath: /* @__PURE__ */ new Map(),
5951
- byParagraphIndex: /* @__PURE__ */ new Map()
5994
+ byBlockPath: /* @__PURE__ */ new Map()
5952
5995
  };
5953
5996
  function buildNumberingInputIndex(numberingInputs) {
5954
5997
  const byNumberingKey = /* @__PURE__ */ new Map();
5955
5998
  const byBlockPath = /* @__PURE__ */ new Map();
5956
- const byParagraph = /* @__PURE__ */ new Map();
5957
5999
  for (const input of numberingInputs) {
5958
6000
  if (!byNumberingKey.has(input.numberingKey)) {
5959
6001
  byNumberingKey.set(input.numberingKey, input);
@@ -5961,11 +6003,8 @@ function buildNumberingInputIndex(numberingInputs) {
5961
6003
  if (!byBlockPath.has(input.blockPath)) {
5962
6004
  byBlockPath.set(input.blockPath, input);
5963
6005
  }
5964
- if (!byParagraph.has(input.paragraphIndex)) {
5965
- byParagraph.set(input.paragraphIndex, input);
5966
- }
5967
6006
  }
5968
- return { byNumberingKey, byBlockPath, byParagraphIndex: byParagraph };
6007
+ return { byNumberingKey, byBlockPath };
5969
6008
  }
5970
6009
  function collectBookmarkRangeLayoutFacts(fragmentId, blockPath, bookmarkRanges) {
5971
6010
  if (!blockPath || !bookmarkRanges || bookmarkRanges.length === 0) return [];
@@ -6085,8 +6124,7 @@ function collectNumberingLayoutFactsForBlock(block, blockPath, numberingIndex, n
6085
6124
  const canonical = lookupNumberingInput(
6086
6125
  numberingIndex,
6087
6126
  numberingKey,
6088
- context.path,
6089
- paragraphIndex
6127
+ context.path
6090
6128
  );
6091
6129
  const target = findNumberingTarget(numberingTargets, context.path);
6092
6130
  const numberingLayoutId = numberingKey ?? [
@@ -6126,7 +6164,7 @@ function findNumberingTarget(numberingTargets, blockPath) {
6126
6164
  if (blockPath === void 0) return void 0;
6127
6165
  return numberingTargets.find((target) => target.blockPath === blockPath);
6128
6166
  }
6129
- function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraphIndex) {
6167
+ function lookupNumberingInput(numberingIndex, numberingKey, blockPath) {
6130
6168
  if (!numberingIndex) return void 0;
6131
6169
  if (numberingKey !== void 0) {
6132
6170
  const byKey = numberingIndex.byNumberingKey.get(numberingKey);
@@ -6136,7 +6174,7 @@ function lookupNumberingInput(numberingIndex, numberingKey, blockPath, paragraph
6136
6174
  const byPath = numberingIndex.byBlockPath.get(blockPath);
6137
6175
  if (byPath !== void 0) return byPath;
6138
6176
  }
6139
- return paragraphIndex !== void 0 ? numberingIndex.byParagraphIndex.get(paragraphIndex) : void 0;
6177
+ return void 0;
6140
6178
  }
6141
6179
  function collectNumberingUnavailableReasons(numbering, canonical) {
6142
6180
  const reasons = [];
@@ -6545,20 +6583,337 @@ function createEmpiricalProvider() {
6545
6583
  }
6546
6584
  async function createCanvasProvider(fontLoader) {
6547
6585
  try {
6548
- const mod = await import("./measurement-backend-canvas-Q3MJMEYX.js");
6586
+ const mod = await import("./measurement-backend-canvas-F7ZYDACK.js");
6549
6587
  return mod.createCanvasBackend(fontLoader);
6550
6588
  } catch {
6551
6589
  return createEmpiricalProvider();
6552
6590
  }
6553
6591
  }
6554
6592
 
6593
+ // src/runtime/layout/persistent-layout-measurement-cache.ts
6594
+ var DEFAULT_MAX_ENTRIES = 1e4;
6595
+ var DEFAULT_MAX_ESTIMATED_BYTES = 50 * 1024 * 1024;
6596
+ function createPersistentLayoutMeasurementCache(options = {}) {
6597
+ const maxEntries = Math.max(1, options.maxEntries ?? DEFAULT_MAX_ENTRIES);
6598
+ const maxEstimatedBytes = Math.max(
6599
+ 1024,
6600
+ options.maxEstimatedBytes ?? DEFAULT_MAX_ESTIMATED_BYTES
6601
+ );
6602
+ const entries = /* @__PURE__ */ new Map();
6603
+ const counters = {
6604
+ hits: 0,
6605
+ misses: 0,
6606
+ sets: 0,
6607
+ evictions: 0,
6608
+ clears: 0,
6609
+ estimatedBytes: 0,
6610
+ invalidatedByReason: {}
6611
+ };
6612
+ function evictOldest() {
6613
+ const oldest = entries.keys().next();
6614
+ if (oldest.done) return;
6615
+ const entry = entries.get(oldest.value);
6616
+ if (entry) {
6617
+ counters.estimatedBytes -= entry.estimatedBytes;
6618
+ }
6619
+ entries.delete(oldest.value);
6620
+ counters.evictions += 1;
6621
+ }
6622
+ return {
6623
+ get(key) {
6624
+ const cacheKey = serializeCacheKey(key);
6625
+ const entry = entries.get(cacheKey);
6626
+ if (!entry) {
6627
+ counters.misses += 1;
6628
+ return void 0;
6629
+ }
6630
+ entries.delete(cacheKey);
6631
+ entries.set(cacheKey, entry);
6632
+ counters.hits += 1;
6633
+ return entry.value;
6634
+ },
6635
+ set(key, value) {
6636
+ const cacheKey = serializeCacheKey(key);
6637
+ const previous = entries.get(cacheKey);
6638
+ if (previous) {
6639
+ counters.estimatedBytes -= previous.estimatedBytes;
6640
+ entries.delete(cacheKey);
6641
+ }
6642
+ const estimatedBytes = estimateBytes(key, value);
6643
+ entries.set(cacheKey, { key, value, estimatedBytes });
6644
+ counters.estimatedBytes += estimatedBytes;
6645
+ counters.sets += 1;
6646
+ while (entries.size > maxEntries || counters.estimatedBytes > maxEstimatedBytes) {
6647
+ evictOldest();
6648
+ }
6649
+ },
6650
+ invalidate(reason, predicate) {
6651
+ if (!predicate) {
6652
+ const removed2 = entries.size;
6653
+ counters.estimatedBytes = 0;
6654
+ entries.clear();
6655
+ counters.invalidatedByReason[reason] = (counters.invalidatedByReason[reason] ?? 0) + removed2;
6656
+ return;
6657
+ }
6658
+ let removed = 0;
6659
+ for (const [cacheKey, entry] of entries) {
6660
+ if (!predicate(entry.key)) continue;
6661
+ counters.estimatedBytes -= entry.estimatedBytes;
6662
+ entries.delete(cacheKey);
6663
+ removed += 1;
6664
+ }
6665
+ counters.invalidatedByReason[reason] = (counters.invalidatedByReason[reason] ?? 0) + removed;
6666
+ },
6667
+ clear(reason) {
6668
+ const removed = entries.size;
6669
+ counters.estimatedBytes = 0;
6670
+ entries.clear();
6671
+ counters.clears += 1;
6672
+ counters.invalidatedByReason[reason] = (counters.invalidatedByReason[reason] ?? 0) + removed;
6673
+ },
6674
+ stats() {
6675
+ return {
6676
+ hits: counters.hits,
6677
+ misses: counters.misses,
6678
+ sets: counters.sets,
6679
+ evictions: counters.evictions,
6680
+ clears: counters.clears,
6681
+ size: entries.size,
6682
+ estimatedBytes: Math.max(0, counters.estimatedBytes),
6683
+ invalidatedByReason: { ...counters.invalidatedByReason }
6684
+ };
6685
+ }
6686
+ };
6687
+ }
6688
+ function createCachedLayoutMeasurementProvider(delegate, options = {}) {
6689
+ const cache = options.cache ?? createPersistentLayoutMeasurementCache(options);
6690
+ function emitCounter(type, key) {
6691
+ const telemetryBus = options.telemetryBus;
6692
+ if (!telemetryBus?.isEnabled("layout")) return;
6693
+ telemetryBus.emitLazy("layout", () => ({
6694
+ type,
6695
+ payload: key ? {
6696
+ measurementKind: key.measurementKind,
6697
+ blockId: key.blockId,
6698
+ backendVersion: key.backendVersion
6699
+ } : void 0
6700
+ }));
6701
+ }
6702
+ return {
6703
+ get fidelity() {
6704
+ return delegate.fidelity;
6705
+ },
6706
+ measurementCache: cache,
6707
+ measurementCacheStats() {
6708
+ return cache.stats();
6709
+ },
6710
+ whenReady() {
6711
+ return delegate.whenReady();
6712
+ },
6713
+ measureLineFragments(input) {
6714
+ const key = buildLineFragmentsKey(input, delegate, options);
6715
+ const cached = cache.get(key);
6716
+ if (cached) {
6717
+ emitCounter("pageRender.measurement.hit", key);
6718
+ return cloneMeasuredLineFragments(cached);
6719
+ }
6720
+ emitCounter("pageRender.measurement.miss", key);
6721
+ const measured = delegate.measureLineFragments(input);
6722
+ cache.set(key, cloneMeasuredLineFragments(measured));
6723
+ return measured;
6724
+ },
6725
+ measureInlineObject(input) {
6726
+ const key = buildInlineObjectKey(input, delegate, options);
6727
+ const cached = cache.get(key);
6728
+ if (cached) {
6729
+ emitCounter("pageRender.measurement.hit", key);
6730
+ return { ...cached };
6731
+ }
6732
+ emitCounter("pageRender.measurement.miss", key);
6733
+ const measured = delegate.measureInlineObject(input);
6734
+ cache.set(key, { ...measured });
6735
+ return measured;
6736
+ },
6737
+ measureTableBlock(input) {
6738
+ const key = buildTableBlockKey(input, delegate, options);
6739
+ const cached = cache.get(key);
6740
+ if (cached) {
6741
+ emitCounter("pageRender.measurement.hit", key);
6742
+ return cloneMeasuredTableBlock(cached);
6743
+ }
6744
+ emitCounter("pageRender.measurement.miss", key);
6745
+ const measured = delegate.measureTableBlock(input);
6746
+ cache.set(key, cloneMeasuredTableBlock(measured));
6747
+ return measured;
6748
+ },
6749
+ invalidateCache() {
6750
+ delegate.invalidateCache();
6751
+ cache.clear("provider.invalidateCache");
6752
+ emitCounter("pageRender.measurement.invalidated.provider.invalidateCache");
6753
+ }
6754
+ };
6755
+ }
6756
+ function isCachedLayoutMeasurementProvider(provider) {
6757
+ return typeof provider.measurementCacheStats === "function";
6758
+ }
6759
+ function buildLineFragmentsKey(input, delegate, options) {
6760
+ const block = input.block;
6761
+ const identity = measurementIdentityForBlock(block);
6762
+ return {
6763
+ measurementKind: "line-fragments",
6764
+ blockId: identity.blockId,
6765
+ blockPath: identity.blockPath,
6766
+ contentHash: hashStable({
6767
+ kind: block.kind,
6768
+ identity: identity.identityHash,
6769
+ segments: block.segments,
6770
+ numbering: block.numbering,
6771
+ numberingPrefix: block.numberingPrefix,
6772
+ numberingSuffix: block.numberingSuffix,
6773
+ resolvedNumbering: block.resolvedNumbering
6774
+ }),
6775
+ formattingHash: createLayoutReadyFormattingSnapshot(
6776
+ input.formatting,
6777
+ input.runs
6778
+ ).hash,
6779
+ constraintsHash: hashStable({ columnWidth: input.columnWidth }),
6780
+ sectionHash: resolveOptionValue(options.sectionHash, "section:provider-input"),
6781
+ fontEpoch: resolveOptionValue(options.fontEpoch, "font:default"),
6782
+ backendVersion: resolveOptionValue(options.backendVersion, delegate.fidelity),
6783
+ displayModeHash: resolveOptionValue(options.displayModeHash, "display:default")
6784
+ };
6785
+ }
6786
+ function buildInlineObjectKey(input, delegate, options) {
6787
+ return {
6788
+ measurementKind: "inline-object",
6789
+ blockId: "inline-object",
6790
+ blockPath: "inline-object",
6791
+ contentHash: hashStable({ display: input.display }),
6792
+ formattingHash: "format:none",
6793
+ constraintsHash: hashStable({
6794
+ widthTwips: input.widthTwips,
6795
+ heightTwips: input.heightTwips
6796
+ }),
6797
+ sectionHash: resolveOptionValue(options.sectionHash, "section:provider-input"),
6798
+ fontEpoch: resolveOptionValue(options.fontEpoch, "font:default"),
6799
+ backendVersion: resolveOptionValue(options.backendVersion, delegate.fidelity),
6800
+ displayModeHash: resolveOptionValue(options.displayModeHash, "display:default")
6801
+ };
6802
+ }
6803
+ function buildTableBlockKey(input, delegate, options) {
6804
+ const block = input.block;
6805
+ const identity = measurementIdentityForBlock(block);
6806
+ return {
6807
+ measurementKind: "table-block",
6808
+ blockId: identity.blockId,
6809
+ blockPath: identity.blockPath,
6810
+ contentHash: hashStable({
6811
+ kind: block.kind,
6812
+ identity: identity.identityHash,
6813
+ rows: block.rows,
6814
+ gridColumns: block.gridColumns,
6815
+ gridColumnsRelative: block.gridColumnsRelative,
6816
+ tableResolved: block.tableResolved,
6817
+ tblLook: block.tblLook
6818
+ }),
6819
+ formattingHash: hashStable({
6820
+ styleId: block.styleId,
6821
+ alignment: block.alignment
6822
+ }),
6823
+ constraintsHash: hashStable({ columnWidth: input.columnWidth }),
6824
+ sectionHash: resolveOptionValue(options.sectionHash, "section:provider-input"),
6825
+ fontEpoch: resolveOptionValue(options.fontEpoch, "font:default"),
6826
+ backendVersion: resolveOptionValue(options.backendVersion, delegate.fidelity),
6827
+ displayModeHash: resolveOptionValue(options.displayModeHash, "display:default")
6828
+ };
6829
+ }
6830
+ function measurementIdentityForBlock(block) {
6831
+ const identity = block.layoutIdentity;
6832
+ if (!identity) {
6833
+ return {
6834
+ blockId: block.blockId,
6835
+ blockPath: blockPathForBlock(block),
6836
+ identityHash: "identity:legacy"
6837
+ };
6838
+ }
6839
+ return {
6840
+ blockId: identity.blockId,
6841
+ blockPath: identity.blockPath,
6842
+ identityHash: hashStable({
6843
+ storyKey: identity.storyKey,
6844
+ blockId: identity.blockId,
6845
+ blockPath: identity.blockPath,
6846
+ sourceRef: identity.sourceRef,
6847
+ table: identity.table,
6848
+ list: identity.list,
6849
+ field: identity.field,
6850
+ object: identity.object
6851
+ })
6852
+ };
6853
+ }
6854
+ function blockPathForBlock(block) {
6855
+ return `${block.from}:${block.to}`;
6856
+ }
6857
+ function resolveOptionValue(option, fallback) {
6858
+ if (typeof option === "function") return option();
6859
+ return option ?? fallback;
6860
+ }
6861
+ function serializeCacheKey(key) {
6862
+ return stableStringify(key);
6863
+ }
6864
+ function estimateBytes(key, value) {
6865
+ return stableStringify(key).length + stableStringify(value).length;
6866
+ }
6867
+ function cloneMeasuredLineFragments(value) {
6868
+ return {
6869
+ lineCount: value.lineCount,
6870
+ maxLineWidth: value.maxLineWidth,
6871
+ lineHeights: [...value.lineHeights]
6872
+ };
6873
+ }
6874
+ function cloneMeasuredTableBlock(value) {
6875
+ return {
6876
+ totalHeightTwips: value.totalHeightTwips,
6877
+ rowHeights: [...value.rowHeights]
6878
+ };
6879
+ }
6880
+ function hashStable(value) {
6881
+ return fnv1a(stableStringify(value)).toString(36);
6882
+ }
6883
+ function stableStringify(value) {
6884
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
6885
+ if (Array.isArray(value)) {
6886
+ return `[${value.map((item) => stableStringify(item)).join(",")}]`;
6887
+ }
6888
+ if (value instanceof Map) {
6889
+ return stableStringify(Array.from(value.entries()));
6890
+ }
6891
+ const object = value;
6892
+ const keys = Object.keys(object).filter((key) => object[key] !== void 0 && typeof object[key] !== "function").sort();
6893
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${stableStringify(object[key])}`).join(",")}}`;
6894
+ }
6895
+ function fnv1a(input) {
6896
+ let hash = 2166136261;
6897
+ for (let i = 0; i < input.length; i += 1) {
6898
+ hash ^= input.charCodeAt(i);
6899
+ hash = Math.imul(hash, 16777619);
6900
+ }
6901
+ return hash >>> 0;
6902
+ }
6903
+
6555
6904
  // src/runtime/layout/layout-engine-version.ts
6556
- var LAYOUT_ENGINE_VERSION = 88;
6905
+ var LAYOUT_ENGINE_VERSION = 93;
6557
6906
  var LAYCACHE_SCHEMA_VERSION = 12;
6558
6907
 
6559
6908
  // src/runtime/layout/layout-engine-instance.ts
6560
6909
  var FULL_VIEWPORT_WINDOW_KEY = "full";
6561
6910
  var DEFAULT_VIEWPORT_PAGE_WINDOW_BUFFER = 1;
6911
+ function indexLayoutIdentitiesByBlockPath(identities) {
6912
+ return new Map(identities.map((identity) => [identity.blockPath, identity]));
6913
+ }
6914
+ function indexEditableTargetsByBlockPath(targets) {
6915
+ return new Map(targets.map((target) => [target.blockPath, target]));
6916
+ }
6562
6917
  function normalizeViewportPageWindow(window2) {
6563
6918
  if (!window2) return void 0;
6564
6919
  const buffer = Number.isFinite(window2.bufferPages) ? Math.max(0, Math.floor(window2.bufferPages ?? 0)) : DEFAULT_VIEWPORT_PAGE_WINDOW_BUFFER;
@@ -6754,8 +7109,22 @@ function recordFullRebuildReason(reasonKind) {
6754
7109
  probe.invalidationCounts[totalKey] = (probe.invalidationCounts[totalKey] ?? 0) + 1;
6755
7110
  probe.invalidationCounts[byReasonKey] = (probe.invalidationCounts[byReasonKey] ?? 0) + 1;
6756
7111
  }
7112
+ function wrapMeasurementProvider(provider, measurementCache, telemetryBus) {
7113
+ if (!measurementCache || isCachedLayoutMeasurementProvider(provider)) {
7114
+ return provider;
7115
+ }
7116
+ const cacheOptions = measurementCache === true ? {} : measurementCache;
7117
+ return createCachedLayoutMeasurementProvider(provider, {
7118
+ ...cacheOptions,
7119
+ ...telemetryBus ? { telemetryBus } : {}
7120
+ });
7121
+ }
6757
7122
  function createLayoutEngine(options = {}) {
6758
- let measurementProvider = options.measurementProvider ?? createEmpiricalMeasurementProvider();
7123
+ let measurementProvider = wrapMeasurementProvider(
7124
+ options.measurementProvider ?? createEmpiricalMeasurementProvider(),
7125
+ options.measurementCache,
7126
+ options.telemetryBus
7127
+ );
6759
7128
  const autoUpgradeToCanvas = options.autoUpgradeToCanvasBackend !== false;
6760
7129
  const telemetryBus = options.telemetryBus;
6761
7130
  const dirtyFieldFamilies = /* @__PURE__ */ new Set();
@@ -6855,13 +7224,20 @@ function createLayoutEngine(options = {}) {
6855
7224
  const pageCountBeforeRecompute = previousPageCount;
6856
7225
  const document2 = input.document;
6857
7226
  const viewportWindow = normalizeViewportPageWindow(input.viewportPageWindow);
7227
+ const layoutInputs = collectCanonicalLayoutInputs(document2);
7228
+ const layoutIdentitiesByBlockPath = indexLayoutIdentitiesByBlockPath(
7229
+ layoutInputs.layoutIdentities
7230
+ );
7231
+ const editableTargetsByBlockPath = indexEditableTargetsByBlockPath(
7232
+ layoutInputs.editableTargets
7233
+ );
6858
7234
  const mainSurface = createEditorSurfaceSnapshot(
6859
7235
  document2,
6860
7236
  createSelectionSnapshot(0, 0),
6861
- MAIN_STORY_TARGET
7237
+ MAIN_STORY_TARGET,
7238
+ { editableTargetsByBlockPath, layoutIdentitiesByBlockPath }
6862
7239
  );
6863
7240
  const sections = buildResolvedSections(document2);
6864
- const layoutInputs = collectCanonicalLayoutInputs(document2);
6865
7241
  const fieldRegions = layoutInputs.fieldRegions;
6866
7242
  const pageStack = buildPageStackWithSplits(
6867
7243
  document2,
@@ -6973,10 +7349,18 @@ function createLayoutEngine(options = {}) {
6973
7349
  const firstDirty = range.firstPageIndex;
6974
7350
  if (firstDirty < 0 || firstDirty >= priorGraph.pages.length) return null;
6975
7351
  const document2 = input.document;
7352
+ const layoutInputs = collectCanonicalLayoutInputs(document2);
7353
+ const layoutIdentitiesByBlockPath = indexLayoutIdentitiesByBlockPath(
7354
+ layoutInputs.layoutIdentities
7355
+ );
7356
+ const editableTargetsByBlockPath = indexEditableTargetsByBlockPath(
7357
+ layoutInputs.editableTargets
7358
+ );
6976
7359
  const mainSurface = createEditorSurfaceSnapshot(
6977
7360
  document2,
6978
7361
  createSelectionSnapshot(0, 0),
6979
- MAIN_STORY_TARGET
7362
+ MAIN_STORY_TARGET,
7363
+ { editableTargetsByBlockPath, layoutIdentitiesByBlockPath }
6980
7364
  );
6981
7365
  const sections = buildResolvedSections(document2);
6982
7366
  const dirtyPage = priorGraph.pages[firstDirty];
@@ -7005,7 +7389,6 @@ function createLayoutEngine(options = {}) {
7005
7389
  const freshSnapshotsToRebuild = freshSnapshots.slice(0, convergenceIndex);
7006
7390
  const convergedTailStart = convergenceIndex < freshSnapshots.length ? firstDirty + convergenceIndex : void 0;
7007
7391
  const freshStories = resolvePageStories(freshSnapshotsToRebuild);
7008
- const layoutInputs = collectCanonicalLayoutInputs(document2);
7009
7392
  const fieldRegions = layoutInputs.fieldRegions;
7010
7393
  const freshBodyFragmentsByPageIndex = projectSurfaceBlocksToPageFragments(
7011
7394
  mainSurface,
@@ -7135,9 +7518,13 @@ function createLayoutEngine(options = {}) {
7135
7518
  const readCachedRevision = () => cachedGraph?.revision ?? 0;
7136
7519
  void (async () => {
7137
7520
  try {
7138
- const mod = await import("./measurement-backend-canvas-Q3MJMEYX.js");
7521
+ const mod = await import("./measurement-backend-canvas-F7ZYDACK.js");
7139
7522
  const canvasProvider = mod.createCanvasBackend();
7140
- measurementProvider = canvasProvider;
7523
+ measurementProvider = wrapMeasurementProvider(
7524
+ canvasProvider,
7525
+ options.measurementCache,
7526
+ telemetryBus
7527
+ );
7141
7528
  cachedKey = null;
7142
7529
  cachedGraph = null;
7143
7530
  cachedFormatting = null;
@@ -7222,7 +7609,11 @@ function createLayoutEngine(options = {}) {
7222
7609
  },
7223
7610
  swapMeasurementProvider(provider) {
7224
7611
  const previousFidelity = measurementProvider.fidelity;
7225
- measurementProvider = provider;
7612
+ measurementProvider = wrapMeasurementProvider(
7613
+ provider,
7614
+ options.measurementCache,
7615
+ telemetryBus
7616
+ );
7226
7617
  if (previousFidelity !== provider.fidelity) {
7227
7618
  cachedKey = null;
7228
7619
  cachedGraph = null;
@@ -7251,6 +7642,10 @@ function createLayoutEngine(options = {}) {
7251
7642
  cachedFormatting = null;
7252
7643
  cachedMapper = null;
7253
7644
  },
7645
+ getMeasurementCacheStats() {
7646
+ if (!isCachedLayoutMeasurementProvider(measurementProvider)) return null;
7647
+ return measurementProvider.measurementCacheStats();
7648
+ },
7254
7649
  /**
7255
7650
  * L7 Phase 2.5 — seed the cached graph from a prerender envelope.
7256
7651
  * Populates both `cachedGraph` and `cachedKey` (keyed on the provided