@stll/folio-core 0.54.1 → 0.55.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.
Files changed (251) hide show
  1. package/dist/ai-edits/apply.d.ts +1 -1
  2. package/dist/ai-edits/apply.js +40 -32
  3. package/dist/ai-edits/headless.d.ts +1 -2
  4. package/dist/ai-edits/headless.js +13 -27
  5. package/dist/ai-edits/read.d.ts +1 -0
  6. package/dist/ai-edits/read.js +7 -2
  7. package/dist/ai-edits/table-mutation-plan.d.ts +2 -1
  8. package/dist/ai-edits/table-mutation-plan.js +39 -1
  9. package/dist/ai-suggestions/apply.d.ts +1 -1
  10. package/dist/ai-suggestions/apply.js +3 -2
  11. package/dist/compare/compare.js +2 -1
  12. package/dist/compare/content-types.d.ts +3 -15
  13. package/dist/controller/canonicalComposition.d.ts +36 -0
  14. package/dist/controller/canonicalComposition.js +168 -0
  15. package/dist/controller/canonicalInput.d.ts +45 -0
  16. package/dist/controller/canonicalInput.js +338 -0
  17. package/dist/controller/canonicalOperations.d.ts +22 -0
  18. package/dist/controller/canonicalOperations.js +85 -0
  19. package/dist/controller/canonicalReview.d.ts +12 -0
  20. package/dist/controller/canonicalReview.js +19 -0
  21. package/dist/controller/canonicalSession.d.ts +149 -0
  22. package/dist/controller/canonicalSession.js +1038 -0
  23. package/dist/controller/canonicalStoryEditor.d.ts +34 -0
  24. package/dist/controller/canonicalStoryEditor.js +82 -0
  25. package/dist/controller/canonicalStructure.d.ts +16 -0
  26. package/dist/controller/canonicalStructure.js +269 -0
  27. package/dist/controller/folioEditor.d.ts +1 -1
  28. package/dist/controller/folioEditor.js +9 -0
  29. package/dist/controller/headerFooterEditorManager.d.ts +4 -0
  30. package/dist/controller/headerFooterEditorManager.js +71 -3
  31. package/dist/controller/hiddenEditorApi.d.ts +35 -0
  32. package/dist/controller/hiddenEditorApi.js +25 -8
  33. package/dist/controller/hiddenEditorManager.d.ts +11 -2
  34. package/dist/controller/hiddenEditorManager.js +456 -30
  35. package/dist/controller/layoutPipeline.d.ts +1 -1
  36. package/dist/controller/layoutPipeline.js +2 -0
  37. package/dist/controller/noteEditorManager.d.ts +4 -0
  38. package/dist/controller/noteEditorManager.js +113 -15
  39. package/dist/docx/attributeRemainder.js +1 -0
  40. package/dist/docx/bookmarkIds.d.ts +11 -0
  41. package/dist/docx/bookmarkIds.js +33 -0
  42. package/dist/docx/canonicalSessionInput.d.ts +11 -0
  43. package/dist/docx/canonicalSessionInput.js +27 -0
  44. package/dist/docx/canonicalStoryRepack.d.ts +10 -0
  45. package/dist/docx/canonicalStoryRepack.js +41 -0
  46. package/dist/docx/contentTypeRegistry.d.ts +8 -0
  47. package/dist/docx/contentTypeRegistry.js +64 -0
  48. package/dist/docx/documentParser.d.ts +14 -1
  49. package/dist/docx/documentParser.js +17 -4
  50. package/dist/docx/drawingIdNormalization.js +23 -8
  51. package/dist/docx/ensureParaIds.d.ts +12 -1
  52. package/dist/docx/ensureParaIds.js +173 -213
  53. package/dist/docx/foldedListNumberFields.d.ts +85 -0
  54. package/dist/docx/foldedListNumberFields.js +267 -0
  55. package/dist/docx/headerFooterVerbatim.d.ts +14 -1
  56. package/dist/docx/headerFooterVerbatim.js +95 -2
  57. package/dist/docx/listNumberingInstances.js +11 -9
  58. package/dist/docx/noteIds.d.ts +9 -0
  59. package/dist/docx/noteIds.js +17 -0
  60. package/dist/docx/noteReferenceMark.d.ts +3 -1
  61. package/dist/docx/noteReferenceMark.js +15 -14
  62. package/dist/docx/numberingIds.d.ts +14 -0
  63. package/dist/docx/numberingIds.js +16 -0
  64. package/dist/docx/numberingParser.d.ts +3 -1
  65. package/dist/docx/numberingParser.js +17 -3
  66. package/dist/docx/numericIdAllocator.d.ts +12 -0
  67. package/dist/docx/numericIdAllocator.js +33 -0
  68. package/dist/docx/numericIdNormalization.d.ts +16 -0
  69. package/dist/docx/numericIdNormalization.js +174 -0
  70. package/dist/docx/packageParts.d.ts +3 -1
  71. package/dist/docx/packageParts.js +65 -16
  72. package/dist/docx/paragraphMarkPropertyPresence.d.ts +9 -0
  73. package/dist/docx/paragraphMarkPropertyPresence.js +21 -0
  74. package/dist/docx/paragraphParser.js +101 -53
  75. package/dist/docx/paragraphPropertySource.d.ts +15 -1
  76. package/dist/docx/paragraphPropertySource.js +76 -22
  77. package/dist/docx/paragraphTextBoxEnrichment.js +2 -1
  78. package/dist/docx/parser.js +19 -6
  79. package/dist/docx/rasterMime.d.ts +64 -0
  80. package/dist/docx/rasterMime.js +116 -0
  81. package/dist/docx/replyToComment.js +13 -6
  82. package/dist/docx/reviewHistoryNamespace.d.ts +4 -0
  83. package/dist/docx/reviewHistoryNamespace.js +4 -0
  84. package/dist/docx/reviewResolutionProvenance.d.ts +25 -0
  85. package/dist/docx/reviewResolutionProvenance.js +153 -0
  86. package/dist/docx/rezip.d.ts +7 -3
  87. package/dist/docx/rezip.js +121 -52
  88. package/dist/docx/runConsolidator.d.ts +2 -58
  89. package/dist/docx/runConsolidator.js +3 -175
  90. package/dist/docx/runParser.d.ts +2 -1
  91. package/dist/docx/runParser.js +156 -116
  92. package/dist/docx/saveDiagnostics.d.ts +11 -0
  93. package/dist/docx/saveDiagnostics.js +0 -0
  94. package/dist/docx/selectiveSave.d.ts +2 -1
  95. package/dist/docx/selectiveSave.js +14 -1
  96. package/dist/docx/selectiveXmlPatch.d.ts +16 -8
  97. package/dist/docx/selectiveXmlPatch.js +74 -2
  98. package/dist/docx/serializer/headerFooterSerializer.d.ts +5 -1
  99. package/dist/docx/serializer/headerFooterSerializer.js +19 -11
  100. package/dist/docx/serializer/noteSerializer.d.ts +2 -2
  101. package/dist/docx/serializer/noteSerializer.js +24 -8
  102. package/dist/docx/serializer/paragraphSerializer.js +41 -4
  103. package/dist/docx/serializer/partNamespaces.js +6 -3
  104. package/dist/docx/serializer/runSerializer.js +8 -5
  105. package/dist/docx/serializer/trackedChangeAttributes.js +7 -1
  106. package/dist/docx/server/build.js +14 -3
  107. package/dist/docx/server/createBilingualDocument.js +10 -9
  108. package/dist/docx/settingsHeaderFooterUpdate.d.ts +5 -0
  109. package/dist/docx/settingsHeaderFooterUpdate.js +90 -0
  110. package/dist/docx/settingsParser.d.ts +1 -2
  111. package/dist/docx/settingsParser.js +5 -6
  112. package/dist/docx/storyBlockReplay.d.ts +11 -0
  113. package/dist/docx/storyBlockReplay.js +367 -0
  114. package/dist/docx/streamingXmlParser.d.ts +31 -1
  115. package/dist/docx/streamingXmlParser.js +136 -21
  116. package/dist/docx/structuralXmlPatch.js +8 -1
  117. package/dist/docx/unzip.d.ts +3 -1
  118. package/dist/docx/unzip.js +36 -16
  119. package/dist/docx/verbatimCapture.d.ts +3 -1
  120. package/dist/docx/verbatimCapture.js +49 -6
  121. package/dist/i18n/messages/ar.gen.d.ts +5 -0
  122. package/dist/i18n/messages/ar.gen.js +656 -0
  123. package/dist/i18n/messages/cs.gen.d.ts +5 -0
  124. package/dist/i18n/messages/cs.gen.js +656 -0
  125. package/dist/i18n/messages/de.gen.d.ts +5 -0
  126. package/dist/i18n/messages/de.gen.js +656 -0
  127. package/dist/i18n/messages/en.gen.d.ts +5 -0
  128. package/dist/i18n/messages/en.gen.js +656 -0
  129. package/dist/i18n/messages/es.gen.d.ts +5 -0
  130. package/dist/i18n/messages/es.gen.js +656 -0
  131. package/dist/i18n/messages/et.gen.d.ts +5 -0
  132. package/dist/i18n/messages/et.gen.js +656 -0
  133. package/dist/i18n/messages/fr.gen.d.ts +5 -0
  134. package/dist/i18n/messages/fr.gen.js +656 -0
  135. package/dist/i18n/messages/he.gen.d.ts +5 -0
  136. package/dist/i18n/messages/he.gen.js +656 -0
  137. package/dist/i18n/messages/hi.gen.d.ts +5 -0
  138. package/dist/i18n/messages/hi.gen.js +656 -0
  139. package/dist/i18n/messages/hu.gen.d.ts +5 -0
  140. package/dist/i18n/messages/hu.gen.js +656 -0
  141. package/dist/i18n/messages/locales.d.ts +5 -0
  142. package/dist/i18n/messages/locales.js +22 -0
  143. package/dist/i18n/messages/lt.gen.d.ts +5 -0
  144. package/dist/i18n/messages/lt.gen.js +656 -0
  145. package/dist/i18n/messages/lv.gen.d.ts +5 -0
  146. package/dist/i18n/messages/lv.gen.js +656 -0
  147. package/dist/i18n/messages/pl.gen.d.ts +5 -0
  148. package/dist/i18n/messages/pl.gen.js +656 -0
  149. package/dist/i18n/messages/pt-BR.gen.d.ts +5 -0
  150. package/dist/i18n/messages/pt-BR.gen.js +656 -0
  151. package/dist/i18n/messages/sk.gen.d.ts +5 -0
  152. package/dist/i18n/messages/sk.gen.js +656 -0
  153. package/dist/i18n/messages/tr.gen.d.ts +5 -0
  154. package/dist/i18n/messages/tr.gen.js +656 -0
  155. package/dist/i18n/messages/zh-CN.gen.d.ts +5 -0
  156. package/dist/i18n/messages/zh-CN.gen.js +656 -0
  157. package/dist/i18n/messages.d.ts +2 -3
  158. package/dist/i18n/messages.js +1 -19
  159. package/dist/internal/noteMarkerAttrs.d.ts +8 -0
  160. package/dist/internal/noteMarkerAttrs.js +16 -0
  161. package/dist/internal/pageBreakRunSourceDescendantIndex.js +1 -0
  162. package/dist/internal/prosemirrorAttrBoundary.d.ts +21 -0
  163. package/dist/internal/prosemirrorAttrBoundary.js +50 -0
  164. package/dist/layout-bridge/convert/fixedTableColumnWidths.d.ts +6 -0
  165. package/dist/layout-bridge/convert/fixedTableColumnWidths.js +23 -0
  166. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  167. package/dist/layout-bridge/convert/footnoteLayout.js +3 -3
  168. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  169. package/dist/layout-bridge/convert/headerFooterLayout.js +1 -0
  170. package/dist/layout-bridge/convert/noteReferences.d.ts +1 -3
  171. package/dist/layout-bridge/convert/noteReferences.js +1 -6
  172. package/dist/layout-bridge/convert/paragraphRuns.js +2 -4
  173. package/dist/layout-bridge/convert/tableConversion.js +4 -1
  174. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +2 -2
  175. package/dist/layout-bridge/convert/toFlowBlocks.js +2 -2
  176. package/dist/layout-painter/index.js +2 -5
  177. package/dist/managers/DocumentLoaderManager.d.ts +1 -0
  178. package/dist/managers/DocumentLoaderManager.js +8 -1
  179. package/dist/markdown/renderBlock.js +15 -1
  180. package/dist/markdown/renderParagraph.js +9 -13
  181. package/dist/markdown/renderRuns.js +3 -2
  182. package/dist/markdown/renderTable.js +2 -0
  183. package/dist/markdown/types.d.ts +3 -9
  184. package/dist/paged-layout/editorScrollRoot.d.ts +15 -0
  185. package/dist/paged-layout/editorScrollRoot.js +72 -0
  186. package/dist/paged-layout/scrollToPmPosition.js +8 -22
  187. package/dist/prosemirror/attrs/index.d.ts +2 -12
  188. package/dist/prosemirror/attrs/index.js +22 -48
  189. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +2 -1
  190. package/dist/prosemirror/canonicalCommands.d.ts +97 -0
  191. package/dist/prosemirror/canonicalCommands.js +28 -0
  192. package/dist/prosemirror/commands/clearParagraphIndent.d.ts +6 -0
  193. package/dist/prosemirror/commands/clearParagraphIndent.js +25 -0
  194. package/dist/prosemirror/commands/pageBreak.js +15 -1
  195. package/dist/prosemirror/commentIdAllocator.d.ts +15 -22
  196. package/dist/prosemirror/commentIdAllocator.js +50 -25
  197. package/dist/prosemirror/commentReferenceAttrs.d.ts +2 -1
  198. package/dist/prosemirror/conversion/fromProseDoc.js +91 -19
  199. package/dist/prosemirror/conversion/listRenderingDefinition.d.ts +6 -0
  200. package/dist/prosemirror/conversion/listRenderingDefinition.js +97 -0
  201. package/dist/prosemirror/conversion/toProseDoc.d.ts +4 -3
  202. package/dist/prosemirror/conversion/toProseDoc.js +51 -11
  203. package/dist/prosemirror/executeEditorCommand.d.ts +11 -0
  204. package/dist/prosemirror/executeEditorCommand.js +26 -0
  205. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  206. package/dist/prosemirror/extensions/core/HistoryExtension.js +97 -5
  207. package/dist/prosemirror/extensions/core/ParagraphExtension.js +53 -20
  208. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +22 -28
  209. package/dist/prosemirror/extensions/features/ListExtension.js +18 -5
  210. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.d.ts +5 -2
  211. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +13 -1
  212. package/dist/prosemirror/extensions/marks/TextColorExtension.js +3 -2
  213. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  214. package/dist/prosemirror/extensions/marks/markUtils.js +70 -8
  215. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.d.ts +6 -0
  216. package/dist/prosemirror/extensions/nodes/NoteMarkerExtension.js +36 -0
  217. package/dist/prosemirror/extensions/nodes/PreservedXmlExtension.js +4 -2
  218. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -6
  219. package/dist/prosemirror/listMarker.d.ts +1 -0
  220. package/dist/prosemirror/listMarker.js +16 -7
  221. package/dist/prosemirror/listNumbering.js +26 -5
  222. package/dist/prosemirror/listRenderingAttrs.d.ts +1 -0
  223. package/dist/prosemirror/listRenderingAttrs.js +3 -0
  224. package/dist/prosemirror/markupViewNotes.js +3 -2
  225. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +2 -1
  226. package/dist/prosemirror/noteReferenceReview.js +5 -3
  227. package/dist/prosemirror/plugins/revisionIds.d.ts +23 -19
  228. package/dist/prosemirror/plugins/revisionIds.js +110 -29
  229. package/dist/prosemirror/plugins/suggestionMode.d.ts +2 -2
  230. package/dist/prosemirror/plugins/suggestionMode.js +246 -42
  231. package/dist/prosemirror/rangeAnchorAttrs.d.ts +2 -1
  232. package/dist/prosemirror/runFormattingFromMarks.d.ts +4 -1
  233. package/dist/prosemirror/runFormattingFromMarks.js +15 -1
  234. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -1
  235. package/dist/prosemirror/runFormattingInlineCarriers.js +4 -1
  236. package/dist/prosemirror/schema/marks.d.ts +2 -0
  237. package/dist/prosemirror/schema/nodes.d.ts +10 -2
  238. package/dist/prosemirror/storyListNumbering.js +11 -9
  239. package/dist/prosemirror/textBoxAnchorAttrs.d.ts +2 -1
  240. package/dist/prosemirror/textInput.d.ts +6 -1
  241. package/dist/prosemirror/textInput.js +14 -3
  242. package/dist/prosemirror/trackedRevisionPath.js +2 -1
  243. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -0
  244. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -0
  245. package/dist/prosemirror/utils/visualLineNavigation.js +6 -8
  246. package/dist/prosemirror/validation.js +4 -0
  247. package/dist/types/content.d.ts +2 -2
  248. package/dist/utils/createDocument.js +2 -2
  249. package/dist/utils/mergeDocumentContent.d.ts +2 -2
  250. package/dist/utils/mergeDocumentContent.js +11 -8
  251. package/package.json +14 -2
@@ -20,7 +20,7 @@ type FolioAIEditView = {
20
20
  /**
21
21
  * Fixed revision provenance, for callers whose output must be reproducible.
22
22
  * Both halves of the stamp travel together because either one left to the
23
- * ambient clock (`new Date()` for the date, a `Date.now()`-seeded cursor for
23
+ * ambient clock (`new Date()` for the date, the shared bounded allocator for
24
24
  * the ids) makes the produced package differ between two runs over the same
25
25
  * inputs. `idSeed` starts a contiguous range the batch allocates from, so it
26
26
  * must sit above every revision id the target document already carries.
@@ -21,6 +21,7 @@ import { carryParagraphProperties, paragraphLeftAfter, propertiesSetInBatch, rec
21
21
  import { directParagraphSpacing, paragraphSpacingAttrPatch, paragraphSpacingEqual, paragraphSpacingFromFormatting, withDirectParagraphSpacing } from "../prosemirror/paragraphSpacing.js";
22
22
  import { getDocumentNumbering, getDocumentNumberingInstanceIds } from "../prosemirror/plugins/documentNumbering.js";
23
23
  import { getDocumentStyleDefinitions, getDocumentStyleResolver } from "../prosemirror/plugins/documentStyleState.js";
24
+ import { claimRevisionIds, nextRevisionId, nextRevisionIdRange, reserveRevisionIds, seedRevisionIdsFromDoc } from "../prosemirror/plugins/revisionIds.js";
24
25
  import { rebaseParagraphRuns } from "../prosemirror/rebaseParagraphRuns.js";
25
26
  import { NON_INCLUSIVE_MARK_DISPOSITION, addCarriedMarks, annotatedReplacement, commentsAcrossBlockBoundary, commentsForTrackedInsertion, hasReplacedAnnotations, inheritedReplacementMarks, placeTrackedInsertion, surveyReplacedAnnotations } from "../prosemirror/replacedAnnotations.js";
26
27
  import { applyMarksToRunFormattingRepresentation, runFormattingInlineControlNodeName, selectRunFormattingCarrierRepresentations } from "../prosemirror/runFormattingInlineCarriers.js";
@@ -825,24 +826,6 @@ const applyTrackedInlineFormattingToRanges = ({ tr, schema, doc = tr.doc, ranges
825
826
  };
826
827
  };
827
828
  /**
828
- * Module-scoped monotonic counter for tracked-change revision ids.
829
- * Seeded once from `Date.now()` so ids are roughly time-ordered for
830
- * humans reading raw DOCX, then incremented per allocation. A bare
831
- * `Date.now()` seed per applyAIEditOperations call would collide
832
- * across batches that fire within the same millisecond (the panel's
833
- * Accept-all loop does exactly that — multiple calls in tight
834
- * succession).
835
- *
836
- * A batch without a revision stamp allocates from it as it writes and claims
837
- * each operation's ids once they are written, rather than reserving a guess
838
- * up front: how many revisions an operation records is known only once it has
839
- * recorded them (clearing a background records one run-property change per
840
- * carrier). The claim also comes before anything that may start another
841
- * batch, a comment-id callback or the dispatch, so batches in one realm never
842
- * share an id and follow one another without a gap.
843
- */
844
- let revisionIdCursor = Date.now() * 1e3;
845
- /**
846
829
  * Walk the live doc once and bucket every textblock by its
847
830
  * normalised text hash. Resolution then maps each snapshot anchor
848
831
  * to the live block at the same ordinal among same-hash siblings —
@@ -1502,6 +1485,22 @@ const finalParagraphPredecessor = (doc, at) => {
1502
1485
  }
1503
1486
  return null;
1504
1487
  };
1488
+ /**
1489
+ * Whether a sibling between a final carrier's predecessor and the carrier
1490
+ * has its break deleted by this batch.
1491
+ */
1492
+ const crossesBatchDeletion = ({ doc, from, to, batchRevisionIds }) => {
1493
+ const $to = doc.resolve(to);
1494
+ let position = to;
1495
+ for (let index = $to.index() - 1; index >= 0 && position > from; index--) {
1496
+ const node = $to.parent.child(index);
1497
+ position -= node.nodeSize;
1498
+ const mark = node.attrs["pPrMark"];
1499
+ const revisionId = isPlainDeletedPPrMark(mark) ? addedOrDeletedBreakRevisionId(mark) : null;
1500
+ if (revisionId !== null && batchRevisionIds.has(revisionId)) return true;
1501
+ }
1502
+ return false;
1503
+ };
1505
1504
  /** Pending retirements, read after the merge has mapped any inserted separator. */
1506
1505
  const pendingRemovedFinalBreakPositions = (tr, deletions) => {
1507
1506
  const positions = /* @__PURE__ */ new Set();
@@ -1586,7 +1585,12 @@ const withRetiredFinalParagraphs = ({ tr, deletions, mergedPropertyTargets, appl
1586
1585
  date,
1587
1586
  ...revisionExtras
1588
1587
  },
1589
- keep: propertiesSetInBatch(emptied, batchRevisionIds)
1588
+ keep: crossesBatchDeletion({
1589
+ doc: tr.doc,
1590
+ from: position + previous.nodeSize,
1591
+ to: at,
1592
+ batchRevisionIds
1593
+ }) ? /* @__PURE__ */ new Set() : propertiesSetInBatch(emptied, batchRevisionIds)
1590
1594
  });
1591
1595
  resolvedOperationIds.add(operationId);
1592
1596
  addedRevisions.push({
@@ -2060,6 +2064,7 @@ const buildInsertedParagraphs = ({ item, schema, formattingFromStyle, mode, auth
2060
2064
  };
2061
2065
  };
2062
2066
  const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: requestedOperations, mode = "tracked-changes", author = "AI", initials, createCommentId, revisionStamp, revisionIdSeed, wordDiff, wordDiffMode = "bounded", tableTemplates, replacementBackground = "clear", undefinedStyles = "refuse" }) => {
2067
+ seedRevisionIdsFromDoc(view.state.doc);
2063
2068
  const applied = [];
2064
2069
  const skipped = [];
2065
2070
  const normalizations = [];
@@ -2116,7 +2121,7 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
2116
2121
  id: operation.id,
2117
2122
  reason: "unsupportedBlock"
2118
2123
  })),
2119
- nextRevisionId: revisionIdSeed ?? revisionStamp?.idSeed ?? revisionIdCursor
2124
+ nextRevisionId: revisionIdSeed ?? revisionStamp?.idSeed ?? nextRevisionId()
2120
2125
  };
2121
2126
  const liveBlocks = collectLiveBlocksByHash(view.state.doc);
2122
2127
  const liveBlocksByParaId = collectLiveBlocksByParaId(view.state.doc);
@@ -2226,14 +2231,14 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
2226
2231
  item,
2227
2232
  operationId: item.operation.id,
2228
2233
  target: getTableMutationPlanTarget(item)
2229
- })));
2234
+ })), view.state.doc);
2230
2235
  skipped.push(...tablePlan.skipped);
2231
2236
  const executableResolved = tablePlan.executable;
2232
2237
  if (executableResolved.length === 0) return {
2233
2238
  applied,
2234
2239
  skipped,
2235
2240
  ...normalizations.length > 0 && { normalizations },
2236
- nextRevisionId: revisionIdSeed ?? revisionStamp?.idSeed ?? revisionIdCursor
2241
+ nextRevisionId: revisionIdSeed ?? revisionStamp?.idSeed ?? nextRevisionId()
2237
2242
  };
2238
2243
  const moveSideCounts = /* @__PURE__ */ new Map();
2239
2244
  for (const { operation } of executableResolved) {
@@ -2268,17 +2273,20 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations: reques
2268
2273
  const mergedPropertyTargets = [];
2269
2274
  const deferredNoopFinalDeletions = /* @__PURE__ */ new Set();
2270
2275
  const ownsSharedRevisionIdCursor = revisionIdSeed === void 0 && revisionStamp === void 0;
2271
- let revisionSeed = revisionIdSeed ?? revisionStamp?.idSeed ?? revisionIdCursor;
2272
- /**
2273
- * Claim the shared ids below `nextRevisionId` for this batch. A seeded or
2274
- * stamped batch allocates from its own range and claims nothing.
2275
- */
2276
- const claimSharedRevisionIds = (nextRevisionId) => {
2277
- if (ownsSharedRevisionIdCursor) revisionIdCursor = Math.max(revisionIdCursor, nextRevisionId);
2276
+ let revisionSeed = revisionIdSeed ?? revisionStamp?.idSeed ?? nextRevisionIdRange();
2277
+ let claimedThrough = revisionSeed;
2278
+ const claimSharedRevisionIds = (next) => {
2279
+ if (revisionIdSeed !== void 0) return;
2280
+ if (ownsSharedRevisionIdCursor) claimRevisionIds(claimedThrough, next);
2281
+ else reserveRevisionIds(claimedThrough, next);
2282
+ claimedThrough = next;
2278
2283
  };
2279
- /** Continue past any shared id a batch the host started meanwhile claimed. */
2284
+ /** Continue past ids a reentrant callback allocated in this realm. */
2280
2285
  const continueSharedRevisionIds = () => {
2281
- if (ownsSharedRevisionIdCursor) revisionSeed = Math.max(revisionSeed, revisionIdCursor);
2286
+ if (ownsSharedRevisionIdCursor && nextRevisionId() !== claimedThrough) {
2287
+ revisionSeed = nextRevisionIdRange();
2288
+ claimedThrough = revisionSeed;
2289
+ }
2282
2290
  };
2283
2291
  const date = revisionStamp?.date ?? (/* @__PURE__ */ new Date()).toISOString();
2284
2292
  const insertedColumnCounts = /* @__PURE__ */ new Map();
@@ -3738,7 +3746,7 @@ const previewFolioAIEditOperationsWithResult = (options) => {
3738
3746
  applied: result.applied.map(({ id }) => ({ id })),
3739
3747
  skipped: result.skipped,
3740
3748
  ...result.normalizations !== void 0 && { normalizations: result.normalizations },
3741
- nextRevisionId: options.revisionStamp?.idSeed ?? revisionIdCursor
3749
+ nextRevisionId: options.revisionStamp?.idSeed ?? nextRevisionId()
3742
3750
  },
3743
3751
  doc: previewView.state.doc,
3744
3752
  commentIds
@@ -179,7 +179,7 @@ type FolioDocxComparisonStoryProjection = {
179
179
  type FolioDocxComparisonProjection = {
180
180
  stories: readonly FolioDocxComparisonStoryProjection[];
181
181
  revisions: {
182
- highestId: number;
182
+ ids: readonly number[];
183
183
  present: boolean;
184
184
  };
185
185
  };
@@ -350,7 +350,6 @@ declare class FolioDocxReviewer {
350
350
  private readonly importedFooters;
351
351
  private readonly resolvedStoryExpectations;
352
352
  private readonly createdComments;
353
- private readonly usedCommentIds;
354
353
  /** Comments the body anchored when it was loaded, read as the editor projects it. */
355
354
  private readonly loadedMainCommentIds;
356
355
  private readonly documentOperationUndoEntries;
@@ -7,6 +7,7 @@ import { applyReplyThreadMarkers } from "../docx/commentReplyMarkers.js";
7
7
  import { rebindDrawingImageRelationship } from "../docx/drawingRelationships.js";
8
8
  import { getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
9
9
  import { getHeaderFooterText } from "../docx/headerFooterParser.js";
10
+ import { createNumberingIdAllocator } from "../docx/numberingIds.js";
10
11
  import { getCachedNumberingMap } from "../docx/numberingParser.js";
11
12
  import { recreateProseNodeWithParagraphPropertySource, transferProseParagraphPropertySource } from "../docx/paragraphPropertySource.js";
12
13
  import { parseDocx } from "../docx/parser.js";
@@ -20,6 +21,7 @@ import { captureSectionReferenceInventory, resolvedSectionReferenceLosses, withS
20
21
  import { expectCharacterStyleMarkAttrs, expectFootnoteRefMarkAttrs } from "../prosemirror/attrs/index.js";
21
22
  import { acceptAIEditRevision, acceptSuggestion, getSuggestions, rejectAIEditRevision, rejectAllSuggestions, rejectSuggestion, resolveAllChangesInHeadlessState, suggestionIdOfRevision } from "../prosemirror/commands/comments.js";
22
23
  import { sectionRejectProperties } from "../prosemirror/commands/propertyChangeScope.js";
24
+ import { allocateCommentId, createCommentIdAllocator, seedCommentAllocator } from "../prosemirror/commentIdAllocator.js";
23
25
  import { proseDocToBlocks, updateDocumentContent } from "../prosemirror/conversion/fromProseDoc.js";
24
26
  import { footnoteToProseDoc, headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
25
27
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
@@ -68,14 +70,6 @@ import JSZip from "jszip";
68
70
  *
69
71
  * Scope: main, header, footer, footnote, and endnote blocks.
70
72
  */
71
- /**
72
- * Standalone comment-id allocator for the reviewer. The React editor uses
73
- * `Date.now()`-seeded ids from `commentsHelpers`; that module is DOM-bound
74
- * (`EditorView`, `findBodyPmAnchors`) and unimportable here, so the reviewer
75
- * mints its own. Seeded once per realm and incremented so ids stay unique
76
- * across reviewers created within the same millisecond.
77
- */
78
- let commentIdCursor = Date.now();
79
73
  let undoHandleCursor = Date.now();
80
74
  const createReviewerComment = ({ id, text, author, date }) => ({
81
75
  id,
@@ -399,7 +393,6 @@ var FolioDocxReviewer = class FolioDocxReviewer {
399
393
  importedFooters = /* @__PURE__ */ new Map();
400
394
  resolvedStoryExpectations = /* @__PURE__ */ new Map();
401
395
  createdComments = [];
402
- usedCommentIds;
403
396
  /** Comments the body anchored when it was loaded, read as the editor projects it. */
404
397
  loadedMainCommentIds;
405
398
  documentOperationUndoEntries = [];
@@ -418,7 +411,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
418
411
  this.originalBuffer = args.originalBuffer;
419
412
  this.state = args.state;
420
413
  this.author = args.author;
421
- this.usedCommentIds = new Set((args.baseDocument.package.document.comments ?? []).map(({ id }) => id));
414
+ seedCommentAllocator(createCommentIdAllocator(), args.baseDocument.package.document.comments, { state: args.state });
422
415
  this.loadedMainCommentIds = anchoredCommentIdsInProseDoc(args.state.doc);
423
416
  comparisonAccessByReviewer.set(this, Object.freeze({
424
417
  stageTerminalTableReviewCarrier: (target) => this.stageTerminalTableReviewCarrier(target),
@@ -571,8 +564,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
571
564
  const targetAbstracts = new Map(target.abstractNums.map((entry) => [entry.abstractNumId, entry]));
572
565
  const levelsByNumId = referencedNumberingLevelsByNumId({ references });
573
566
  const importedAbstractIds = /* @__PURE__ */ new Map();
574
- let nextAbstractId = 0;
575
- for (const id of abstracts.keys()) nextAbstractId = Math.max(nextAbstractId, id + 1);
567
+ const abstractIds = createNumberingIdAllocator("abstract", [...abstracts.keys(), ...targetAbstracts.keys()]);
576
568
  for (const numId of levelsByNumId.keys()) {
577
569
  const targetNum = targetNums.get(numId);
578
570
  if (!targetNum) return "conflict";
@@ -592,8 +584,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
592
584
  if (abstractNumId === void 0) {
593
585
  abstractNumId = targetAbstract.abstractNumId;
594
586
  const collision = abstracts.get(abstractNumId);
595
- if (collision && canonicalJson(collision) !== canonicalJson(targetAbstract)) abstractNumId = nextAbstractId++;
596
- nextAbstractId = Math.max(nextAbstractId, abstractNumId + 1);
587
+ if (collision && canonicalJson(collision) !== canonicalJson(targetAbstract)) abstractNumId = abstractIds.next();
597
588
  importedAbstractIds.set(targetAbstract.abstractNumId, abstractNumId);
598
589
  abstracts.set(abstractNumId, {
599
590
  ...targetAbstract,
@@ -628,9 +619,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
628
619
  const targetNums = new Map(target.nums.map((entry) => [entry.numId, entry]));
629
620
  const targetAbstracts = new Map(target.abstractNums.map((entry) => [entry.abstractNumId, entry]));
630
621
  const levelsByNumId = referencedNumberingLevelsByNumId({ references });
631
- let nextNumId = 0;
632
- for (const id of nums.keys()) nextNumId = Math.max(nextNumId, id + 1);
633
- for (const id of targetNums.keys()) nextNumId = Math.max(nextNumId, id + 1);
622
+ const numberingIds = createNumberingIdAllocator("num", [...nums.keys(), ...targetNums.keys()]);
634
623
  const remapped = /* @__PURE__ */ new Map();
635
624
  for (const numId of levelsByNumId.keys()) {
636
625
  const targetNum = targetNums.get(numId);
@@ -642,7 +631,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
642
631
  target,
643
632
  numId,
644
633
  levelsByNumId
645
- })) remapped.set(numId, nextNumId++);
634
+ })) remapped.set(numId, numberingIds.next());
646
635
  }
647
636
  return remapped;
648
637
  }
@@ -759,18 +748,18 @@ var FolioDocxReviewer = class FolioDocxReviewer {
759
748
  }
760
749
  projectComparisonStoriesInternal(mode) {
761
750
  const handles = this.listStoryHandlesInternal();
762
- let highestId = 0;
751
+ const ids = /* @__PURE__ */ new Set();
763
752
  let present = false;
764
753
  if (mode === "with-revision-census") {
765
754
  for (const change of this.currentFinalSectionProperties()?.propertyChanges ?? []) {
766
- highestId = Math.max(highestId, change.info.id);
755
+ ids.add(change.info.id);
767
756
  present = true;
768
757
  }
769
758
  for (const handle of handles) {
770
759
  const state = this.getEditableStoryState(handle);
771
760
  if (!state) continue;
772
761
  const stats = getTrackedChangeStatsFromDoc(state.doc);
773
- highestId = Math.max(highestId, stats.highestId);
762
+ for (const id of stats.ids) ids.add(id);
774
763
  present ||= stats.present;
775
764
  }
776
765
  }
@@ -785,7 +774,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
785
774
  return {
786
775
  stories,
787
776
  revisions: {
788
- highestId,
777
+ ids: [...ids],
789
778
  present
790
779
  }
791
780
  };
@@ -1231,7 +1220,6 @@ var FolioDocxReviewer = class FolioDocxReviewer {
1231
1220
  });
1232
1221
  if (!reply) return null;
1233
1222
  this.createdComments.push(reply);
1234
- this.usedCommentIds.add(reply.id);
1235
1223
  this.anchorReplyInEditor({
1236
1224
  parentId: reply.parentId ?? parentId,
1237
1225
  replyId: reply.id
@@ -1907,6 +1895,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
1907
1895
  const source = story.type === "header" || story.type === "footer" ? this.getHeaderFooterStory(story) : this.getNoteStory(story);
1908
1896
  if (!source) return null;
1909
1897
  const conversionOptions = {
1898
+ ...this.baseDocument.package.numbering !== void 0 && { numbering: this.baseDocument.package.numbering },
1910
1899
  ...this.baseDocument.package.styles !== void 0 && { styles: this.baseDocument.package.styles },
1911
1900
  ...this.baseDocument.package.theme !== void 0 && { theme: this.baseDocument.package.theme }
1912
1901
  };
@@ -2186,10 +2175,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
2186
2175
  }
2187
2176
  /** Allocate outside every parsed or newly-created comment and reply id. */
2188
2177
  nextCommentId() {
2189
- while (this.usedCommentIds.has(commentIdCursor)) commentIdCursor += 1;
2190
- const id = commentIdCursor++;
2191
- this.usedCommentIds.add(id);
2192
- return id;
2178
+ return allocateCommentId();
2193
2179
  }
2194
2180
  /**
2195
2181
  * Drive a ProseMirror command against the reviewer's headless state via the
@@ -76,6 +76,7 @@ declare const getTrackedChangeGroupIdsFromDoc: (doc: Node, id: number) => number
76
76
  declare const getTrackedChangeStatsFromDoc: (doc: Node) => {
77
77
  highestId: number;
78
78
  present: boolean;
79
+ ids: readonly number[];
79
80
  };
80
81
  /**
81
82
  * The comment anchors present in the body, read from the `comment` mark the
@@ -313,11 +313,16 @@ const getTrackedChangeGroupIdsFromDoc = (doc, id) => getTrackedChangeGroupsFromP
313
313
  /** @internal Read revision statistics without paying for an unrelated block projection. */
314
314
  const getTrackedChangeStatsFromDoc = (doc) => {
315
315
  let highestId = 0;
316
+ const revisionIds = /* @__PURE__ */ new Set();
316
317
  const groups = getTrackedChangeGroupsFromProjectedDoc(doc, null);
317
- for (const { ids } of groups) for (const id of ids) highestId = Math.max(highestId, id);
318
+ for (const { ids } of groups) for (const id of ids) {
319
+ highestId = Math.max(highestId, id);
320
+ revisionIds.add(id);
321
+ }
318
322
  return {
319
323
  highestId,
320
- present: groups.length > 0
324
+ present: groups.length > 0,
325
+ ids: [...revisionIds]
321
326
  };
322
327
  };
323
328
  /**
@@ -1,3 +1,4 @@
1
+ import { Node } from "prosemirror-model";
1
2
  //#region src/ai-edits/table-mutation-plan.d.ts
2
3
  type TableRectangle = {
3
4
  left: number;
@@ -32,7 +33,7 @@ type TableMutationPlan<T> = {
32
33
  executable: T[];
33
34
  skipped: TableMutationPlanSkip[];
34
35
  };
35
- declare const planTableMutations: <T>(candidates: readonly TableMutationPlanCandidate<T>[]) => TableMutationPlan<T>;
36
+ declare const planTableMutations: <T>(candidates: readonly TableMutationPlanCandidate<T>[], doc: Node) => TableMutationPlan<T>;
36
37
  declare const tableRectanglesEqual: (left: TableRectangle, right: TableRectangle) => boolean;
37
38
  //#endregion
38
39
  export { TableMutationPlanTarget, TableRectangle, planTableMutations, tableRectanglesEqual };
@@ -1,5 +1,7 @@
1
+ import { panic } from "better-result";
2
+ import { TableMap } from "prosemirror-tables";
1
3
  //#region src/ai-edits/table-mutation-plan.ts
2
- const planTableMutations = (candidates) => {
4
+ const planTableMutations = (candidates, doc) => {
3
5
  const tableStructureMutations = /* @__PURE__ */ new Set();
4
6
  const mergeTables = /* @__PURE__ */ new Set();
5
7
  const splitTables = /* @__PURE__ */ new Set();
@@ -44,6 +46,17 @@ const planTableMutations = (candidates) => {
44
46
  });
45
47
  continue;
46
48
  }
49
+ if (claimedRectangles.length > 0 && mergesRemoveRow({
50
+ doc,
51
+ tablePosition: target.tablePosition,
52
+ rectangles: [...claimedRectangles, target.rectangle]
53
+ })) {
54
+ skipped.push({
55
+ id: candidate.operationId,
56
+ reason: "unsupportedBlock"
57
+ });
58
+ continue;
59
+ }
47
60
  claimedRectangles.push(target.rectangle);
48
61
  mergeRectanglesByTable.set(target.tablePosition, claimedRectangles);
49
62
  executable.push(candidate.item);
@@ -84,6 +97,31 @@ const planTableMutations = (candidates) => {
84
97
  skipped
85
98
  };
86
99
  };
100
+ /**
101
+ * Disjoint merges can still share a row's survival. Direct merging closes a
102
+ * row left without cells, invalidating other rectangles' original row indices;
103
+ * tracked merging cannot record that removal. Keep a row-removing merge alone
104
+ * and refuse the later merge when their combined folded cells empty a row.
105
+ */
106
+ const mergesRemoveRow = ({ doc, tablePosition, rectangles }) => {
107
+ const table = doc.nodeAt(tablePosition);
108
+ if (table?.type.spec["tableRole"] !== "table") return panic("A planned cell merge lost its table", { position: tablePosition });
109
+ const map = TableMap.get(table);
110
+ const folded = /* @__PURE__ */ new Set();
111
+ for (const rectangle of rectangles) {
112
+ const kept = map.map[rectangle.top * map.width + rectangle.left];
113
+ for (const position of map.cellsInRect(rectangle)) if (position !== kept) folded.add(position);
114
+ }
115
+ let removesRow = false;
116
+ table.forEach((row, rowOffset) => {
117
+ let remaining = row.childCount;
118
+ row.forEach((_cell, cellOffset) => {
119
+ if (folded.has(rowOffset + 1 + cellOffset)) remaining--;
120
+ });
121
+ if (row.childCount > 0 && remaining === 0) removesRow = true;
122
+ });
123
+ return removesRow;
124
+ };
87
125
  const tableRectanglesOverlap = (left, right) => left.left < right.right && right.left < left.right && left.top < right.bottom && right.top < left.bottom;
88
126
  const tableRectanglesEqual = (left, right) => left.left === right.left && left.top === right.top && left.right === right.right && left.bottom === right.bottom;
89
127
  //#endregion
@@ -6,7 +6,7 @@ type ApplyResult = {
6
6
  stale: string[];
7
7
  };
8
8
  type ApplyOptions = {
9
- view: EditorView;
9
+ view: Pick<EditorView, "state" | "dispatch">;
10
10
  suggestions: AISuggestion[];
11
11
  mode: AISuggestionApplyMode;
12
12
  author: string;
@@ -1,3 +1,4 @@
1
+ import { mintRevisionId, seedRevisionIdsFromDoc } from "../prosemirror/plugins/revisionIds.js";
1
2
  import { resolveSuggestionAnchor } from "./conflict.js";
2
3
  //#region src/ai-suggestions/apply.ts
3
4
  function applySuggestions(options) {
@@ -39,10 +40,10 @@ function applySuggestions(options) {
39
40
  stale: [...stale, ...resolved.map((r) => r.suggestion.id)]
40
41
  };
41
42
  const date = (/* @__PURE__ */ new Date()).toISOString();
42
- let revisionSeed = Date.now();
43
+ seedRevisionIdsFromDoc(view.state.doc);
43
44
  for (const { suggestion, from, to } of resolved) {
44
45
  const attrs = {
45
- revisionId: revisionSeed++,
46
+ revisionId: mintRevisionId(),
46
47
  author,
47
48
  date
48
49
  };
@@ -10,6 +10,7 @@ import { isAltChunkMarkup } from "../docx/altChunk.js";
10
10
  import { isOpaqueNestedRowMarkup, opaqueRevisionCarrierName } from "../docx/opaqueCarrier.js";
11
11
  import { sectionReferenceHistory } from "../docx/sectionReferenceHistory.js";
12
12
  import { sameCanonicalInlinePresentation } from "../internal/compare/inline-presentation.js";
13
+ import { revisionIdSeedAbove } from "../prosemirror/plugins/revisionIds.js";
13
14
  import { createStyleResolver } from "../prosemirror/styles/styleResolver.js";
14
15
  import { canonicalJson } from "../utils/canonicalJson.js";
15
16
  import { createContentComparisonWorkSession } from "./content.js";
@@ -386,7 +387,7 @@ const parseComparison = async (base, target, options) => {
386
387
  reviewer,
387
388
  revisionStamp: {
388
389
  date: options.timestamp,
389
- idSeed: baseProjection.revisions.highestId + 1
390
+ idSeed: revisionIdSeedAbove(baseProjection.revisions.ids)
390
391
  },
391
392
  packageDate,
392
393
  pairs: comparisonPairs,
@@ -83,14 +83,9 @@ type FolioContentTableLocation = {
83
83
  */
84
84
  type FolioContentParagraphAlignment = document_d_exports.ParagraphAlignment;
85
85
  /** Line-height interpretation understood by the neutral comparison model. */
86
- type FolioContentLineSpacingRule = "auto" | "exact" | "atLeast";
86
+ type FolioContentLineSpacingRule = NonNullable<document_d_exports.ParagraphFormatting["lineSpacingRule"]>;
87
87
  /** The complete modeled attribute set of direct paragraph indentation. */
88
- type FolioContentParagraphIndentation = {
89
- indentLeft?: number;
90
- indentRight?: number;
91
- indentFirstLine?: number;
92
- hangingIndent?: boolean;
93
- };
88
+ type FolioContentParagraphIndentation = Pick<document_d_exports.ParagraphFormatting, "indentLeft" | "indentRight" | "indentFirstLine" | "hangingIndent">;
94
89
  /** A concrete numbering instance and its zero-based level. */
95
90
  type FolioContentListReference = {
96
91
  numId: number;
@@ -100,14 +95,7 @@ type FolioContentListReference = {
100
95
  * The complete modeled attribute set of direct paragraph spacing. Optional
101
96
  * fields distinguish an absent attribute from an explicit zero or false value.
102
97
  */
103
- type FolioContentParagraphSpacing = {
104
- spaceBefore?: number;
105
- spaceAfter?: number;
106
- lineSpacing?: number;
107
- lineSpacingRule?: FolioContentLineSpacingRule;
108
- beforeAutospacing?: boolean;
109
- afterAutospacing?: boolean;
110
- };
98
+ type FolioContentParagraphSpacing = Pick<document_d_exports.ParagraphFormatting, "spaceBefore" | "spaceAfter" | "lineSpacing" | "lineSpacingRule" | "beforeAutospacing" | "afterAutospacing">;
111
99
  /** A representation-neutral block in one ordered document story. */
112
100
  type FolioContentBlock<Kind extends string = string> = {
113
101
  id: string;
@@ -0,0 +1,36 @@
1
+ import { EditorState, Transaction } from "prosemirror-state";
2
+ import { EditorView } from "prosemirror-view";
3
+ //#region src/controller/canonicalComposition.d.ts
4
+ type CompositionOptions = {
5
+ begin: () => boolean;
6
+ end: () => void;
7
+ replace: (input: {
8
+ from: number;
9
+ to: number;
10
+ text: string;
11
+ semantic: "composition";
12
+ }) => void;
13
+ refuse: (reason: string) => void;
14
+ };
15
+ type CompositionState = {
16
+ type: "committed";
17
+ } | {
18
+ type: "provisional" | "refused";
19
+ baseline: EditorState;
20
+ phase: "active" | "ended";
21
+ };
22
+ /** Native IME owns the provisional view; the captured canonical projection stays unchanged. */
23
+ declare const createCanonicalComposition: (options: CompositionOptions) => {
24
+ readonly status: CompositionState["type"];
25
+ readonly active: boolean;
26
+ start: (view: EditorView) => void;
27
+ ended: (view: EditorView) => void;
28
+ authorizeNative: (view: EditorView) => void;
29
+ flushed: (view: EditorView) => void;
30
+ recover: (view: EditorView) => void;
31
+ cancel: (view: EditorView) => void;
32
+ reset: () => void;
33
+ accept: (view: EditorView, transaction: Transaction) => boolean;
34
+ };
35
+ //#endregion
36
+ export { createCanonicalComposition };