@stll/folio-core 0.37.4 → 0.38.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 (131) hide show
  1. package/dist/ai-edits/apply.js +275 -88
  2. package/dist/ai-edits/clean-text.js +12 -1
  3. package/dist/ai-edits/headless.d.ts +110 -0
  4. package/dist/ai-edits/headless.js +569 -40
  5. package/dist/ai-edits/index.d.ts +2 -1
  6. package/dist/ai-edits/snapshot.d.ts +24 -1
  7. package/dist/ai-edits/snapshot.js +206 -9
  8. package/dist/ai-edits/table-geometry.d.ts +7 -7
  9. package/dist/ai-edits/table-geometry.js +43 -27
  10. package/dist/ai-edits/table-template.d.ts +2 -1
  11. package/dist/ai-edits/table-template.js +9 -3
  12. package/dist/ai-edits/types.d.ts +38 -16
  13. package/dist/compare/__fixtures__/body-sequence.d.ts +4 -0
  14. package/dist/compare/__fixtures__/body-sequence.js +5 -3
  15. package/dist/compare/compare.d.ts +26 -2
  16. package/dist/compare/compare.js +444 -16
  17. package/dist/compare/content-alignment.js +216 -137
  18. package/dist/compare/content-types.d.ts +36 -2
  19. package/dist/compare/content.d.ts +13 -10
  20. package/dist/compare/content.js +69 -23
  21. package/dist/compare/formatting.d.ts +4 -22
  22. package/dist/compare/formatting.js +8 -112
  23. package/dist/compare/inline-atom-resources.d.ts +6 -0
  24. package/dist/compare/inline-atom-resources.js +26 -0
  25. package/dist/compare/inline-atoms.d.ts +35 -0
  26. package/dist/compare/inline-atoms.js +383 -0
  27. package/dist/compare/inline-provenance.d.ts +36 -0
  28. package/dist/compare/inline-provenance.js +334 -0
  29. package/dist/compare/plan.d.ts +4 -1
  30. package/dist/compare/plan.js +32 -4
  31. package/dist/compare/scenario.d.ts +4 -6
  32. package/dist/compare/section-boundary-properties.d.ts +63 -0
  33. package/dist/compare/section-boundary-properties.js +235 -0
  34. package/dist/compare/style-resources.d.ts +30 -0
  35. package/dist/compare/style-resources.js +404 -0
  36. package/dist/compare/types.d.ts +50 -11
  37. package/dist/compare/types.js +3 -1
  38. package/dist/compare/verification.d.ts +3 -5
  39. package/dist/compare/verification.js +8 -39
  40. package/dist/compat/eigenpal.d.ts +4 -4
  41. package/dist/compat/eigenpal.js +3 -3
  42. package/dist/document-operations.d.ts +5 -3
  43. package/dist/document-operations.js +112 -5
  44. package/dist/docx/blockContentParser.js +14 -2
  45. package/dist/docx/drawingIdNormalization.js +43 -2
  46. package/dist/docx/drawingRelationships.d.ts +10 -0
  47. package/dist/docx/drawingRelationships.js +28 -0
  48. package/dist/docx/fieldParser.js +1 -1
  49. package/dist/docx/hyperlinkParser.js +3 -5
  50. package/dist/docx/imageRawXml.d.ts +8 -0
  51. package/dist/docx/imageRawXml.js +13 -0
  52. package/dist/docx/newImage.d.ts +2 -2
  53. package/dist/docx/newImage.js +3 -3
  54. package/dist/docx/numberingParser.d.ts +1 -13
  55. package/dist/docx/numberingParser.js +31 -37
  56. package/dist/docx/paragraphParser.js +12 -9
  57. package/dist/docx/paragraphPropertySource.d.ts +8 -5
  58. package/dist/docx/paragraphPropertySource.js +16 -4
  59. package/dist/docx/removeHeaderFooterParts.d.ts +14 -0
  60. package/dist/docx/removeHeaderFooterParts.js +87 -0
  61. package/dist/docx/rezip.d.ts +3 -1
  62. package/dist/docx/rezip.js +143 -41
  63. package/dist/docx/runParser.js +16 -5
  64. package/dist/docx/sectionParser.js +3 -0
  65. package/dist/docx/sectionReferenceHistory.d.ts +17 -0
  66. package/dist/docx/sectionReferenceHistory.js +59 -0
  67. package/dist/docx/selectiveSave.js +11 -31
  68. package/dist/docx/selectiveXmlPatch.d.ts +8 -1
  69. package/dist/docx/selectiveXmlPatch.js +62 -2
  70. package/dist/docx/serializer/borderSerializer.d.ts +4 -1
  71. package/dist/docx/serializer/borderSerializer.js +20 -18
  72. package/dist/docx/serializer/commentSerializer.js +1 -1
  73. package/dist/docx/serializer/numberingSerializer.js +1 -1
  74. package/dist/docx/serializer/paragraphSerializer.js +13 -177
  75. package/dist/docx/serializer/partNamespaces.d.ts +1 -1
  76. package/dist/docx/serializer/partNamespaces.js +4 -0
  77. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  78. package/dist/docx/serializer/runSerializer.js +4 -130
  79. package/dist/docx/serializer/sectionPropertiesSerializer.js +5 -2
  80. package/dist/docx/serializer/stylesSerializer.js +1 -1
  81. package/dist/docx/serializer/textFormattingSerializer.d.ts +17 -0
  82. package/dist/docx/serializer/textFormattingSerializer.js +144 -0
  83. package/dist/docx/tableParser.js +21 -11
  84. package/dist/docx/xmlParser.d.ts +10 -1
  85. package/dist/docx/xmlParser.js +23 -1
  86. package/dist/index.d.ts +4 -4
  87. package/dist/index.js +3 -3
  88. package/dist/internal/compare/inline-presentation.d.ts +20 -0
  89. package/dist/internal/compare/inline-presentation.js +222 -0
  90. package/dist/internal/paragraphFormattingSerialization.d.ts +25 -0
  91. package/dist/internal/paragraphFormattingSerialization.js +164 -0
  92. package/dist/internal/sectionReferenceResolution.d.ts +21 -0
  93. package/dist/internal/sectionReferenceResolution.js +72 -0
  94. package/dist/layout-bridge/convert/toFlowBlocks.js +1 -0
  95. package/dist/markdown/renderRuns.js +1 -0
  96. package/dist/markdown/renderTable.js +1 -0
  97. package/dist/prosemirror/attrs/index.js +20 -1
  98. package/dist/prosemirror/commands/comments.d.ts +11 -1
  99. package/dist/prosemirror/commands/comments.js +68 -6
  100. package/dist/prosemirror/commands/propertyChangeScope.d.ts +9 -3
  101. package/dist/prosemirror/commands/propertyChangeScope.js +4 -10
  102. package/dist/prosemirror/conversion/fromProseDoc.js +22 -22
  103. package/dist/prosemirror/conversion/toProseDoc.js +16 -57
  104. package/dist/prosemirror/extensions/core/ParagraphExtension.js +2 -0
  105. package/dist/prosemirror/extensions/marks/RunFormattingOverrideExtension.js +3 -0
  106. package/dist/prosemirror/imageCommit.js +7 -9
  107. package/dist/prosemirror/paragraphIndentation.d.ts +21 -0
  108. package/dist/prosemirror/paragraphIndentation.js +72 -0
  109. package/dist/prosemirror/plugins/documentNumbering.d.ts +3 -1
  110. package/dist/prosemirror/plugins/documentNumbering.js +7 -1
  111. package/dist/prosemirror/plugins/documentStyles.d.ts +3 -1
  112. package/dist/prosemirror/plugins/documentStyles.js +7 -1
  113. package/dist/prosemirror/rebaseParagraphRunFormatting.d.ts +3 -1
  114. package/dist/prosemirror/rebaseParagraphRunFormatting.js +2 -1
  115. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +15 -2
  116. package/dist/prosemirror/runFormattingInlineCarriers.js +33 -3
  117. package/dist/prosemirror/runStyleFormatting.d.ts +15 -2
  118. package/dist/prosemirror/runStyleFormatting.js +76 -2
  119. package/dist/prosemirror/schema/marks.d.ts +3 -1
  120. package/dist/prosemirror/schema/marks.js +2 -0
  121. package/dist/prosemirror/schema/nodes.d.ts +3 -0
  122. package/dist/prosemirror/tableCellRevisionVisibility.d.ts +6 -0
  123. package/dist/prosemirror/tableCellRevisionVisibility.js +14 -0
  124. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +1 -1
  125. package/dist/prosemirror/trackedRunInlineAtoms.js +1 -1
  126. package/dist/redline.js +15 -2
  127. package/dist/server.d.ts +3 -2
  128. package/dist/server.js +2 -2
  129. package/dist/version-comparison.d.ts +2 -0
  130. package/dist/version-comparison.js +30 -29
  131. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  import { folioAIBlockIdStability } from "./ai-edits/block-identity.js";
2
2
  import { FolioDocxReviewer } from "./ai-edits/headless.js";
3
3
  import { alignFolioContentBlocks, alignFolioContentStructure, createFolioContentAlignmentWorkSession, exceedsFolioContentLcsBudget } from "./compare/content-alignment.js";
4
- import { compareAlignedFolioContent, createContentComparisonWorkSession } from "./compare/content.js";
4
+ import { FolioContentInlinePresentationProjectionError, compareAlignedFolioContent, createContentComparisonWorkSession } from "./compare/content.js";
5
5
  import { pairFolioDocumentStories } from "./document-stories.js";
6
6
  import { FOLIO_DOCUMENT_METADATA_PROPERTIES, FOLIO_DOCUMENT_PRIVACY_TRANSFORMS, PRIVATE_METADATA_PROPERTIES_BY_TRANSFORM, isFolioDocumentPrivacyTransform } from "./docx/metadataPrivacy.js";
7
7
  import { TaggedError, panic } from "better-result";
@@ -21,39 +21,35 @@ import { TaggedError, panic } from "better-result";
21
21
  * ## Alignment
22
22
  *
23
23
  * Compatible body and table/container segments are aligned by the neutral
24
- * comparison core. Within each compatible segment, blocks are paired in
25
- * three passes, each only considering blocks the previous pass left unpaired:
24
+ * comparison core. Quadratic structural candidate alignment shares bounded
25
+ * cell and token budgets across the comparison. Within each compatible
26
+ * segment, blocks are paired in four confidence-ordered passes:
26
27
  *
27
28
  * 1. **Stable-id pairing.** Blocks whose ids are equal and whose snapshot
28
- * provenance marks those ids stable are paired directly. A source
29
- * `w14:paraId` is stable identity independent of text, so an equal-id pair
30
- * with different text is a genuine edit (`modified`). Deterministically
31
- * synthesized ids and `seq-NNNN` fallbacks are positional instead: the
32
- * adapter preserves that provenance so an ordinal shift falls through to
33
- * exact-text alignment rather than becoming a false identity match.
34
- * 2. **Exact-text pairing.** An order-preserving LCS over remaining blocks,
35
- * matched by exact text equality. This is what recovers same-text blocks
36
- * that pass 1 missed because a fallback id shifted with the ordinal. Its
37
- * O(m·n) table is skipped ({@link exceedsLcsBudget}) once the unpaired
38
- * counts on both sides would exceed a fixed cell budget, so a document
39
- * with few/no stable ids can't force a quadratic-sized allocation; those
40
- * blocks fall through to pass 3 instead.
41
- * 3. **Positional fallback.** Whatever a monotonicity filter leaves
42
- * unpaired is split into the gaps between anchored pairs (pass 1 + 2,
43
- * time-ordered); within each gap the shorter side is zipped positionally
44
- * against the longer one (`modified`), and any excess on either side is
45
- * reported as `added` / `deleted`.
46
- *
47
- * The combined anchor set from passes 1 and 2 is re-filtered to the longest
48
- * increasing subsequence by revised-side index before pass 3 runs, so a
49
- * pathological crossing match (content reordered across versions) can't
50
- * produce an out-of-order gap — the alignment always walks both documents
51
- * forward.
29
+ * provenance marks those ids stable become the highest-confidence
30
+ * monotone anchor candidates. A source `w14:paraId` is stable identity
31
+ * independent of text, so an equal-id pair with different text is a genuine
32
+ * edit (`modified`). Deterministically synthesized ids and `seq-NNNN`
33
+ * fallbacks are positional instead: the adapter preserves that provenance
34
+ * so an ordinal shift falls through to exact-text alignment rather than
35
+ * becoming a false identity match.
36
+ * 2. **Exact-text pairing.** Within each stable-id gap, nonblank text that is
37
+ * unique on both sides becomes an exact anchor. An O(n log n) increasing-
38
+ * subsequence selection keeps those anchors ordered; repeated or blank
39
+ * text is deliberately not treated as identity evidence.
40
+ * 3. **Residual-id continuity.** Within the stable-plus-exact gaps, a unique
41
+ * id whose provenance changed between positional and stable may pair. This
42
+ * preserves identity across serialize-and-reopen boundaries without
43
+ * letting weaker evidence cross an established correspondence.
44
+ * 4. **Positional fallback.** Whatever remains is split into the gaps between
45
+ * the confidence-ordered anchors; within each gap the shorter side is
46
+ * zipped positionally against the longer one (`modified`), and any excess
47
+ * on either side is reported as `added` / `deleted`.
52
48
  *
53
49
  * ## Move detection
54
50
  *
55
51
  * Relocated content would otherwise report as an unrelated `deleted` +
56
- * `added` pair (both order-preserving passes drop crossing matches by
52
+ * `added` pair (the monotone alignment passes drop crossing matches by
57
53
  * design). The neutral comparison core re-classifies eligible exact and
58
54
  * closely edited pairs as `movedFrom` / `movedTo` entries sharing a
59
55
  * `moveGroupId`. Candidate counts and similarity work share bounded budgets
@@ -90,8 +86,10 @@ const INLINE_FORMAT_PROPERTIES = {
90
86
  color: true
91
87
  };
92
88
  const PARAGRAPH_FORMAT_PROPERTIES = {
89
+ indentation: true,
93
90
  styleId: true,
94
91
  listLevel: true,
92
+ listReference: true,
95
93
  alignment: true,
96
94
  spacing: true
97
95
  };
@@ -184,7 +182,10 @@ const compareStoryBlocks = ({ baseStory, revisedStory, baseBlocks, revisedBlocks
184
182
  idStability: folioAIBlockIdStability,
185
183
  maxChanges: Number.MAX_SAFE_INTEGER
186
184
  });
187
- if (compared.isErr()) return panic("A version comparison exceeded an unreachable internal result limit", { cause: compared.error });
185
+ if (compared.isErr()) {
186
+ if (compared.error instanceof FolioContentInlinePresentationProjectionError) return panic("Version comparison requires an alignable inline formatting projection", { cause: compared.error });
187
+ return panic("A version comparison exceeded an unreachable internal result limit", { cause: compared.error });
188
+ }
188
189
  const changes = [];
189
190
  const counts = createSummaryCounts();
190
191
  const baseBlockById = /* @__PURE__ */ new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/folio-core",
3
- "version": "0.37.4",
3
+ "version": "0.38.0",
4
4
  "description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
5
5
  "keywords": [
6
6
  "document-model",
@@ -121,7 +121,7 @@
121
121
  "perf": "bun scripts/profile-editor.ts"
122
122
  },
123
123
  "dependencies": {
124
- "@stll/docx-core": "^0.19.4",
124
+ "@stll/docx-core": "^0.20.0",
125
125
  "@stll/docx-utils": "^0.1.0",
126
126
  "@stll/template-conditions": ">=0.4.0 <1.0.0",
127
127
  "better-result": "3.0.1",