@beyondwork/docx-react-component 1.0.127 → 1.0.129

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 (98) hide show
  1. package/dist/api/public-types.cjs +215 -61
  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 +2 -2
  5. package/dist/api/v3.cjs +1324 -71
  6. package/dist/api/v3.d.cts +3 -3
  7. package/dist/api/v3.d.ts +3 -3
  8. package/dist/api/v3.js +8 -8
  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-KV435YXO.js → chunk-5DSHUYSY.js} +1 -1
  12. package/dist/{chunk-TQDQU2E3.js → chunk-63FYIGCT.js} +2 -2
  13. package/dist/{chunk-ZDOAUP3V.js → chunk-DDN2AIGE.js} +1 -1
  14. package/dist/{chunk-6F5QW44A.js → chunk-DJU2W4E4.js} +2 -2
  15. package/dist/{chunk-4EENH4FG.js → chunk-EZKJXIPH.js} +1 -1
  16. package/dist/{chunk-CXSYRB37.js → chunk-HUIHBBAQ.js} +166 -49
  17. package/dist/{chunk-ESJ2MES5.js → chunk-JJGVE5J7.js} +1 -1
  18. package/dist/{chunk-LZVBNDGU.js → chunk-LJH64PV3.js} +3 -3
  19. package/dist/{chunk-MWSBGJQO.js → chunk-OTQIW2TC.js} +2 -2
  20. package/dist/{chunk-2QL5DAKF.js → chunk-PGKUJZXV.js} +3 -3
  21. package/dist/{chunk-PUMZWE2D.js → chunk-PRAZBHNF.js} +460 -136
  22. package/dist/{chunk-4YJVRIUB.js → chunk-Q3QYGKFE.js} +51 -8
  23. package/dist/{chunk-YHZHPXDB.js → chunk-RMRTQGW3.js} +50 -13
  24. package/dist/{chunk-XRACP43Q.js → chunk-SKPTKQHF.js} +351 -13
  25. package/dist/{chunk-D5HYZQTG.js → chunk-VNLDQJ47.js} +1 -1
  26. package/dist/{chunk-BYSRJ4FE.js → chunk-W34X3KBR.js} +1 -1
  27. package/dist/{chunk-V6XVZFFH.js → chunk-XMHSGPLN.js} +2 -2
  28. package/dist/{chunk-46KNRA4C.js → chunk-XQCAMKIQ.js} +849 -6
  29. package/dist/{chunk-YD2JE54B.js → chunk-YZDZ4FGR.js} +1 -1
  30. package/dist/compare.d.cts +1 -1
  31. package/dist/compare.d.ts +1 -1
  32. package/dist/core/commands/formatting-commands.d.cts +2 -2
  33. package/dist/core/commands/formatting-commands.d.ts +2 -2
  34. package/dist/core/commands/image-commands.cjs +166 -49
  35. package/dist/core/commands/image-commands.d.cts +2 -2
  36. package/dist/core/commands/image-commands.d.ts +2 -2
  37. package/dist/core/commands/image-commands.js +4 -4
  38. package/dist/core/commands/section-layout-commands.d.cts +2 -2
  39. package/dist/core/commands/section-layout-commands.d.ts +2 -2
  40. package/dist/core/commands/style-commands.d.cts +2 -2
  41. package/dist/core/commands/style-commands.d.ts +2 -2
  42. package/dist/core/commands/table-structure-commands.cjs +166 -49
  43. package/dist/core/commands/table-structure-commands.d.cts +2 -2
  44. package/dist/core/commands/table-structure-commands.d.ts +2 -2
  45. package/dist/core/commands/table-structure-commands.js +3 -3
  46. package/dist/core/commands/text-commands.cjs +166 -49
  47. package/dist/core/commands/text-commands.d.cts +2 -2
  48. package/dist/core/commands/text-commands.d.ts +2 -2
  49. package/dist/core/commands/text-commands.js +4 -4
  50. package/dist/core/selection/mapping.d.cts +2 -2
  51. package/dist/core/selection/mapping.d.ts +2 -2
  52. package/dist/core/state/editor-state.d.cts +2 -2
  53. package/dist/core/state/editor-state.d.ts +2 -2
  54. package/dist/index.cjs +1943 -219
  55. package/dist/index.d.cts +5 -5
  56. package/dist/index.d.ts +5 -5
  57. package/dist/index.js +56 -22
  58. package/dist/io/docx-session.cjs +51 -8
  59. package/dist/io/docx-session.d.cts +4 -4
  60. package/dist/io/docx-session.d.ts +4 -4
  61. package/dist/io/docx-session.js +3 -3
  62. package/dist/legal.d.cts +1 -1
  63. package/dist/legal.d.ts +1 -1
  64. package/dist/legal.js +2 -2
  65. package/dist/{loader-CFICtb9m.d.ts → loader-4qsw4eIU.d.ts} +3 -3
  66. package/dist/{loader-DveZOVuC.d.cts → loader-B8TKhmQi.d.cts} +3 -3
  67. package/dist/{public-types-beSYFJRR.d.cts → public-types-B5CRoR6f.d.cts} +220 -1
  68. package/dist/{public-types-Cgl3efbO.d.ts → public-types-p9b8rfy8.d.ts} +220 -1
  69. package/dist/public-types.cjs +215 -61
  70. package/dist/public-types.d.cts +2 -2
  71. package/dist/public-types.d.ts +2 -2
  72. package/dist/public-types.js +2 -2
  73. package/dist/runtime/collab.d.cts +3 -3
  74. package/dist/runtime/collab.d.ts +3 -3
  75. package/dist/runtime/document-runtime.cjs +999 -193
  76. package/dist/runtime/document-runtime.d.cts +2 -2
  77. package/dist/runtime/document-runtime.d.ts +2 -2
  78. package/dist/runtime/document-runtime.js +13 -13
  79. package/dist/{session-B7u82EJF.d.cts → session-BnGIjaex.d.cts} +3 -3
  80. package/dist/{session-BWMJ9jm4.d.ts → session-vEYKf-w3.d.ts} +3 -3
  81. package/dist/session.cjs +51 -8
  82. package/dist/session.d.cts +5 -5
  83. package/dist/session.d.ts +5 -5
  84. package/dist/session.js +4 -4
  85. package/dist/tailwind.cjs +215 -61
  86. package/dist/tailwind.d.cts +2 -2
  87. package/dist/tailwind.d.ts +2 -2
  88. package/dist/tailwind.js +5 -5
  89. package/dist/{types-BQjdVZsh.d.cts → types-BLuvZ6cQ.d.cts} +2 -2
  90. package/dist/{types-DvvmS5A7.d.ts → types-Dutlyj0T.d.ts} +2 -2
  91. package/dist/ui-tailwind/editor-surface/search-plugin.d.cts +3 -3
  92. package/dist/ui-tailwind/editor-surface/search-plugin.d.ts +3 -3
  93. package/dist/ui-tailwind/editor-surface/search-plugin.js +3 -3
  94. package/dist/ui-tailwind.cjs +215 -61
  95. package/dist/ui-tailwind.d.cts +3 -3
  96. package/dist/ui-tailwind.d.ts +3 -3
  97. package/dist/ui-tailwind.js +5 -5
  98. package/package.json +1 -1
@@ -11,7 +11,7 @@ import {
11
11
  } from "./chunk-M6XR534O.js";
12
12
  import {
13
13
  buildBookmarkNameMap
14
- } from "./chunk-YD2JE54B.js";
14
+ } from "./chunk-YZDZ4FGR.js";
15
15
  import {
16
16
  deleteSelectionOrBackward,
17
17
  deleteSelectionOrForward,
@@ -22,7 +22,7 @@ import {
22
22
  insertText,
23
23
  outdentParagraphAtSelection,
24
24
  splitParagraph
25
- } from "./chunk-LZVBNDGU.js";
25
+ } from "./chunk-LJH64PV3.js";
26
26
  import {
27
27
  applyFormattingOperationToDocument,
28
28
  applyTextMarkOperationToDocumentRange,
@@ -32,18 +32,18 @@ import {
32
32
  insertImage,
33
33
  repositionFloatingImage,
34
34
  resizeImage
35
- } from "./chunk-6F5QW44A.js";
35
+ } from "./chunk-DJU2W4E4.js";
36
36
  import {
37
37
  applyTextTransaction
38
- } from "./chunk-KV435YXO.js";
38
+ } from "./chunk-5DSHUYSY.js";
39
39
  import {
40
40
  applyTableStructureOperationForEditableTarget,
41
41
  removeCellFromRow,
42
42
  removeTableRowPure
43
- } from "./chunk-ZDOAUP3V.js";
43
+ } from "./chunk-DDN2AIGE.js";
44
44
  import {
45
45
  resolveParagraphScope
46
- } from "./chunk-BYSRJ4FE.js";
46
+ } from "./chunk-W34X3KBR.js";
47
47
  import {
48
48
  buildGeometryDebugEntry,
49
49
  collectLineBoxesForRegion,
@@ -51,30 +51,35 @@ import {
51
51
  createRenderKernel,
52
52
  incrementInvalidationCounter,
53
53
  recordPerfSample
54
- } from "./chunk-MWSBGJQO.js";
54
+ } from "./chunk-OTQIW2TC.js";
55
55
  import {
56
56
  AI_ACTION_POLICIES,
57
+ allocateNumberingInstance,
57
58
  buildFormattingDebugEntry,
59
+ cloneNumberingCatalog,
58
60
  collectScopeLocations,
59
61
  createDocumentOutlineSnapshot,
60
62
  createDocumentSectionSnapshots,
61
63
  createScopeCompilerService,
62
64
  createSectionLocations,
63
65
  createTocSnapshot,
66
+ ensureDefaultListInstance,
64
67
  findAllScopesAt,
65
68
  findBookmarkNameForOffset,
66
69
  findDocumentSectionSnapshot,
67
70
  findScopesIntersecting,
68
71
  findTextMatches,
69
72
  findTextWithStyleMatches,
73
+ getListKind,
70
74
  rebuildFieldRegistry,
71
75
  resolveEditableCommandTarget,
72
76
  resolveEditableTableStructureTarget,
73
77
  resolveEditableTextTarget,
74
78
  resolveHeadingPath,
75
79
  resolveScope,
76
- serializeFragmentToWordML
77
- } from "./chunk-XRACP43Q.js";
80
+ serializeFragmentToWordML,
81
+ setStartOverride
82
+ } from "./chunk-SKPTKQHF.js";
78
83
  import {
79
84
  ISSUE_METADATA_ID,
80
85
  LAYOUT_ENGINE_VERSION,
@@ -109,7 +114,7 @@ import {
109
114
  setWorkspaceMode,
110
115
  setZoomLevel,
111
116
  snapCommentAnchorAwayFromTable
112
- } from "./chunk-YHZHPXDB.js";
117
+ } from "./chunk-RMRTQGW3.js";
113
118
  import {
114
119
  countLogicalPositions,
115
120
  createPlainText,
@@ -128,7 +133,7 @@ import {
128
133
  replaceStoryBlocks,
129
134
  resolvePageFieldDisplayText,
130
135
  storyTargetKey
131
- } from "./chunk-CXSYRB37.js";
136
+ } from "./chunk-HUIHBBAQ.js";
132
137
  import {
133
138
  createCommentSidebarProjection,
134
139
  createCommentStoreFromRuntimeComments
@@ -152,12 +157,12 @@ import {
152
157
  persistedSnapshotFromEditorSessionState,
153
158
  remapRevisionStore,
154
159
  setRevisionStatus
155
- } from "./chunk-ESJ2MES5.js";
160
+ } from "./chunk-JJGVE5J7.js";
156
161
  import {
157
162
  isSupportedFieldFamily,
158
163
  parseTocLevelRange,
159
164
  resolveRefFieldText
160
- } from "./chunk-4YJVRIUB.js";
165
+ } from "./chunk-Q3QYGKFE.js";
161
166
  import {
162
167
  collectEditableTargetRefs,
163
168
  collectEditableTargetRefsForStoryBlockRanges,
@@ -1282,7 +1287,7 @@ function restartNumbering(document, paragraphIndex, context, startAt = 1, option
1282
1287
  affectedParagraphIndexes: []
1283
1288
  };
1284
1289
  }
1285
- const catalog = ensureNumberingCatalog(working.numbering);
1290
+ const catalog = cloneNumberingCatalog(working.numbering);
1286
1291
  const existingInstance = catalog.instances[target.numbering.numberingInstanceId];
1287
1292
  if (!existingInstance) {
1288
1293
  return {
@@ -1290,15 +1295,12 @@ function restartNumbering(document, paragraphIndex, context, startAt = 1, option
1290
1295
  affectedParagraphIndexes: []
1291
1296
  };
1292
1297
  }
1293
- const numberingInstanceId = createNumberingInstanceId(catalog);
1294
- catalog.instances[numberingInstanceId] = {
1295
- numberingInstanceId,
1296
- abstractNumberingId: existingInstance.abstractNumberingId,
1297
- overrides: mergeOverride(existingInstance.overrides, {
1298
- level: target.numbering.level,
1299
- startAt
1300
- })
1301
- };
1298
+ const numberingInstanceId = allocateNumberingInstance(
1299
+ catalog,
1300
+ existingInstance.abstractNumberingId,
1301
+ existingInstance.overrides
1302
+ );
1303
+ setStartOverride(catalog, numberingInstanceId, target.numbering.level, startAt);
1302
1304
  const affectedParagraphIndexes = [];
1303
1305
  for (let index = resolvedParagraphIndex; index < paragraphs.length; index += 1) {
1304
1306
  const paragraph = paragraphs[index];
@@ -1352,7 +1354,7 @@ function continueNumbering(document, paragraphIndex, context, options = {}) {
1352
1354
  affectedParagraphIndexes: []
1353
1355
  };
1354
1356
  }
1355
- const catalog = ensureNumberingCatalog(working.numbering);
1357
+ const catalog = cloneNumberingCatalog(working.numbering);
1356
1358
  const currentInstanceId = target.numbering.numberingInstanceId;
1357
1359
  const currentKind = getListKind(catalog, currentInstanceId);
1358
1360
  if (!currentKind) {
@@ -1419,7 +1421,7 @@ function toggleListKind(document, paragraphIndexes, kind, context, options) {
1419
1421
  affectedParagraphIndexes: []
1420
1422
  };
1421
1423
  }
1422
- const catalog = ensureNumberingCatalog(working.numbering);
1424
+ const catalog = cloneNumberingCatalog(working.numbering);
1423
1425
  const allAlreadyKind = normalizedIndexes.every((index) => {
1424
1426
  const paragraph = paragraphs[index];
1425
1427
  return paragraph.numbering ? getListKind(catalog, paragraph.numbering.numberingInstanceId) === kind : false;
@@ -1434,7 +1436,7 @@ function toggleListKind(document, paragraphIndexes, kind, context, options) {
1434
1436
  affectedParagraphIndexes: normalizedIndexes
1435
1437
  };
1436
1438
  }
1437
- const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultInstance(catalog, kind);
1439
+ const numberingInstanceId = findAdjacentCompatibleInstance(paragraphs, catalog, normalizedIndexes[0], kind) ?? ensureDefaultListInstance(catalog, kind);
1438
1440
  for (const index of normalizedIndexes) {
1439
1441
  const paragraph = paragraphs[index];
1440
1442
  paragraph.numbering = {
@@ -1599,23 +1601,6 @@ function sortJson(value) {
1599
1601
  }
1600
1602
  return value;
1601
1603
  }
1602
- function ensureDefaultInstance(catalog, kind) {
1603
- const existing = Object.values(catalog.instances).find(
1604
- (instance) => getListKind(catalog, instance.numberingInstanceId) === kind
1605
- );
1606
- if (existing) {
1607
- return existing.numberingInstanceId;
1608
- }
1609
- const abstractNumberingId = createAbstractNumberingId(catalog);
1610
- catalog.abstractDefinitions[abstractNumberingId] = kind === "bulleted" ? createDefaultBulletedDefinition(abstractNumberingId) : createDefaultNumberedDefinition(abstractNumberingId);
1611
- const numberingInstanceId = createNumberingInstanceId(catalog);
1612
- catalog.instances[numberingInstanceId] = {
1613
- numberingInstanceId,
1614
- abstractNumberingId,
1615
- overrides: []
1616
- };
1617
- return numberingInstanceId;
1618
- }
1619
1604
  function findAdjacentCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
1620
1605
  const previous = paragraphs[fromIndex - 1];
1621
1606
  if (previous?.numbering) {
@@ -1638,69 +1623,6 @@ function findPreviousCompatibleInstance(paragraphs, catalog, fromIndex, kind) {
1638
1623
  }
1639
1624
  return void 0;
1640
1625
  }
1641
- function getListKind(catalog, numberingInstanceId) {
1642
- const instance = catalog.instances[numberingInstanceId];
1643
- const definition = instance ? catalog.abstractDefinitions[instance.abstractNumberingId] : void 0;
1644
- const levelZero = definition?.levels.find((level) => level.level === 0);
1645
- if (!levelZero) {
1646
- return void 0;
1647
- }
1648
- return levelZero.format === "bullet" ? "bulleted" : "numbered";
1649
- }
1650
- function mergeOverride(overrides, nextOverride) {
1651
- const filtered = overrides.filter((override) => override.level !== nextOverride.level);
1652
- filtered.push(nextOverride);
1653
- return filtered.sort((left, right) => left.level - right.level);
1654
- }
1655
- function createDefaultNumberedDefinition(abstractNumberingId) {
1656
- return {
1657
- abstractNumberingId,
1658
- levels: [
1659
- { level: 0, format: "decimal", text: "%1." },
1660
- { level: 1, format: "decimal", text: "%1.%2." },
1661
- { level: 2, format: "lowerLetter", text: "(%3)" },
1662
- { level: 3, format: "lowerRoman", text: "(%4)" },
1663
- { level: 4, format: "decimal", text: "%5." },
1664
- { level: 5, format: "lowerLetter", text: "(%6)" },
1665
- { level: 6, format: "lowerRoman", text: "(%7)" },
1666
- { level: 7, format: "decimal", text: "%8." },
1667
- { level: 8, format: "lowerLetter", text: "(%9)" }
1668
- ]
1669
- };
1670
- }
1671
- function createDefaultBulletedDefinition(abstractNumberingId) {
1672
- return {
1673
- abstractNumberingId,
1674
- levels: [
1675
- { level: 0, format: "bullet", text: "\u2022" },
1676
- { level: 1, format: "bullet", text: "o" },
1677
- { level: 2, format: "bullet", text: "\u25A0" },
1678
- { level: 3, format: "bullet", text: "\u2022" },
1679
- { level: 4, format: "bullet", text: "o" },
1680
- { level: 5, format: "bullet", text: "\u25A0" },
1681
- { level: 6, format: "bullet", text: "\u2022" },
1682
- { level: 7, format: "bullet", text: "o" },
1683
- { level: 8, format: "bullet", text: "\u25A0" }
1684
- ]
1685
- };
1686
- }
1687
- function createAbstractNumberingId(catalog) {
1688
- let index = 1;
1689
- while (catalog.abstractDefinitions[`abstract-num:generated-${index}`]) {
1690
- index += 1;
1691
- }
1692
- return `abstract-num:generated-${index}`;
1693
- }
1694
- function createNumberingInstanceId(catalog) {
1695
- let index = 1;
1696
- while (catalog.instances[`num:generated-${index}`]) {
1697
- index += 1;
1698
- }
1699
- return `num:generated-${index}`;
1700
- }
1701
- function ensureNumberingCatalog(value) {
1702
- return structuredClone(value);
1703
- }
1704
1626
  function cloneEnvelope(document, timestamp) {
1705
1627
  return {
1706
1628
  ...structuredClone(document),
@@ -1889,7 +1811,7 @@ function applyFragmentInsert(document, selection, fragment, context) {
1889
1811
  );
1890
1812
  workingDocument = collapseResult.document;
1891
1813
  workingSelection = collapseResult.selection;
1892
- if (context.textTarget?.kind === "table-paragraph") {
1814
+ if (context.textTarget?.kind === "table-paragraph" || context.textTarget?.kind === "text-leaf") {
1893
1815
  workingContext = {
1894
1816
  ...context,
1895
1817
  textTarget: {
@@ -1911,11 +1833,11 @@ function applyFragmentInsert(document, selection, fragment, context) {
1911
1833
  selection
1912
1834
  };
1913
1835
  }
1914
- const targetedTablePath = workingContext.textTarget?.kind === "table-paragraph" ? workingContext.textTarget.blockPath : void 0;
1915
- if (targetedTablePath) {
1836
+ const targetedBlockPath = workingContext.textTarget?.kind === "table-paragraph" || workingContext.textTarget?.kind === "text-leaf" ? workingContext.textTarget.blockPath : void 0;
1837
+ if (targetedBlockPath) {
1916
1838
  const targeted = insertFragmentBlocksAfterPath(
1917
1839
  splitResult.document,
1918
- targetedTablePath,
1840
+ targetedBlockPath,
1919
1841
  fragment.blocks
1920
1842
  );
1921
1843
  if (targeted) {
@@ -5827,7 +5749,7 @@ function emptyCompatibilityReport() {
5827
5749
  }
5828
5750
 
5829
5751
  // src/runtime/debug/runtime-debug-facet.ts
5830
- function createRuntimeDebugFacet(getRuntime, bus) {
5752
+ function createRuntimeDebugFacet(getRuntime, bus, options = {}) {
5831
5753
  return {
5832
5754
  bus,
5833
5755
  getSnapshot(query) {
@@ -5845,7 +5767,318 @@ function createRuntimeDebugFacet(getRuntime, bus) {
5845
5767
  },
5846
5768
  getChannels() {
5847
5769
  return bus.getChannels();
5770
+ },
5771
+ getHotEditTraces() {
5772
+ return options.getHotEditTraces?.() ?? [];
5773
+ }
5774
+ };
5775
+ }
5776
+
5777
+ // src/runtime/hot-edit/hot-edit-trace.ts
5778
+ var HOT_EDIT_TRACE_LIMIT = 64;
5779
+ var HotEditTraceRecorder = class {
5780
+ traces = [];
5781
+ sequence = 0;
5782
+ begin(input) {
5783
+ this.sequence += 1;
5784
+ return {
5785
+ sequence: this.sequence,
5786
+ commandType: input.commandType,
5787
+ startedAtUtc: input.nowUtc,
5788
+ startedAtMs: nowMs(),
5789
+ startCounters: input.counters.snapshot()
5790
+ };
5791
+ }
5792
+ complete(pending, input) {
5793
+ const endCounters = input.counters.snapshot();
5794
+ const refreshAllCount = counterDelta(pending.startCounters, endCounters, "refresh.all");
5795
+ const patchHitCount = counterDelta(pending.startCounters, endCounters, "surface.localText.patchHit");
5796
+ const patchBudgetFallbackCount = counterDelta(
5797
+ pending.startCounters,
5798
+ endCounters,
5799
+ "surface.localText.patchBudgetFallback"
5800
+ );
5801
+ const boundedEditableTargetBuildCount = counterDelta(
5802
+ pending.startCounters,
5803
+ endCounters,
5804
+ "runtime.editableTargets.boundedBuilds"
5805
+ );
5806
+ const tier = refineTier(input.tier, {
5807
+ refreshAllCount,
5808
+ patchHitCount,
5809
+ patchBudgetFallbackCount,
5810
+ boundedEditableTargetBuildCount
5811
+ });
5812
+ const trace = {
5813
+ sequence: pending.sequence,
5814
+ startedAtUtc: pending.startedAtUtc,
5815
+ commandType: pending.commandType,
5816
+ tier,
5817
+ patchMissReason: input.patchMissReason,
5818
+ totalDurationUs: Math.max(0, Math.round((nowMs() - pending.startedAtMs) * 1e3)),
5819
+ refreshAllCount,
5820
+ patchHitCount,
5821
+ patchBudgetFallbackCount,
5822
+ boundedEditableTargetBuildCount
5823
+ };
5824
+ this.traces.push(trace);
5825
+ if (this.traces.length > HOT_EDIT_TRACE_LIMIT) {
5826
+ this.traces.splice(0, this.traces.length - HOT_EDIT_TRACE_LIMIT);
5827
+ }
5828
+ input.counters.increment(`hotEdit.tier.${trace.tier}`);
5829
+ if (trace.patchMissReason !== "none") {
5830
+ input.counters.increment(`hotEdit.patchMiss.${trace.patchMissReason}`);
5831
+ }
5832
+ return trace;
5833
+ }
5834
+ getTraces() {
5835
+ return Object.freeze([...this.traces]);
5836
+ }
5837
+ clear() {
5838
+ this.traces.splice(0, this.traces.length);
5839
+ }
5840
+ };
5841
+ function refineTier(requested, counters) {
5842
+ if (requested === "blocked") return requested;
5843
+ if (counters.refreshAllCount > 0) return "full-refresh";
5844
+ if (counters.patchBudgetFallbackCount > 0 || counters.boundedEditableTargetBuildCount > 0) {
5845
+ return "bounded-projection";
5846
+ }
5847
+ if (counters.patchHitCount > 0) return "patch";
5848
+ return requested;
5849
+ }
5850
+ function counterDelta(start, end, key) {
5851
+ return (end[key] ?? 0) - (start[key] ?? 0);
5852
+ }
5853
+ function nowMs() {
5854
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
5855
+ }
5856
+
5857
+ // src/runtime/hot-edit/surface-local-patcher.ts
5858
+ function patchSurfaceTextSegment(surface, patch) {
5859
+ const delta = patch.insertedText.length - Math.max(0, patch.to - patch.from);
5860
+ let patched = false;
5861
+ const blocks = surface.blocks.map((block) => {
5862
+ const result = patchBlock(block, patch, delta);
5863
+ if (result.patched) patched = true;
5864
+ return result.block;
5865
+ });
5866
+ if (!patched) {
5867
+ return { status: "miss", reason: "segment-not-found" };
5868
+ }
5869
+ return {
5870
+ status: "patched",
5871
+ surface: {
5872
+ ...surface,
5873
+ storySize: surface.storySize + delta,
5874
+ plainText: surface.plainText.slice(0, patch.from) + patch.insertedText + surface.plainText.slice(patch.to),
5875
+ blocks
5876
+ }
5877
+ };
5878
+ }
5879
+ function patchBlock(block, patch, delta) {
5880
+ if (patch.to < block.from) return { block, patched: false };
5881
+ if (patch.from > block.to) {
5882
+ return { block: shiftBlock(block, delta), patched: false };
5883
+ }
5884
+ switch (block.kind) {
5885
+ case "paragraph":
5886
+ return patchParagraph(block, patch, delta);
5887
+ case "sdt_block": {
5888
+ let patched = false;
5889
+ const children = block.children.map((child) => {
5890
+ const result = patchBlock(child, patch, delta);
5891
+ patched ||= result.patched;
5892
+ return result.block;
5893
+ });
5894
+ return {
5895
+ block: patched ? { ...block, to: block.to + delta, children } : block,
5896
+ patched
5897
+ };
5898
+ }
5899
+ case "table": {
5900
+ let patched = false;
5901
+ const rows = block.rows.map((row2) => ({
5902
+ ...row2,
5903
+ cells: row2.cells.map((cell) => ({
5904
+ ...cell,
5905
+ content: cell.content.map((child) => {
5906
+ const result = patchBlock(child, patch, delta);
5907
+ patched ||= result.patched;
5908
+ return result.block;
5909
+ })
5910
+ }))
5911
+ }));
5912
+ return {
5913
+ block: patched ? { ...block, to: block.to + delta, rows } : block,
5914
+ patched
5915
+ };
5916
+ }
5917
+ case "opaque_block":
5918
+ return { block, patched: false };
5919
+ }
5920
+ }
5921
+ function patchParagraph(block, patch, delta) {
5922
+ if (patch.from < block.from || patch.to > block.to) {
5923
+ return { block, patched: false };
5924
+ }
5925
+ const segmentIndex = block.segments.findIndex(
5926
+ (segment2) => segment2.kind === "text" && patch.from >= segment2.from && patch.to <= segment2.to
5927
+ );
5928
+ if (segmentIndex < 0) return { block, patched: false };
5929
+ const segment = block.segments[segmentIndex];
5930
+ if (segment.kind !== "text") return { block, patched: false };
5931
+ const localFrom = patch.from - segment.from;
5932
+ const localTo = patch.to - segment.from;
5933
+ const segments = block.segments.map((candidate, index) => {
5934
+ if (index < segmentIndex) return candidate;
5935
+ if (index === segmentIndex) {
5936
+ return {
5937
+ ...segment,
5938
+ text: segment.text.slice(0, localFrom) + patch.insertedText + segment.text.slice(localTo),
5939
+ to: segment.to + delta
5940
+ };
5941
+ }
5942
+ return shiftInlineSegment(candidate, delta);
5943
+ });
5944
+ return {
5945
+ block: {
5946
+ ...block,
5947
+ to: block.to + delta,
5948
+ segments
5949
+ },
5950
+ patched: true
5951
+ };
5952
+ }
5953
+ function shiftBlock(block, delta) {
5954
+ if (delta === 0) return block;
5955
+ switch (block.kind) {
5956
+ case "paragraph":
5957
+ return {
5958
+ ...block,
5959
+ from: block.from + delta,
5960
+ to: block.to + delta,
5961
+ segments: block.segments.map((segment) => shiftInlineSegment(segment, delta))
5962
+ };
5963
+ case "sdt_block":
5964
+ return {
5965
+ ...block,
5966
+ from: block.from + delta,
5967
+ to: block.to + delta,
5968
+ children: block.children.map((child) => shiftBlock(child, delta))
5969
+ };
5970
+ case "table":
5971
+ return {
5972
+ ...block,
5973
+ from: block.from + delta,
5974
+ to: block.to + delta,
5975
+ rows: block.rows.map((row2) => ({
5976
+ ...row2,
5977
+ cells: row2.cells.map((cell) => ({
5978
+ ...cell,
5979
+ content: cell.content.map((child) => shiftBlock(child, delta))
5980
+ }))
5981
+ }))
5982
+ };
5983
+ case "opaque_block":
5984
+ return {
5985
+ ...block,
5986
+ from: block.from + delta,
5987
+ to: block.to + delta
5988
+ };
5989
+ }
5990
+ }
5991
+ function shiftInlineSegment(segment, delta) {
5992
+ if (delta === 0) return segment;
5993
+ return {
5994
+ ...segment,
5995
+ from: segment.from + delta,
5996
+ to: segment.to + delta
5997
+ };
5998
+ }
5999
+
6000
+ // src/runtime/hot-edit/hot-edit-profiler.ts
6001
+ var HEAVY_REVIEW_ITEM_THRESHOLD = 24;
6002
+ var DENSE_BLOCK_NODE_THRESHOLD = 256;
6003
+ function deriveHotEditDocumentProfile(document) {
6004
+ const blocks = document.content.children ?? [];
6005
+ let tableBlockCount = 0;
6006
+ let maxNestedSurfaceNodesPerBlock = 0;
6007
+ for (const block of blocks) {
6008
+ if (block.type === "table") tableBlockCount += 1;
6009
+ maxNestedSurfaceNodesPerBlock = Math.max(
6010
+ maxNestedSurfaceNodesPerBlock,
6011
+ countBlockNodes(block)
6012
+ );
6013
+ }
6014
+ const commentCount = Object.keys(document.review.comments ?? {}).length;
6015
+ const revisionCount = Object.keys(document.review.revisions ?? {}).length;
6016
+ const secondaryStoryBlockCount = countSecondaryStoryBlocks(document);
6017
+ return {
6018
+ blockCount: blocks.length,
6019
+ tableBlockCount,
6020
+ maxNestedSurfaceNodesPerBlock,
6021
+ commentCount,
6022
+ revisionCount,
6023
+ secondaryStoryBlockCount,
6024
+ hasHeavyReview: commentCount + revisionCount >= HEAVY_REVIEW_ITEM_THRESHOLD,
6025
+ hasDenseTables: tableBlockCount > 0 && maxNestedSurfaceNodesPerBlock > DENSE_BLOCK_NODE_THRESHOLD
6026
+ };
6027
+ }
6028
+ function countBlockNodes(block) {
6029
+ const value = block;
6030
+ let total = 1;
6031
+ if (Array.isArray(value.children)) {
6032
+ total += value.children.length;
6033
+ for (const child of value.children) {
6034
+ if (isBlockLike(child)) total += countBlockNodes(child);
6035
+ }
6036
+ }
6037
+ if (Array.isArray(value.rows)) {
6038
+ for (const row2 of value.rows) {
6039
+ total += 1;
6040
+ for (const cell of row2.cells ?? []) {
6041
+ total += 1;
6042
+ for (const child of cell.children ?? []) {
6043
+ total += countBlockNodes(child);
6044
+ }
6045
+ }
5848
6046
  }
6047
+ }
6048
+ return total;
6049
+ }
6050
+ function isBlockLike(value) {
6051
+ return Boolean(value && typeof value === "object" && "type" in value);
6052
+ }
6053
+ function countSecondaryStoryBlocks(document) {
6054
+ const subParts = document.subParts;
6055
+ if (!subParts) return 0;
6056
+ let count = 0;
6057
+ for (const value of Object.values(subParts)) {
6058
+ count += countBlocksInUnknownStory(value);
6059
+ }
6060
+ return count;
6061
+ }
6062
+ function countBlocksInUnknownStory(value) {
6063
+ if (!value || typeof value !== "object") return 0;
6064
+ const candidate = value;
6065
+ if (Array.isArray(candidate.children)) return candidate.children.length;
6066
+ if (Array.isArray(candidate.content?.children)) return candidate.content.children.length;
6067
+ return Object.values(value).reduce((total, entry) => total + countBlocksInUnknownStory(entry), 0);
6068
+ }
6069
+
6070
+ // src/runtime/hot-edit/hot-edit-policy.ts
6071
+ var DEFAULT_MAX_SHIFTED_SURFACE_NODES = 5e3;
6072
+ var DEFAULT_MAX_SHIFTED_NODES_PER_BLOCK = 256;
6073
+ var DEFAULT_SELECTION_CORRIDOR_BLOCK_RADIUS = 8;
6074
+ var HEAVY_DOCUMENT_SELECTION_CORRIDOR_BLOCK_RADIUS = 12;
6075
+ function resolveHotEditPolicy(profile) {
6076
+ const complexGeometry = profile.hasDenseTables || profile.secondaryStoryBlockCount > 0;
6077
+ return {
6078
+ maxShiftedSurfaceNodes: DEFAULT_MAX_SHIFTED_SURFACE_NODES,
6079
+ maxShiftedNodesPerBlock: DEFAULT_MAX_SHIFTED_NODES_PER_BLOCK,
6080
+ selectionCorridorBlockRadius: complexGeometry ? HEAVY_DOCUMENT_SELECTION_CORRIDOR_BLOCK_RADIUS : DEFAULT_SELECTION_CORRIDOR_BLOCK_RADIUS,
6081
+ preferBoundedProjectionForDenseTails: profile.hasDenseTables
5849
6082
  };
5850
6083
  }
5851
6084
 
@@ -12245,8 +12478,6 @@ function mapLocalSelectionOnRemoteReplay(selection, mapping) {
12245
12478
 
12246
12479
  // src/runtime/document-runtime.ts
12247
12480
  var CANONICAL_BLOCK_REFS_SYMBOL = /* @__PURE__ */ Symbol.for("wre.canonical-block-refs");
12248
- var LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES = 5e3;
12249
- var LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK = 256;
12250
12481
  function getLocalTextPatchMetadata(mapping) {
12251
12482
  const metadata = mapping.metadata?.localTextPatch;
12252
12483
  if (!metadata || typeof metadata !== "object") {
@@ -12353,6 +12584,17 @@ function createDocumentRuntime(options) {
12353
12584
  const loadScheduler = options.loadScheduler ?? createLoadScheduler({ backendOverride: "sync" });
12354
12585
  let effectiveMarkupModeProvider;
12355
12586
  const perfCounters = new PerfCounters();
12587
+ const hotEditTraces = new HotEditTraceRecorder();
12588
+ let cachedHotEditPolicy = null;
12589
+ function getHotEditPolicy() {
12590
+ if (cachedHotEditPolicy?.document === state.document) {
12591
+ return cachedHotEditPolicy.policy;
12592
+ }
12593
+ const profile = deriveHotEditDocumentProfile(state.document);
12594
+ const policy = resolveHotEditPolicy(profile);
12595
+ cachedHotEditPolicy = { document: state.document, profile, policy };
12596
+ return policy;
12597
+ }
12356
12598
  let analyticsEmitScheduled = false;
12357
12599
  let analyticsEmitScheduleMode = "none";
12358
12600
  let deferNextContextAnalyticsEmit = false;
@@ -12424,7 +12666,6 @@ function createDocumentRuntime(options) {
12424
12666
  let viewportBlockRanges = null;
12425
12667
  let viewportRangesKey = serializeViewportRanges(viewportBlockRanges);
12426
12668
  let viewportBlocksPerPageEstimate = null;
12427
- const EDITING_CORRIDOR_BLOCK_RADIUS = 8;
12428
12669
  const getRuntimeForLayoutFacet = () => {
12429
12670
  if (!runtimeRef) {
12430
12671
  throw new Error("Document runtime viewport methods are not initialized");
@@ -12758,8 +12999,8 @@ function createDocumentRuntime(options) {
12758
12999
  return viewportBlockRanges;
12759
13000
  }
12760
13001
  const corridor = {
12761
- start: Math.max(0, caretBlockIndex - EDITING_CORRIDOR_BLOCK_RADIUS),
12762
- end: Math.min(previousSurface.blocks.length, caretBlockIndex + EDITING_CORRIDOR_BLOCK_RADIUS + 1)
13002
+ start: Math.max(0, caretBlockIndex - getHotEditPolicy().selectionCorridorBlockRadius),
13003
+ end: Math.min(previousSurface.blocks.length, caretBlockIndex + getHotEditPolicy().selectionCorridorBlockRadius + 1)
12763
13004
  };
12764
13005
  return normalizeViewportRanges([...viewportBlockRanges ?? [], corridor]);
12765
13006
  }
@@ -12840,8 +13081,12 @@ function createDocumentRuntime(options) {
12840
13081
  (block2) => block2.kind === "paragraph" && editFrom >= block2.from && editTo <= block2.to
12841
13082
  );
12842
13083
  if (blockIndex < 0) {
12843
- perfCounters.increment("surface.localText.patchMiss");
12844
- return null;
13084
+ return tryPatchNestedLocalTextSurface(
13085
+ previousSurface,
13086
+ editFrom,
13087
+ editTo,
13088
+ patch.insertedText
13089
+ );
12845
13090
  }
12846
13091
  const block = previousSurface.blocks[blockIndex];
12847
13092
  if (block.kind !== "paragraph") {
@@ -12916,6 +13161,34 @@ function createDocumentRuntime(options) {
12916
13161
  perfCounters.increment("surface.localText.total.us", Math.round((performance.now() - tTotal0) * 1e3));
12917
13162
  }
12918
13163
  }
13164
+ function tryPatchNestedLocalTextSurface(previousSurface, editFrom, editTo, insertedText) {
13165
+ const shiftBudget = estimateLocalTextPatchShiftBudget(previousSurface.blocks, 0);
13166
+ perfCounters.increment("surface.localText.shiftedBlocks", shiftBudget.shiftedBlocks);
13167
+ perfCounters.increment("surface.localText.shiftedNodes", shiftBudget.shiftedNodes);
13168
+ if (!shiftBudget.withinBudget) {
13169
+ perfCounters.increment("surface.localText.patchBudgetFallback");
13170
+ return null;
13171
+ }
13172
+ const patched = patchSurfaceTextSegment(previousSurface, {
13173
+ from: editFrom,
13174
+ to: editTo,
13175
+ insertedText
13176
+ });
13177
+ if (patched.status !== "patched") {
13178
+ perfCounters.increment("surface.localText.patchMiss");
13179
+ return null;
13180
+ }
13181
+ const refs = getSurfaceCanonicalBlockRefs(previousSurface);
13182
+ if (refs) {
13183
+ const nextRefs = state.document.content.children.map(
13184
+ (block, index) => block ?? refs[index] ?? null
13185
+ );
13186
+ attachSurfaceCanonicalBlockRefs(patched.surface, nextRefs);
13187
+ }
13188
+ perfCounters.increment("surface.localText.patchHit");
13189
+ perfCounters.increment("surface.localText.patchDelta", insertedText.length - (editTo - editFrom));
13190
+ return patched.surface;
13191
+ }
12919
13192
  function shiftSurfaceInlineSegment(segment, delta) {
12920
13193
  if (delta === 0) return segment;
12921
13194
  return {
@@ -12963,25 +13236,26 @@ function createDocumentRuntime(options) {
12963
13236
  }
12964
13237
  }
12965
13238
  function estimateLocalTextPatchShiftBudget(blocks, startIndex) {
13239
+ const policy = getHotEditPolicy();
12966
13240
  const shiftedBlocks = Math.max(0, blocks.length - startIndex);
12967
13241
  let shiftedNodes = 0;
12968
13242
  for (let index = startIndex; index < blocks.length; index += 1) {
12969
13243
  const shiftedBlockNodes = countSurfaceShiftNodesUpTo(
12970
13244
  blocks[index],
12971
13245
  Math.min(
12972
- LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK,
12973
- LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES - shiftedNodes
13246
+ policy.maxShiftedNodesPerBlock,
13247
+ policy.maxShiftedSurfaceNodes - shiftedNodes
12974
13248
  ) + 1
12975
13249
  );
12976
13250
  shiftedNodes += shiftedBlockNodes;
12977
- if (shiftedBlockNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_NODES_PER_BLOCK) {
13251
+ if (shiftedBlockNodes > policy.maxShiftedNodesPerBlock) {
12978
13252
  return {
12979
13253
  shiftedBlocks,
12980
13254
  shiftedNodes,
12981
13255
  withinBudget: false
12982
13256
  };
12983
13257
  }
12984
- if (shiftedNodes > LOCAL_TEXT_PATCH_MAX_SHIFTED_SURFACE_NODES) {
13258
+ if (shiftedNodes > policy.maxShiftedSurfaceNodes) {
12985
13259
  return {
12986
13260
  shiftedBlocks,
12987
13261
  shiftedNodes,
@@ -13945,7 +14219,9 @@ function createDocumentRuntime(options) {
13945
14219
  });
13946
14220
  const r5ScratchReplayState = { ...state };
13947
14221
  const r5ScratchReplaySnapshot = { ...cachedRenderSnapshot };
13948
- const debugFacet = createRuntimeDebugFacet(() => runtime, telemetryBus);
14222
+ const debugFacet = createRuntimeDebugFacet(() => runtime, telemetryBus, {
14223
+ getHotEditTraces: () => hotEditTraces.getTraces()
14224
+ });
13949
14225
  function prepareTableStructureCommandForExecution(command, document, storyTarget) {
13950
14226
  const resolution = resolveEditableTableStructureTarget({
13951
14227
  document,
@@ -14038,15 +14314,16 @@ function createDocumentRuntime(options) {
14038
14314
  ...resolution.textTarget ? { textTarget: resolution.textTarget } : {}
14039
14315
  };
14040
14316
  }
14041
- function prepareFragmentInsertCommandForExecution(command, document, surface, storyTarget) {
14317
+ function prepareFragmentInsertCommandForExecution(command, document, surface, storyTarget, selection) {
14042
14318
  if (!command.editableTarget) {
14043
- return { kind: "accepted", selection: state.selection };
14319
+ return { kind: "accepted", selection };
14044
14320
  }
14045
14321
  const resolution = resolveEditableTextTarget({
14046
14322
  document,
14047
14323
  surface,
14048
14324
  target: command.editableTarget,
14049
14325
  activeStoryKey: canonicalEditableTargetStoryKey(storyTarget),
14326
+ selection,
14050
14327
  editableTargetCache: editableTargetBlockCache
14051
14328
  });
14052
14329
  if (resolution.kind === "rejected") {
@@ -14064,7 +14341,7 @@ function createDocumentRuntime(options) {
14064
14341
  }
14065
14342
  return {
14066
14343
  kind: "accepted",
14067
- selection: createSelectionSnapshot(resolution.range.from, resolution.range.to),
14344
+ selection,
14068
14345
  ...resolution.textTarget ? { textTarget: resolution.textTarget } : {}
14069
14346
  };
14070
14347
  }
@@ -14236,7 +14513,8 @@ function createDocumentRuntime(options) {
14236
14513
  command,
14237
14514
  state.document,
14238
14515
  cachedRenderSnapshot.surface?.blocks ?? [],
14239
- activeStory
14516
+ activeStory,
14517
+ commandSelection
14240
14518
  );
14241
14519
  if (prepared.kind === "rejected") {
14242
14520
  return;
@@ -14399,7 +14677,8 @@ function createDocumentRuntime(options) {
14399
14677
  command,
14400
14678
  replayState.document,
14401
14679
  replaySnapshot.surface?.blocks ?? [],
14402
- replayStory
14680
+ replayStory,
14681
+ replayState.selection
14403
14682
  );
14404
14683
  if (prepared.kind === "rejected") {
14405
14684
  return;
@@ -14542,7 +14821,8 @@ function createDocumentRuntime(options) {
14542
14821
  command,
14543
14822
  stateForCommand.document,
14544
14823
  snapshotForCommand.surface?.blocks ?? [],
14545
- replayStory
14824
+ replayStory,
14825
+ stateForCommand.selection
14546
14826
  );
14547
14827
  if (prepared.kind === "rejected") {
14548
14828
  continue;
@@ -15106,7 +15386,7 @@ function createDocumentRuntime(options) {
15106
15386
  try {
15107
15387
  const timestamp = clock();
15108
15388
  const selection = target ? createSelectionFromPublicAnchor(target) : state.selection;
15109
- const editableTarget = editContext?.editableTarget && isTableParagraphEditableTarget(editContext.editableTarget) ? editContext.editableTarget : inferEditableTargetForFragmentInsert(
15389
+ const editableTarget = editContext?.editableTarget && isFragmentInsertEditableTarget(editContext.editableTarget) ? editContext.editableTarget : inferEditableTargetForFragmentInsert(
15110
15390
  cachedRenderSnapshot.surface?.blocks ?? [],
15111
15391
  selection
15112
15392
  );
@@ -15237,12 +15517,23 @@ function createDocumentRuntime(options) {
15237
15517
  return actionDepth > 0;
15238
15518
  },
15239
15519
  applyActiveStoryTextCommand(command) {
15520
+ const pendingHotEditTrace = hotEditTraces.begin({
15521
+ commandType: command.type,
15522
+ nowUtc: clock(),
15523
+ counters: perfCounters
15524
+ });
15240
15525
  try {
15241
- return applyTextCommandInActiveStory(command);
15526
+ const ack = applyTextCommandInActiveStory(command);
15527
+ hotEditTraces.complete(pendingHotEditTrace, {
15528
+ tier: classifyHotEditTier(ack),
15529
+ patchMissReason: classifyHotEditPatchMissReason(ack),
15530
+ counters: perfCounters
15531
+ });
15532
+ return ack;
15242
15533
  } catch (error) {
15243
15534
  const runtimeError = toRuntimeError(error);
15244
15535
  emitError(runtimeError);
15245
- return {
15536
+ const ack = {
15246
15537
  kind: "rejected",
15247
15538
  refreshClass: "blocked",
15248
15539
  opId: command.origin?.opId,
@@ -15254,6 +15545,12 @@ function createDocumentRuntime(options) {
15254
15545
  }
15255
15546
  ]
15256
15547
  };
15548
+ hotEditTraces.complete(pendingHotEditTrace, {
15549
+ tier: "blocked",
15550
+ patchMissReason: "participant-blocked",
15551
+ counters: perfCounters
15552
+ });
15553
+ return ack;
15257
15554
  }
15258
15555
  },
15259
15556
  addComment(params) {
@@ -16924,7 +17221,7 @@ function createDocumentRuntime(options) {
16924
17221
  editableTargetCache: editableTargetBlockCache,
16925
17222
  activeStorySize: cachedRenderSnapshot.surface?.storySize,
16926
17223
  textTarget,
16927
- preserveNumberingOnSplit: commandForDispatch.type === "paragraph.split" && targetResolution?.kind === "accepted" && editableTarget?.listAddress?.operationScope === "list-text",
17224
+ preserveNumberingOnSplit: (commandForDispatch.type === "paragraph.split" || commandForDispatch.type === "fragment.insert") && targetResolution?.kind === "accepted" && editableTarget?.listAddress?.operationScope === "list-text",
16928
17225
  rejectTargetlessTableStructureInsert: true
16929
17226
  };
16930
17227
  const baseState = selection === state.selection ? state : {
@@ -17029,6 +17326,27 @@ function createDocumentRuntime(options) {
17029
17326
  newRevisionToken: state.revisionToken
17030
17327
  }));
17031
17328
  }
17329
+ function classifyHotEditTier(ack) {
17330
+ if (ack.kind === "rejected" || ack.refreshClass === "blocked") {
17331
+ return "blocked";
17332
+ }
17333
+ if (ack.refreshClass === "full-projection" || ack.kind === "structural-divergence") {
17334
+ return "full-refresh";
17335
+ }
17336
+ if (ack.refreshClass === "local-text-equivalent" || ack.refreshClass === "selection-only" || ack.refreshClass === "surface-only") {
17337
+ return "patch";
17338
+ }
17339
+ return "full-refresh";
17340
+ }
17341
+ function classifyHotEditPatchMissReason(ack) {
17342
+ if (ack.kind === "rejected" || ack.refreshClass === "blocked") {
17343
+ return "participant-blocked";
17344
+ }
17345
+ if (ack.refreshClass === "full-projection" || ack.kind === "structural-divergence") {
17346
+ return "effect-disqualified";
17347
+ }
17348
+ return "none";
17349
+ }
17032
17350
  function classifyAck(params) {
17033
17351
  const { opId, priorState, transaction, newRevisionToken } = params;
17034
17352
  const meta = transaction.mapping.metadata ?? {};
@@ -17746,7 +18064,7 @@ function canonicalEditableTargetStoryKey(storyTarget) {
17746
18064
  function inferEditableTargetForFragmentInsert(blocks, selection) {
17747
18065
  const position = Math.min(selection.anchor, selection.head);
17748
18066
  const target = findEditableTargetAtSurfacePosition(blocks, position);
17749
- return target && isTableParagraphEditableTarget(target) ? target : void 0;
18067
+ return target && isFragmentInsertEditableTarget(target) ? target : void 0;
17750
18068
  }
17751
18069
  function findEditableTargetAtSurfacePosition(blocks, position) {
17752
18070
  for (const block of blocks) {
@@ -17775,8 +18093,14 @@ function findEditableTargetInSurfaceCell(cell, position) {
17775
18093
  }
17776
18094
  return findEditableTargetAtSurfacePosition(cell.content, position);
17777
18095
  }
17778
- function isTableParagraphEditableTarget(target) {
17779
- return target.editability === "editable" && target.posture.blockers.length === 0 && target.commandFamily === "text-leaf" && (target.kind === "table-cell-paragraph-text" || target.kind === "nested-table-cell-paragraph-text" || target.kind === "sdt-table-cell-paragraph-text");
18096
+ function isFragmentInsertEditableTarget(target) {
18097
+ if (target.editability !== "editable" || target.posture.blockers.length > 0 || target.commandFamily !== "text-leaf") {
18098
+ return false;
18099
+ }
18100
+ if (target.listAddress?.operationScope === "list-text") {
18101
+ return true;
18102
+ }
18103
+ return target.kind === "table-cell-paragraph-text" || target.kind === "nested-table-cell-paragraph-text" || target.kind === "sdt-table-cell-paragraph-text";
17780
18104
  }
17781
18105
  function extractSelectionFragment(document, selection, activeStory) {
17782
18106
  const from = Math.min(selection.anchor, selection.head);