@stll/folio-core 0.35.1 → 0.36.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 (80) hide show
  1. package/dist/ai-edits/apply.js +370 -118
  2. package/dist/ai-edits/headless.js +16 -10
  3. package/dist/ai-edits/index.d.ts +2 -2
  4. package/dist/ai-edits/index.js +2 -2
  5. package/dist/ai-edits/snapshot.js +6 -1
  6. package/dist/ai-edits/types.d.ts +19 -6
  7. package/dist/ai-edits/word-diff.d.ts +18 -3
  8. package/dist/ai-edits/word-diff.js +556 -67
  9. package/dist/compare/compare.js +7 -16
  10. package/dist/compare/plan.js +8 -5
  11. package/dist/compare/verification.d.ts +8 -9
  12. package/dist/compare/verification.js +51 -46
  13. package/dist/compat/eigenpal.d.ts +2 -2
  14. package/dist/compat/eigenpal.js +2 -2
  15. package/dist/controller/headerFooterEditorManager.js +5 -5
  16. package/dist/controller/hiddenEditorApi.js +1 -1
  17. package/dist/controller/noteEditorManager.js +2 -2
  18. package/dist/document-operations.d.ts +5 -3
  19. package/dist/document-operations.js +32 -5
  20. package/dist/docx/commentParser.js +2 -4
  21. package/dist/docx/commentRangeIntegrity.js +2 -4
  22. package/dist/docx/documentClone.d.ts +2 -0
  23. package/dist/docx/documentClone.js +2 -0
  24. package/dist/docx/headerFooterParser.js +2 -4
  25. package/dist/docx/normalizeBaseDirection.js +5 -7
  26. package/dist/docx/paragraphParser.js +27 -29
  27. package/dist/docx/paragraphPropertySource.d.ts +49 -0
  28. package/dist/docx/paragraphPropertySource.js +113 -0
  29. package/dist/docx/runConsolidator.js +2 -4
  30. package/dist/docx/runParser.js +2 -15
  31. package/dist/docx/sectionParser.js +1 -15
  32. package/dist/docx/serializer/paragraphSerializer.js +287 -30
  33. package/dist/docx/serializer/runSerializer.js +2 -10
  34. package/dist/docx/serializer/sectionPropertiesSerializer.js +2 -10
  35. package/dist/docx/serializer/tableSerializer.js +4 -23
  36. package/dist/docx/serializer/trackedChangeAttributes.d.ts +9 -0
  37. package/dist/docx/serializer/trackedChangeAttributes.js +21 -0
  38. package/dist/docx/server/createBilingualDocument.js +8 -10
  39. package/dist/docx/server/evaluateDocxXmlPatchProposal.js +22 -13
  40. package/dist/docx/server/validateDocxConformance.js +17 -13
  41. package/dist/docx/tableParser.js +1 -37
  42. package/dist/docx/trackedChangeInfo.d.ts +11 -0
  43. package/dist/docx/trackedChangeInfo.js +38 -0
  44. package/dist/docx/verbatimCapture.d.ts +20 -9
  45. package/dist/docx/verbatimCapture.js +208 -8
  46. package/dist/docx/xmlParser.d.ts +3 -1
  47. package/dist/docx/xmlParser.js +6 -1
  48. package/dist/docx/xmlSafety.d.ts +1 -1
  49. package/dist/docx/xmlSafety.js +157 -0
  50. package/dist/index.d.ts +2 -2
  51. package/dist/index.js +2 -2
  52. package/dist/layout-bridge/convert/headerFooterLayout.js +4 -4
  53. package/dist/layout-bridge/convert/toFlowBlocks.js +12 -7
  54. package/dist/markdown/renderBlock.js +7 -10
  55. package/dist/prosemirror/attrs/index.js +15 -0
  56. package/dist/prosemirror/commands/comments.js +365 -32
  57. package/dist/prosemirror/commands/pageBreak.js +1 -1
  58. package/dist/prosemirror/commands/propertyChangeScope.d.ts +26 -4
  59. package/dist/prosemirror/commands/propertyChangeScope.js +65 -3
  60. package/dist/prosemirror/conversion/fromProseDoc.d.ts +2 -4
  61. package/dist/prosemirror/conversion/fromProseDoc.js +130 -18
  62. package/dist/prosemirror/conversion/toProseDoc.js +27 -12
  63. package/dist/prosemirror/extensions/core/ParagraphExtension.js +48 -4
  64. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -1
  65. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +20 -7
  66. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -0
  67. package/dist/prosemirror/paragraphAlignment.d.ts +12 -0
  68. package/dist/prosemirror/paragraphAlignment.js +13 -0
  69. package/dist/prosemirror/plugins/suggestionMode.js +1 -1
  70. package/dist/prosemirror/schema/marks.d.ts +2 -0
  71. package/dist/prosemirror/schema/nodes.d.ts +12 -1
  72. package/dist/prosemirror/styles/resolvedStyleAttrs.js +1 -0
  73. package/dist/redline.js +4 -1
  74. package/dist/server.d.ts +2 -2
  75. package/dist/server.js +2 -2
  76. package/dist/utils/mergeDocumentContent.js +3 -3
  77. package/dist/utils/replaceText.js +2 -1
  78. package/dist/version-comparison.js +6 -4
  79. package/dist/watermark/index.js +2 -4
  80. package/package.json +6 -1
@@ -1,6 +1,7 @@
1
1
  import { applyFolioDocumentOperations } from "../document-operations.js";
2
2
  import { getEndnoteText, getFootnoteText, isSeparatorEndnote, isSeparatorFootnote } from "../docx/footnoteParser.js";
3
3
  import { getHeaderFooterText } from "../docx/headerFooterParser.js";
4
+ import { recreateProseNodeWithParagraphPropertySource, transferProseParagraphPropertySource } from "../docx/paragraphPropertySource.js";
4
5
  import { parseDocx } from "../docx/parser.js";
5
6
  import { createReply } from "../docx/replyToComment.js";
6
7
  import { repackDocx } from "../docx/rezip.js";
@@ -10,6 +11,7 @@ import { proseDocToBlocks, updateDocumentContent } from "../prosemirror/conversi
10
11
  import { footnoteToProseDoc, headerFooterToProseDoc, toProseDoc } from "../prosemirror/conversion/toProseDoc.js";
11
12
  import { ensureBaseDirectionInState } from "../prosemirror/extensions/features/AutoBidiDetectionExtension.js";
12
13
  import { getChangedParagraphIds, hasStructuralChanges, hasUntrackedChanges } from "../prosemirror/extensions/features/ParagraphChangeTrackerExtension.js";
14
+ import { createDocumentStylesPlugin } from "../prosemirror/plugins/documentStyles.js";
13
15
  import { schema, singletonManager } from "../prosemirror/schema/index.js";
14
16
  import { deterministicHexId } from "../utils/hexId.js";
15
17
  import { buildAnnotatedBlockText } from "./clean-text.js";
@@ -17,8 +19,8 @@ import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
17
19
  import { createFolioAIEditSnapshot, folioStoryTables, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./snapshot.js";
18
20
  import { matchTableGeometry } from "./table-geometry.js";
19
21
  import { TaggedError } from "better-result";
20
- import { Fragment } from "prosemirror-model";
21
22
  import { EditorState } from "prosemirror-state";
23
+ import { Fragment } from "prosemirror-model";
22
24
  //#region src/ai-edits/headless.ts
23
25
  /**
24
26
  * Headless `.docx` review path: buffer -> apply AI edits -> buffer, with
@@ -109,14 +111,16 @@ const ensureDeterministicParaIdsInDoc = (doc) => {
109
111
  let paraId = deterministicHexId(`${child.textContent}:${ordinal}`);
110
112
  for (let salt = 1; seen.has(paraId); salt++) paraId = deterministicHexId(`${child.textContent}:${ordinal}:${salt}`);
111
113
  seen.add(paraId);
112
- next = child.type.create({
114
+ next = recreateProseNodeWithParagraphPropertySource(child, { attrs: {
113
115
  ...child.attrs,
114
116
  paraId
115
- }, child.content, child.marks);
117
+ } });
116
118
  }
119
+ const paraId = next.attrs["paraId"];
120
+ if (typeof paraId === "string") transferProseParagraphPropertySource(next, child, paraId);
117
121
  } else if (child.childCount > 0) {
118
122
  const content = rewrite(child);
119
- if (content !== child.content) next = child.copy(content);
123
+ if (content !== child.content) next = recreateProseNodeWithParagraphPropertySource(child, { content });
120
124
  }
121
125
  if (next !== child) changed = true;
122
126
  children.push(next);
@@ -124,7 +128,7 @@ const ensureDeterministicParaIdsInDoc = (doc) => {
124
128
  return changed ? Fragment.fromArray(children) : parent.content;
125
129
  };
126
130
  const content = rewrite(doc);
127
- return content === doc.content ? doc : doc.copy(content);
131
+ return content === doc.content ? doc : recreateProseNodeWithParagraphPropertySource(doc, { content });
128
132
  };
129
133
  const FOLIO_REVIEWED_VIEWS = Object.freeze([
130
134
  "original",
@@ -248,7 +252,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
248
252
  preloadFonts: false,
249
253
  password: options.password
250
254
  });
251
- const plugins = singletonManager.getPlugins();
255
+ const plugins = [...singletonManager.getPlugins(), createDocumentStylesPlugin(baseDocument.package.styles)];
252
256
  const state = ensureBaseDirectionInState(EditorState.create({
253
257
  schema,
254
258
  doc: ensureDeterministicParaIdsInDoc(toProseDoc(baseDocument)),
@@ -413,6 +417,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
413
417
  },
414
418
  ...options.snapshot !== void 0 && { snapshot: options.snapshot },
415
419
  ...options.revisionStamp !== void 0 && { revisionStamp: options.revisionStamp },
420
+ ...options.wordDiff !== void 0 && { wordDiff: options.wordDiff },
416
421
  createUndoEntry: false
417
422
  });
418
423
  return {
@@ -432,6 +437,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
432
437
  batch,
433
438
  ...options.snapshot !== void 0 && { snapshot: options.snapshot },
434
439
  ...options.revisionStamp !== void 0 && { revisionStamp: options.revisionStamp },
440
+ ...options.wordDiff !== void 0 && { wordDiff: options.wordDiff },
435
441
  createUndoEntry: true
436
442
  });
437
443
  }
@@ -872,7 +878,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
872
878
  const state = ensureBaseDirectionInState(EditorState.create({
873
879
  schema,
874
880
  doc: ensureDeterministicParaIdsInDoc(storyDoc),
875
- plugins: singletonManager.getPlugins()
881
+ plugins: [...singletonManager.getPlugins(), createDocumentStylesPlugin(this.baseDocument.package.styles)]
876
882
  }));
877
883
  this.secondaryStoryStates.set(key, {
878
884
  handle: story,
@@ -930,7 +936,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
930
936
  if (!source) continue;
931
937
  const edited = {
932
938
  ...source,
933
- content: proseDocToBlocks(entry.state.doc)
939
+ content: proseDocToBlocks(entry.state.doc, source.content)
934
940
  };
935
941
  if (entry.handle.type === "header") {
936
942
  headers ??= new Map(document.package.headers);
@@ -947,7 +953,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
947
953
  if (!source) continue;
948
954
  const edited = {
949
955
  ...source,
950
- content: proseDocToBlocks(entry.state.doc)
956
+ content: proseDocToBlocks(entry.state.doc, source.content)
951
957
  };
952
958
  footnotes ??= [...document.package.footnotes ?? []];
953
959
  const index = footnotes.findIndex((note) => note.id === noteId);
@@ -959,7 +965,7 @@ var FolioDocxReviewer = class FolioDocxReviewer {
959
965
  if (!source) continue;
960
966
  const edited = {
961
967
  ...source,
962
- content: proseDocToBlocks(entry.state.doc)
968
+ content: proseDocToBlocks(entry.state.doc, source.content)
963
969
  };
964
970
  endnotes ??= [...document.package.endnotes ?? []];
965
971
  const index = endnotes.findIndex((note) => note.id === noteId);
@@ -3,10 +3,10 @@ import { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, Wo
3
3
  import { FolioAIEditApplyOutcome, FolioAIEditView, FolioRevisionStamp, FolioWordDiffOptions, applyFolioAIEditOperations } from "./apply.js";
4
4
  import { DocPositionRange, clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "./blockRange.js";
5
5
  import { buildAnnotatedBlockText } from "./clean-text.js";
6
- import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
6
+ import { ApplyFolioDocumentOperationsOptions, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FolioDocumentOperation, FolioDocumentOperationAffectedTarget, FolioDocumentOperationBatch, FolioDocumentOperationCapabilities, FolioDocumentOperationIssue, FolioDocumentOperationMode, FolioDocumentOperationPrecondition, FolioDocumentOperationReceipt, FolioDocumentOperationRecovery, FolioDocumentOperationResult, FolioDocumentOperationResultBase, FolioDocumentOperationStatus, FolioDocumentOperationStory, FolioDocumentOperationType, FolioDocumentOperationUndoFailureReason, FolioDocumentOperationUndoHandle, FolioDocumentOperationUndoResult, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
7
7
  import { FolioCommentAnchor, FolioReviewChange, FolioReviewChangeKind, getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
8
8
  import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./snapshot.js";
9
9
  import { FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioApplyDocumentOperationsToStoryOptions, FolioDocumentStory, FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, FolioEditableDocumentStoryHandle, FolioReadReviewedStoryOptions, FolioResolveReviewedStoryOptions, FolioResolvedReviewedView, FolioReviewedStory, FolioReviewedView, UnsupportedFolioReviewedViewError, isFolioResolvedReviewedView, isFolioReviewedView } from "./headless.js";
10
10
  import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
11
11
  import { getFolioParaIdFromBlockId } from "../types/block-id.js";
12
- export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAIInlineFormatting, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, type FolioRevisionStamp, type FolioWordDiffOptions, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
12
+ export { type ApplyFolioDocumentOperationsOptions, type DocPositionRange, FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, type FolioAIBlock, type FolioAIBlockAnchor, type FolioAIBlockKind, type FolioAIBlockPreviewRun, type FolioAIBlockTableLocation, type FolioAIComment, type FolioAIEditAppliedOperation, type FolioAIEditApplyMode, type FolioAIEditApplyOutcome, type FolioAIEditApplyResult, type FolioAIEditNormalization, type FolioAIEditNormalizationCode, type FolioAIEditOperation, type FolioAIEditPrecondition, type FolioAIEditReviewMeta, type FolioAIEditSeverity, type FolioAIEditSkipReason, type FolioAIEditSkippedOperation, type FolioAIEditSnapshot, type FolioAIEditView, type FolioAIInlineFormatting, type FolioAISignatureParty, type FolioAITextRangeHandle, type FolioApplyDocumentOperationsToStoryOptions, type FolioCommentAnchor, type FolioDocumentNavigationTarget, type FolioDocumentOperation, type FolioDocumentOperationAffectedTarget, type FolioDocumentOperationBatch, type FolioDocumentOperationCapabilities, type FolioDocumentOperationIssue, type FolioDocumentOperationMode, type FolioDocumentOperationPrecondition, type FolioDocumentOperationReceipt, type FolioDocumentOperationRecovery, type FolioDocumentOperationResult, type FolioDocumentOperationResultBase, type FolioDocumentOperationStatus, type FolioDocumentOperationStory, type FolioDocumentOperationType, type FolioDocumentOperationUndoFailureReason, type FolioDocumentOperationUndoHandle, type FolioDocumentOperationUndoResult, type FolioDocumentOutline, type FolioDocumentOutlineEntry, type FolioDocumentSection, type FolioDocumentSectionHandle, type FolioDocumentSectionReadResult, type FolioDocumentStory, type FolioDocumentStoryHandle, FolioDocumentStoryNotFoundError, type FolioEditableDocumentStoryHandle, type FolioReadReviewedStoryOptions, type FolioResolveReviewedStoryOptions, type FolioResolvedReviewedView, type FolioReviewChange, type FolioReviewChangeKind, type FolioReviewedStory, type FolioReviewedView, type FolioRevisionStamp, type FolioWordDiffOptions, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, type WordDiffGranularity, type WordDiffNormalization, type WordDiffOptions, type WordDiffSegment, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
@@ -1,4 +1,4 @@
1
- import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
1
+ import { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, isFolioDocumentOperationModeSupported, isSupportedFolioDocumentOperationVersion, parseFolioDocumentOperationBatch } from "../document-operations.js";
2
2
  import { getFolioParaIdFromBlockId } from "../types/block-id.js";
3
3
  import { applyFolioAIEditOperations } from "./apply.js";
4
4
  import { clampRangeToDocSize, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange } from "./blockRange.js";
@@ -8,4 +8,4 @@ import { getCommentAnchorsFromDoc, getTrackedChangesFromDoc } from "./read.js";
8
8
  import { getFolioDocumentOutline, readFolioDocumentSection } from "./scoped-reading.js";
9
9
  import { createFolioAIEditSnapshot, createFolioAITextRangeHandle, hashFolioAIBlockText, isFolioAIContentBlock, normalizeFolioAIBlockText } from "./snapshot.js";
10
10
  import { WORD_DIFF_GRANULARITIES, diffWordSegments } from "./word-diff.js";
11
- export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
11
+ export { FOLIO_DOCUMENT_OPERATION_BATCH_MODES, FOLIO_DOCUMENT_OPERATION_CONTRACT_VERSION, FOLIO_DOCUMENT_OPERATION_MODES, FOLIO_DOCUMENT_OPERATION_MODES_BY_TYPE, FOLIO_DOCUMENT_OPERATION_PRECONDITIONS, FOLIO_DOCUMENT_OPERATION_STORIES, FOLIO_DOCUMENT_OPERATION_TYPES, FOLIO_PARAGRAPH_ALIGNMENT_VALUES, FOLIO_RESOLVED_REVIEWED_VIEWS, FOLIO_REVIEWED_VIEWS, FolioDocumentStoryNotFoundError, InvalidFolioDocumentOperationBatchError, UnsupportedFolioDocumentOperationVersionError, UnsupportedFolioReviewedViewError, WORD_DIFF_GRANULARITIES, applyFolioAIEditOperations, applyFolioDocumentOperations, assertSupportedFolioDocumentOperationVersion, buildAnnotatedBlockText, clampRangeToDocSize, createFolioAIEditSnapshot, createFolioAITextRangeHandle, diffWordSegments, getCommentAnchorsFromDoc, getFolioDocumentOperationCapabilities, getFolioDocumentOperationIssues, getFolioDocumentOperationReceipts, getFolioDocumentOutline, getFolioParaIdFromBlockId, getTrackedChangesFromDoc, hashFolioAIBlockText, isFolioAIContentBlock, isFolioDocumentOperationModeSupported, isFolioResolvedReviewedView, isFolioReviewedView, isSupportedFolioDocumentOperationVersion, normalizeFolioAIBlockText, parseFolioDocumentOperationBatch, readFolioDocumentSection, resolveFolioAIBlockRange, resolveFolioAITextRange, resolvePassageRange };
@@ -1,4 +1,5 @@
1
- import { expectRunFormattingOverrideMarkAttrs } from "../prosemirror/attrs/index.js";
1
+ import { expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs } from "../prosemirror/attrs/index.js";
2
+ import { directParagraphAlignment } from "../prosemirror/paragraphAlignment.js";
2
3
  import { deriveBlankBlockId, deriveBlockId } from "../types/block-id.js";
3
4
  import { buildCleanBlockText } from "./clean-text.js";
4
5
  import { panic } from "better-result";
@@ -178,6 +179,7 @@ const createFolioAIEditSnapshot = (doc) => {
178
179
  const listLevel = getListLevel(node);
179
180
  const numberingReferenceKey = getNumberingReferenceKey(node);
180
181
  if (numberingReferenceKey) numberingReferenceKeys.add(numberingReferenceKey);
182
+ const directAlignment = getDirectAlignment(node);
181
183
  const previewRuns = getPreviewRuns(node);
182
184
  const table = getTableLocation({
183
185
  path,
@@ -193,6 +195,7 @@ const createFolioAIEditSnapshot = (doc) => {
193
195
  ...displayLabel !== void 0 && { displayLabel },
194
196
  ...styleId !== void 0 && { styleId },
195
197
  ...listLevel !== void 0 && { listLevel },
198
+ ...directAlignment !== void 0 && { directAlignment },
196
199
  ...previewRuns !== void 0 && { previewRuns },
197
200
  ...table !== void 0 && { table }
198
201
  },
@@ -263,6 +266,8 @@ const getStyleId = (node) => {
263
266
  const styleId = node.attrs["styleId"];
264
267
  return typeof styleId === "string" && styleId.length > 0 ? styleId : void 0;
265
268
  };
269
+ /** Read only authored `w:jc`, never the effective alignment resolved from a style. */
270
+ const getDirectAlignment = (node) => directParagraphAlignment(expectParagraphAttrs(node));
266
271
  const DELETION_MARK = "deletion";
267
272
  const getPreviewRuns = (node) => {
268
273
  const runs = [];
@@ -1,3 +1,4 @@
1
+ import { document_d_exports } from "../types/document.js";
1
2
  //#region src/ai-edits/types.d.ts
2
3
  type FolioAIBlockKind = "heading" | "listItem" | "paragraph";
3
4
  type FolioAIInlineFormatting = Partial<Record<"bold" | "italic" | "underline" | "strike", boolean>> & {
@@ -51,6 +52,8 @@ type FolioAIBlock = {
51
52
  headingLevel?: number;
52
53
  displayLabel?: string;
53
54
  styleId?: string;
55
+ /** Direct `w:pPr/w:jc`; absent when alignment comes only from a style. */
56
+ directAlignment?: document_d_exports.ParagraphAlignment;
54
57
  /**
55
58
  * `w:numPr/w:ilvl`: the block's list indent level. Present only on a block
56
59
  * that carries numbering, and the only pPr property a redline can move
@@ -63,8 +66,8 @@ type FolioAIBlock = {
63
66
  };
64
67
  /**
65
68
  * The paragraph properties an operation may set. A subset of `w:pPrChange`'s
66
- * scope: the two a comparison can see in a block projection, and the two an
67
- * agent has a reason to change.
69
+ * scope: properties a comparison can see in a block projection and an agent
70
+ * has a reason to change.
68
71
  */
69
72
  type FolioAIBlockParagraphProperties = {
70
73
  /** `w:pStyle`. `null` clears the style back to the default. */
@@ -74,6 +77,8 @@ type FolioAIBlockParagraphProperties = {
74
77
  * paragraph stops being a list item rather than moving to another level.
75
78
  */
76
79
  listLevel?: number | null;
80
+ /** Direct `w:jc`. `null` clears the override and restores style inheritance. */
81
+ alignment?: document_d_exports.ParagraphAlignment | null;
77
82
  };
78
83
  /**
79
84
  * Every paragraph of one story, blank ones included.
@@ -222,7 +227,7 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
222
227
  * The paragraph text to insert. A line break splits `text` into
223
228
  * consecutive paragraphs at the same anchor instead of becoming
224
229
  * literal newlines inside one paragraph: only the first paragraph
225
- * gets `styleId` / `inheritFormatting`, later ones use body
230
+ * gets `styleId` / `alignment` / `inheritFormatting`, later ones use body
226
231
  * formatting. Blank lines are dropped. Reported as a
227
232
  * `splitMultilineText` normalization when it happens.
228
233
  *
@@ -262,6 +267,11 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
262
267
  * inheritance alone cannot say.
263
268
  */
264
269
  listLevel?: number | null;
270
+ /**
271
+ * Direct `w:jc` for the inserted block. `null` clears alignment copied
272
+ * from the anchor and lets the inserted paragraph's style decide.
273
+ */
274
+ alignment?: document_d_exports.ParagraphAlignment | null;
265
275
  comment?: FolioAIComment;
266
276
  } | {
267
277
  id: string;
@@ -269,7 +279,8 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
269
279
  blockId: string;
270
280
  text: string;
271
281
  preserveFormatting?: boolean;
272
- styleId?: string;
282
+ /** Paragraph style to apply; `null` clears the direct style. */
283
+ styleId?: string | null;
273
284
  comment?: FolioAIComment;
274
285
  } |
275
286
  /**
@@ -464,8 +475,8 @@ type FolioAIEditOperation = FolioAIEditReviewMeta & {
464
475
  * provenance: rendered with the tracked-change grammar but stripped from
465
476
  * serialized DOCX until a human accepts them. Behaves like `"tracked-changes"`
466
477
  * and covers the inline text/format operations (replaceInBlock, replaceRange,
467
- * formatRange) plus the block and table row/column structural operations
468
- * (insertAfterBlock, insertBeforeBlock, replaceBlock, deleteBlock,
478
+ * formatRange), paragraph properties, plus the block and table row/column structural
479
+ * operations (insertAfterBlock, insertBeforeBlock, replaceBlock, deleteBlock,
469
480
  * insertSignatureTable, insertTableRow, deleteTableRow, insertTableColumn,
470
481
  * deleteTableColumn). Only comment operations and cell merge/split report
471
482
  * `unsupportedMode`.
@@ -506,6 +517,8 @@ type FolioAIEditAppliedOperation = {
506
517
  * fromProseDoc serialises a single id carrying both as a Word
507
518
  * "moveTo/moveFrom" pair, not an ins/del — so the two sides must
508
519
  * be distinct ids in the doc but conceptually one operation here.
520
+ * The list also includes a paragraph-property revision synthesized
521
+ * when an inserted final paragraph mark rotates to its carrier.
509
522
  * Use this list when you need to accept or reject every mark
510
523
  * belonging to this op.
511
524
  */
@@ -23,8 +23,11 @@
23
23
  * 3. When what survives is still too fragmented for its length, the whole
24
24
  * paragraph is one replacement ({@link isTooFragmented}).
25
25
  *
26
- * O(n*m) on token counts; past {@link MAX_WORD_DIFF_CELLS} the DP is skipped
27
- * for a single whole-string `del` + `ins` pair.
26
+ * Common affixes and unique-token anchors split the input into independent
27
+ * gaps before any quadratic work. The residual gaps share one
28
+ * {@link MAX_WORD_DIFF_CELLS} allowance per comparison or apply scope; once it
29
+ * is spent, a gap is a single `del` + `ins` pair. A standalone call owns one
30
+ * fresh scope.
28
31
  */
29
32
  type WordDiffSegment = {
30
33
  type: "equal" | "del" | "ins";
@@ -58,6 +61,18 @@ type WordDiffOptions = {
58
61
  /** Default: nothing normalized, so both strings reconstruct exactly. */
59
62
  normalization?: WordDiffNormalization;
60
63
  };
64
+ /**
65
+ * One internal comparison/apply scope. Every diff shares the same quadratic
66
+ * allowance; public standalone calls below still receive a fresh allowance.
67
+ * Not re-exported from a package entry point.
68
+ */
69
+ declare const createWordDiffSession: (options?: WordDiffOptions) => {
70
+ diff: (before: string, after: string) => WordDiffSegment[];
71
+ };
72
+ /** Attach one internal work scope without widening a caller-facing option type. */
73
+ declare const createScopedWordDiffOptions: <Options extends WordDiffOptions>(options: Options) => Options;
74
+ /** Reuse an internal scope when present; ordinary public callers get a fresh one. */
75
+ declare const wordDiffSessionFromOptions: (options: WordDiffOptions | undefined) => ReturnType<typeof createWordDiffSession>;
61
76
  declare const diffWordSegments: (before: string, after: string, options?: WordDiffOptions) => WordDiffSegment[];
62
77
  //#endregion
63
- export { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, diffWordSegments };
78
+ export { WORD_DIFF_GRANULARITIES, WordDiffGranularity, WordDiffNormalization, WordDiffOptions, WordDiffSegment, createScopedWordDiffOptions, createWordDiffSession, diffWordSegments, wordDiffSessionFromOptions };