/** * Diff between the current document and a history snapshot — pure, no * React, no ProseMirror. Powers the "hover a history item to see what * changed" preview: `HistoryEntryRow` calls this on hover, then * `DocxEditor.previewHistoryDiff()` (see `../../editor.ts`) renders the * result as ProseMirror decorations without touching document content. * * Two levels, both built on the same LCS alignment (`lcsAlign`): * - Block-level (`diffHistoryBlocks`): treats each top-level node of * `doc.content` as one atomic "line" — cheap enough for the block * counts a document actually has (at most a few hundred). * - Word-level (`diffWords`): for a block matched as `modified`, diffs its * text word-by-word so the overlay can highlight only the words that * actually changed instead of tinting the whole paragraph — see * `BlockDiffEntry.wordDiff`. */ type BlockDiffKind = 'added' | 'removed' | 'modified'; type WordDiffKind = 'same' | 'added' | 'removed'; interface WordDiffEntry { kind: WordDiffKind; /** The token itself — a run of non-whitespace, or a run of whitespace (tokens preserve every character, so join()-ing all `text` fields losslessly reconstructs the original string). */ text: string; } interface BlockDiffEntry { kind: BlockDiffKind; /** Index into the CURRENT document's top-level blocks (added/modified only). */ currentIndex?: number; /** Index into the SNAPSHOT document's top-level blocks (removed/modified only). */ snapshotIndex?: number; /** * `removed` only — index into the CURRENT document's top-level blocks that * this removed content should be anchored *before* (`current.length` means * "at the end of the document"). Unlike `snapshotIndex`, this stays valid * as a position in the current doc even once it and the snapshot have a * different number of blocks. */ anchorIndex?: number; /** Short text preview, mainly for the `removed` widget pill (no node in the current doc to anchor to). */ preview?: string; /** `removed` only — full (untruncated) text of the removed block, for rendering the whole removed line. */ removedText?: string; /** `modified` only — word-level diff between the snapshot's and current's full text, in order. */ wordDiff?: WordDiffEntry[]; } interface BlockDiffResult { entries: BlockDiffEntry[]; } /** * Diff `current.content` against `snapshot.content` (both full TipTap JSON * documents). Returns entries in document order (interleaving added/removed/ * modified as they occur, matched blocks omitted). */ declare function diffHistoryBlocks(currentDoc: any, snapshotDoc: any): BlockDiffResult; /** * Word-level diff between `currentText` and `snapshotText`. Whitespace runs * are tokens too (not diffed away) so the overlay can precisely map every * token back to a text offset — see `WordDiffEntry`. */ declare function diffWords(currentText: string, snapshotText: string): WordDiffEntry[]; export { type BlockDiffEntry, type BlockDiffKind, type BlockDiffResult, type WordDiffEntry, type WordDiffKind, diffHistoryBlocks, diffWords };