Release Highlights
-
Shared incremental DOM rendering. Diff viewing and editing now use the same renderer, patching only affected rows. It matches or beats the previous renderers' performance across viewing and editing.
-
Faster diffing with WebAssembly.
@pierre/patchesis an optional, significantly faster replacement forjsdiff, with the same diff output. Enable it throughFileDifforCodeViewoptions:<CodeView items={items} options={{ parseDiffOptions: { preferredDiffLib: '@pierre/patches' } }} />
With a worker pool, also set
highlighterOptions.preferredDiffLibto'@pierre/patches'for inline highlights. -
Find and replace in CodeView. Cmd/Ctrl+F searches across expanded items. Focus an editor to search and replace within that file, with highlights that stay in sync as you type.
Breaking changes
Renderer results
HunksRenderResult and FileRenderResult no longer expose *GutterAST, *ContentAST, gutterAST, contentAST, or css. Use the renderer to generate code nodes:
const diffNodes = diffRenderer.renderCodeAST('additions', diffResult);
const fileNodes = fileRenderer.renderCodeAST(fileResult);Diff columns accept 'unified', 'deletions', or 'additions'. For separate raw gutter/content cells, use columnCells(fileResult.column) or columnCells(diffResult.columns[type]) when that column exists. Remove reads of css; it was always empty.
FileRenderer.renderPartialHTML was also removed. Replace it with:
import { hastToHtml } from '@pierre/diffs';
const html = hastToHtml(fileRenderer.renderCodeAST(result));Editor callbacks
Calling edit, applyEdits, undo, redo, or cleanUp inside onChange or onEditChange now throws, as does rendering a new file or diff there. Defer follow-up mutations until the callback returns:
onEditChange({ file }) {
queueMicrotask(() => editor.applyEdits(formatOn(file)));
}These callbacks report the updated document synchronously; the rendered DOM may still be behind.
Word diff marks in custom rendering
renderDiffWithHighlighter no longer adds data-diff-span marks or applies lineDiffType / maxLineDiffLength. If you consume its rows directly, add the marks yourself using your previous settings (defaults: 'word-alt', 1000):
import {
DiffModel,
LineDiffRangeCache,
lineDiffRangesFor,
markRow,
} from '@pierre/diffs';
const model = DiffModel.fromDiff(diff);
const ranges = new LineDiffRangeCache('word-alt', 1000);
const additionLines = code.additionLines.map((row, line) =>
row.type === 'element'
? markRow(row, lineDiffRangesFor(model, 'additions', line, ranges))
: row
);Here, code is the helper's returned code. Repeat for code.deletionLines with 'deletions'. Built-in components apply these marks automatically.
Custom CodeView editor factories
createEditor now receives onFocus, onBlur, onRender, and searchPanel: 'host' alongside onChange. Pass the full options object to new Editor(type, options, editStateKey) so the new options reach the editor.
Search styling
Replace [data-match-range] selectors with ::highlight(diffs-search-match) and ::highlight(diffs-search-current). Theme editor.findMatch* colors and --diffs-editor-match-bg / --diffs-editor-match-highlight-bg no longer control matches. Set these variables on the host:
| Appearance | Variable |
|---|---|
| Match text | --diffs-fg-search-match-override
|
| Match background | --diffs-bg-search-match-override
|
| Current match background | --diffs-bg-search-match-current-override
|
Defaults are black text, yellow matches, and a modified-blue current match. Match painting requires CSS.highlights; navigation and replacement still work without it.
The find panel now has its own shadow root. Existing panel hooks still work through unsafeCSS, but :host now targets the panel. Remove selectors that depend on file-container ancestors; position the panel with --diffs-search-panel-inset-top and --diffs-search-panel-inset-right. Close and reopen an existing panel to apply changed unsafeCSS.
Other component selectors were flattened (gutter numbers, [data-indicators], conflict markers, selected lines). If an override stops winning, adjust its specificity; place panel overrides in @layer unsafe to override @layer base.
TextDocument line endings
normalizeEol(text) now returns \n-normalized text. Use getText() or getLineText(line, true) when you need the file's original line endings.
What's Changed
- [diffs] Only insert icon sprite for rendered files by @karenling in #1260
- [diffs] Parse the icon sprite once per document by @mds-ant in #1106
- [diffs/edit] Editing Architecture Refactor (tech debt, + some new stuff) (#1225) in #1225
- Introduce @pierre/patches package by @ije in #1193
- [diffs] CodeView: Ctrl+F by @amadeus in #833
New Contributors
- @karenling made their first contribution in #1260
- @mds-ant made their first contribution in #1106
Full Changelog: diffs-v1.6.4...diffs-v1.7.0-beta.1