# @push.rocks/smartdiff A powerful, cross-platform text diffing library for TypeScript/JavaScript with built-in visualization for CLI and browser. 🔍 ## Issue Reporting and Security For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly. ## Install ```sh npm install @push.rocks/smartdiff # or pnpm add @push.rocks/smartdiff ``` ## Features ✨ - 🔤 **Character-level diffs** — See exactly which characters changed - 📝 **Word-level diffs** — Perfect for document comparisons - 📄 **Line-level diffs** — Ideal for code and file comparisons - 🖥️ **CLI output** — ANSI-colored terminal output - 🌐 **HTML output** — Styled spans for browser rendering - 📦 **Compact storage format** — Efficient diff serialization for storage/sync - 🔧 **Git-style unified diffs** — Standard patch format - 💅 **Built-in CSS** — Ready-to-use styles for HTML output ## Usage ### Quick Start ```typescript import { createDiff, applyPatch, formatLineDiffForConsole, formatWordDiffAsHtml, } from '@push.rocks/smartdiff'; // Create and apply compact diffs const patch = createDiff('hello world', 'hello beautiful world'); const result = applyPatch('hello world', patch); // result: 'hello beautiful world' // Visualize changes in terminal console.log(formatLineDiffForConsole(oldCode, newCode)); // Generate HTML for browser display const html = formatWordDiffAsHtml(oldText, newText); ``` --- ## 📦 Compact Diff Storage For storing diffs efficiently (version control, sync, undo/redo): ### `createDiff(original, revision)` Creates a compact JSON-encoded diff optimized for storage. ```typescript import { createDiff } from '@push.rocks/smartdiff'; const diff = createDiff('Hello World', 'Hello smart World'); console.log(diff); // Output: [[0,6],[1,"smart "],[0,5]] ``` **Format:** - `[0, n]` — Keep `n` characters from original - `[1, "text"]` — Insert `"text"` - `[-1, n]` — Delete `n` characters ### `applyPatch(original, diffString)` Reconstructs the revised text from original + diff. ```typescript import { createDiff, applyPatch } from '@push.rocks/smartdiff'; const original = 'hi there'; const revised = 'hi Polly, there is a Sandwich.'; const patch = createDiff(original, revised); const reconstructed = applyPatch(original, patch); // reconstructed === revised ✓ ``` --- ## 🔤 Character-Level Diff For precise character-by-character comparison: ### `getCharDiff(original, revision)` Returns an array of diff segments. ```typescript import { getCharDiff } from '@push.rocks/smartdiff'; const segments = getCharDiff('hello', 'hallo'); // [ // { type: 'equal', value: 'h' }, // { type: 'delete', value: 'e' }, // { type: 'insert', value: 'a' }, // { type: 'equal', value: 'llo' } // ] ``` ### `formatCharDiffForConsole(original, revision)` Returns ANSI-colored string for terminal output. ```typescript import { formatCharDiffForConsole } from '@push.rocks/smartdiff'; console.log(formatCharDiffForConsole('hello world', 'hello beautiful world')); // Displays: hello [green background]beautiful [/green]world ``` ### `formatCharDiffAsHtml(original, revision)` Returns HTML with styled spans. ```typescript import { formatCharDiffAsHtml } from '@push.rocks/smartdiff'; const html = formatCharDiffAsHtml('hello', 'hallo'); // h // e // a // llo ``` --- ## 📝 Word-Level Diff For document and prose comparison: ### `getWordDiff(original, revision)` ```typescript import { getWordDiff } from '@push.rocks/smartdiff'; const segments = getWordDiff('The quick brown fox', 'The slow brown dog'); // [ // { type: 'equal', value: 'The ' }, // { type: 'delete', value: 'quick' }, // { type: 'insert', value: 'slow' }, // { type: 'equal', value: ' brown ' }, // { type: 'delete', value: 'fox' }, // { type: 'insert', value: 'dog' } // ] ``` ### `formatWordDiffForConsole(original, revision)` ```typescript import { formatWordDiffForConsole } from '@push.rocks/smartdiff'; console.log(formatWordDiffForConsole('Hello World', 'Hello Beautiful World')); // Displays: Hello [green]Beautiful [/green]World ``` ### `formatWordDiffAsHtml(original, revision)` ```typescript import { formatWordDiffAsHtml } from '@push.rocks/smartdiff'; const html = formatWordDiffAsHtml('one two three', 'one TWO three'); // one // two // TWO // three ``` --- ## 📄 Line-Level Diff For code and file comparison: ### `getLineDiff(original, revision)` ```typescript import { getLineDiff } from '@push.rocks/smartdiff'; const lineDiff = getLineDiff('line1\nline2\nline3', 'line1\nmodified\nline3'); // [ // { lineNumber: 1, type: 'equal', value: 'line1' }, // { lineNumber: 2, type: 'delete', value: 'line2' }, // { lineNumber: -1, type: 'insert', value: 'modified' }, // { lineNumber: 3, type: 'equal', value: 'line3' } // ] ``` ### `formatLineDiffForConsole(original, revision)` Produces unified diff-style output with colors: ```typescript import { formatLineDiffForConsole } from '@push.rocks/smartdiff'; const oldCode = `function hello() { console.log("hi"); }`; const newCode = `function hello() { console.log("hello world"); }`; console.log(formatLineDiffForConsole(oldCode, newCode)); ``` Output: ```diff function hello() { - console.log("hi"); + console.log("hello world"); } ``` ### `formatLineDiffAsHtml(original, revision)` ```typescript import { formatLineDiffAsHtml } from '@push.rocks/smartdiff'; const html = formatLineDiffAsHtml('a\nb\nc', 'a\nB\nc'); //