react-diff-viewer-continued 4.0.6 → 4.1.1

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.
@@ -0,0 +1,21 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebSearch",
5
+ "Bash(pnpm add:*)",
6
+ "Bash(npx playwright:*)",
7
+ "Bash(pnpm build:*)",
8
+ "Bash(pnpm test:*)",
9
+ "Bash(CI=1 pnpm test:*)",
10
+ "Bash(CI=1 npm test:*)",
11
+ "Bash(pnpm remove:*)",
12
+ "Bash(npm test:*)",
13
+ "Bash(npx tsc:*)",
14
+ "Bash(ls:*)",
15
+ "Bash(pnpm run build:*)",
16
+ "Bash(pnpm exec vitest:*)"
17
+ ],
18
+ "deny": [],
19
+ "ask": []
20
+ }
21
+ }
@@ -0,0 +1,48 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: write
11
+ id-token: write
12
+
13
+ jobs:
14
+ publish:
15
+ runs-on: ubuntu-latest
16
+ if: startsWith(github.event.head_commit.message, 'release:')
17
+ permissions:
18
+ contents: write
19
+ id-token: write
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - uses: pnpm/action-setup@v4
24
+ with:
25
+ version: latest
26
+
27
+ - uses: actions/setup-node@v4
28
+ with:
29
+ node-version: 'lts/*'
30
+ cache: 'pnpm'
31
+ registry-url: 'https://registry.npmjs.org'
32
+
33
+ - run: pnpm install
34
+ - run: pnpm build
35
+
36
+ # Upgrade npm for provenance support (GitHub runners ship with old npm)
37
+ - run: npm install -g npm@latest
38
+
39
+ - name: Publish to npm
40
+ run: pnpm publish --access public --provenance --no-git-checks
41
+ env:
42
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
43
+
44
+ # Create GitHub release with changelog notes
45
+ - name: Create GitHub release
46
+ run: pnpm just-release
47
+ env:
48
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,6 +1,13 @@
1
1
  name: Test & Release
2
+
2
3
  on:
3
4
  push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: write
10
+ pull-requests: write
4
11
 
5
12
  jobs:
6
13
  test:
@@ -11,40 +18,48 @@ jobs:
11
18
  uses: actions/checkout@v4
12
19
  with:
13
20
  fetch-depth: 0
21
+
14
22
  - name: Setup Node.js
15
23
  uses: actions/setup-node@v4
16
24
  with:
17
25
  node-version: 'lts/*'
26
+
18
27
  - uses: pnpm/action-setup@v4
19
28
  with:
20
29
  version: latest
30
+
21
31
  - name: Install dependencies
22
32
  run: pnpm i
33
+
23
34
  - name: Run unit tests
24
35
  run: pnpm run test
36
+
25
37
  release:
26
- name: Release
38
+ name: Create release PR
27
39
  needs: test
28
- if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/next'
29
40
  runs-on: ubuntu-latest
41
+ # Skip if this is already a release commit (from merging a release PR)
42
+ if: "!startsWith(github.event.head_commit.message, 'release:')"
30
43
  steps:
31
44
  - name: Checkout
32
45
  uses: actions/checkout@v4
33
46
  with:
34
47
  fetch-depth: 0
48
+
35
49
  - name: Setup Node.js
36
50
  uses: actions/setup-node@v4
37
51
  with:
38
52
  node-version: 'lts/*'
53
+
39
54
  - uses: pnpm/action-setup@v4
40
55
  with:
41
56
  version: latest
57
+
42
58
  - name: Install dependencies
43
59
  run: pnpm i
44
- - name: Build application
45
- run: pnpm run build
46
- - name: Release
60
+
61
+ - name: Create release PR
47
62
  env:
48
- GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
49
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
50
- run: pnpm semantic-release
63
+ CI: 1
64
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
65
+ run: pnpm just-release
package/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ # Changelog
2
+
3
+ ## 4.1.1 (2026-02-07)
4
+
5
+ ### Bug Fixes
6
+
7
+ - fix problem with missing worker in compiled version
8
+
9
+ ## 4.1.0 (2026-02-04)
10
+
11
+ ### Features
12
+
13
+ - merge compute worker PR and optimize to use virtualization
14
+ - use just-release instead of semantic-release, still semantic, simpler
15
+
16
+ ### Bug Fixes
17
+
18
+ - ordering and syntax highlighting fixes
19
+ - need to actually push your new workflows if you want to use them
20
+
1
21
  ## [4.0.6](https://github.com/aeolun/react-diff-viewer-continued/compare/v4.0.5...v4.0.6) (2025-05-13)
2
22
 
3
23
 
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- <img src='https://github.com/Aeolun/react-diff-viewer-continued/raw/master/logo_dark.png' width="100%" alt='React Diff Viewer' />
1
+ <img src='https://github.com/Aeolun/react-diff-viewer-continued/raw/main/logo_dark.png' width="100%" alt='React Diff Viewer' />
2
2
 
3
3
  <br/>
4
4
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![npm version](https://img.shields.io/npm/v/react-diff-viewer-continued)](https://www.npmjs.com/package/react-diff-viewer-continued)
10
10
  [![npm downloads](https://img.shields.io/npm/dw/react-diff-viewer-continued)](https://www.npmjs.com/package/react-diff-viewer-continued)
11
- [![GitHub license](https://img.shields.io/github/license/aeolun/react-diff-viewer-continued.svg)](https://github.com/aeolun/react-diff-viewer-continued/blob/master/LICENSE)
11
+ [![GitHub license](https://img.shields.io/github/license/aeolun/react-diff-viewer-continued.svg)](https://github.com/aeolun/react-diff-viewer-continued/blob/main/LICENSE)
12
12
 
13
13
  A simple and beautiful text diff viewer component made with [Diff](https://github.com/kpdecker/jsdiff) and [React](https://reactjs.org).
14
14
 
@@ -71,29 +71,85 @@ class Diff extends PureComponent {
71
71
 
72
72
  | Prop | Type | Default | Description |
73
73
  |---------------------------|---------------------------|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
74
- | oldValue | `string \| Object` | `''` | Old value as string (or Object if using `diffJson`). |
75
- | newValue | `string \| Object` | `''` | New value as string (or Object if using `diffJson`). |
74
+ | oldValue | `string \| Object` | `''` | Old value as string (or Object if using `DiffMethod.JSON`). |
75
+ | newValue | `string \| Object` | `''` | New value as string (or Object if using `DiffMethod.JSON`). |
76
76
  | splitView | `boolean` | `true` | Switch between `unified` and `split` view. |
77
77
  | disableWordDiff | `boolean` | `false` | Show and hide word diff in a diff line. |
78
- | compareMethod | `DiffMethod \| (string, string) => diff.Change[]` | `DiffMethod.CHARS` | Uses an existing diff method when a `DiffMethod` enum is passed. If a function is passed, that function is used as the diff method. <br /> <br /> JsDiff text diff method used for diffing strings. Check out the [guide](https://github.com/praneshr/react-diff-viewer/tree/v3.0.0#text-block-diff-comparison) to use different methods. |
78
+ | compareMethod | `DiffMethod \| (string, string) => diff.Change[]` | `DiffMethod.CHARS` | JsDiff text diff method. See [Text block diff comparison](#text-block-diff-comparison). **Important:** For JSON files use `DiffMethod.JSON`, for YAML files use `DiffMethod.YAML` - these use optimized structural comparison that is significantly faster than generic text diff for large files. |
79
79
  | renderGutter | `(diffData) => ReactNode` | `undefined` | Function that can be used to render an extra gutter with various information next to the line number. |
80
80
  | hideLineNumbers | `boolean` | `false` | Show and hide line numbers. |
81
- | alwaysShowLines | `string[]` | `[]` | List of lines to always be shown, regardless of diff status. Line number are prefixed with `L` and `R` for the left and right section of the diff viewer, respectively. For example, `L-20` means 20th line in the left pane. `extraLinesSurroundingDiff` applies to these lines as well. |
82
- | renderContent | `function` | `undefined` | Render Prop API to render code in the diff viewer. Helpful for [syntax highlighting](#syntax-highlighting) |
83
- | onLineNumberClick | `function` | `undefined` | Event handler for line number click. `(lineId: string) => void` |
84
- | highlightLines | `string[]` | `[]` | List of lines to be highlighted. Works together with `onLineNumberClick`. Line number are prefixed with `L` and `R` for the left and right section of the diff viewer, respectively. For example, `L-20` means 20th line in the left pane. To highlight a range of line numbers, pass the prefixed line number as an array. For example, `[L-2, L-3, L-4, L-5]` will highlight the lines `2-5` in the left pane. |
85
- | showDiffOnly | `boolean` | `true` | Shows only the diffed lines and folds the unchanged lines |
81
+ | alwaysShowLines | `string[]` | `[]` | List of lines to always be shown, regardless of diff status. Line numbers are prefixed with `L` and `R` for the left and right section of the diff viewer, respectively. For example, `L-20` means 20th line in the left pane. `extraLinesSurroundingDiff` applies to these lines as well. |
82
+ | renderContent | `function` | `undefined` | Render Prop API to render code in the diff viewer. Helpful for [syntax highlighting](#syntax-highlighting). |
83
+ | onLineNumberClick | `function` | `undefined` | Event handler for line number click. `(lineId: string, event: MouseEvent) => void` |
84
+ | highlightLines | `string[]` | `[]` | List of lines to be highlighted. Works together with `onLineNumberClick`. Line numbers are prefixed with `L` and `R` for the left and right section of the diff viewer, respectively. For example, `L-20` means 20th line in the left pane. To highlight a range of line numbers, pass the prefixed line number as an array. For example, `[L-2, L-3, L-4, L-5]` will highlight the lines `2-5` in the left pane. |
85
+ | showDiffOnly | `boolean` | `true` | Shows only the diffed lines and folds the unchanged lines. |
86
86
  | extraLinesSurroundingDiff | `number` | `3` | Number of extra unchanged lines surrounding the diff. Works along with `showDiffOnly`. |
87
- | codeFoldMessageRenderer | `function` | `Expand {number} of lines ...` | Render Prop API to render code fold message. |
88
- | styles | `object` | `{}` | To override style variables and styles. Learn more about [overriding styles](#overriding-styles) |
89
- | useDarkTheme | `boolean` | `true` | To enable/disable dark theme. |
90
- | leftTitle | `string` | `undefined` | Column title for left section of the diff in split view. This will be used as the only title in inline view. |
91
- | rightTitle | `string` | `undefined` | Column title for right section of the diff in split view. This will be ignored in inline view. |
87
+ | codeFoldMessageRenderer | `function` | `undefined` | Render Prop API to render code fold message. `(totalFoldedLines: number, leftStartLineNumber: number, rightStartLineNumber: number) => ReactElement` |
88
+ | styles | `object` | `{}` | To override style variables and styles. Learn more about [overriding styles](#overriding-styles). |
89
+ | useDarkTheme | `boolean` | `false` | To enable/disable dark theme. |
90
+ | leftTitle | `string \| ReactElement` | `undefined` | Column title for left section of the diff in split view. This will be used as the only title in inline view. |
91
+ | rightTitle | `string \| ReactElement` | `undefined` | Column title for right section of the diff in split view. This will be ignored in inline view. |
92
92
  | linesOffset | `number` | `0` | Number to start count code lines from. |
93
+ | summary | `string \| ReactElement` | `undefined` | Text or element to display in the summary bar (e.g., filename). |
94
+ | hideSummary | `boolean` | `false` | Hide the summary bar (expand/collapse button, change count, summary text). |
95
+ | infiniteLoading | `{ pageSize: number, containerHeight: string }` | `undefined` | Enable virtualization for large diffs. When enabled, only visible rows are rendered. `containerHeight` sets the scrollable container height (e.g., `'500px'` or `'80vh'`). |
96
+ | loadingElement | `() => ReactElement` | `undefined` | Function that returns an element to display while the diff is being computed. Useful with `infiniteLoading` for large files. |
97
+ | nonce | `string` | `''` | Nonce to use for inline styles (for CSP). |
93
98
 
94
99
  ## Instance Methods
95
100
 
96
- `resetCodeBlocks()` - Resets the expanded code blocks to it's initial state. Return `true` on successful reset and `false` during unsuccessful reset.
101
+ `resetCodeBlocks()` - Resets the expanded code blocks to its initial state. Returns `true` on successful reset and `false` during unsuccessful reset.
102
+
103
+ ## Large Diffs and Performance
104
+
105
+ For large files (thousands of lines), the diff viewer provides several features to maintain good performance:
106
+
107
+ ### Virtualization with infiniteLoading
108
+
109
+ Enable virtualization to only render visible rows:
110
+
111
+ ```javascript
112
+ <ReactDiffViewer
113
+ oldValue={largeOldFile}
114
+ newValue={largeNewFile}
115
+ infiniteLoading={{
116
+ pageSize: 20,
117
+ containerHeight: '80vh'
118
+ }}
119
+ loadingElement={() => (
120
+ <div style={{ padding: '20px', textAlign: 'center' }}>
121
+ Computing diff...
122
+ </div>
123
+ )}
124
+ />
125
+ ```
126
+
127
+ When `infiniteLoading` is enabled:
128
+ - Only visible rows are rendered (virtualization)
129
+ - Word-level diffs are computed on-demand as lines become visible
130
+ - A loading element can be shown while the initial diff is computed
131
+
132
+ ### Use optimized diff methods for structured data
133
+
134
+ For JSON and YAML files, always use the dedicated diff methods:
135
+
136
+ ```javascript
137
+ // For JSON files - up to 100x faster for large files
138
+ <ReactDiffViewer
139
+ oldValue={jsonObject}
140
+ newValue={newJsonObject}
141
+ compareMethod={DiffMethod.JSON}
142
+ />
143
+
144
+ // For YAML files
145
+ <ReactDiffViewer
146
+ oldValue={yamlString}
147
+ newValue={newYamlString}
148
+ compareMethod={DiffMethod.YAML}
149
+ />
150
+ ```
151
+
152
+ See [JSON and YAML diffing](#json-and-yaml-diffing) for more details.
97
153
 
98
154
  ## Syntax Highlighting
99
155
 
@@ -113,7 +169,7 @@ An example using [Prism JS](https://prismjs.com)
113
169
 
114
170
  ```javascript
115
171
  import React, { PureComponent } from 'react';
116
- import ReactDiffViewer from 'react-diff-viewer';
172
+ import ReactDiffViewer from 'react-diff-viewer-continued';
117
173
 
118
174
  const oldCode = `
119
175
  const a = 10
@@ -160,7 +216,7 @@ class Diff extends PureComponent {
160
216
 
161
217
  ## Text block diff comparison
162
218
 
163
- Different styles of text block diffing are possible by using the enums corresponding to variou JsDiff methods ([learn more](https://github.com/kpdecker/jsdiff/tree/v4.0.1#api)). The supported methods are as follows.
219
+ Different styles of text block diffing are possible by using the enums corresponding to various JsDiff methods ([learn more](https://github.com/kpdecker/jsdiff/tree/v4.0.1#api)). The supported methods are as follows.
164
220
 
165
221
  ```javascript
166
222
  enum DiffMethod {
@@ -171,25 +227,87 @@ enum DiffMethod {
171
227
  TRIMMED_LINES = 'diffTrimmedLines',
172
228
  SENTENCES = 'diffSentences',
173
229
  CSS = 'diffCss',
230
+ JSON = 'diffJson', // Optimized for JSON files
231
+ YAML = 'diffYaml', // Optimized for YAML files
174
232
  }
175
233
  ```
176
234
 
235
+ ### JSON and YAML diffing
236
+
237
+ For JSON and YAML files, use the dedicated `DiffMethod.JSON` and `DiffMethod.YAML` methods. These use an optimized structural comparison algorithm that is **significantly faster** than generic text diff for large files.
238
+
239
+ **Why use these methods?**
240
+
241
+ Generic text diff algorithms (like `CHARS` or `WORDS`) compare files character-by-character using the Myers diff algorithm, which has O(ND) complexity where N is the file size and D is the number of differences. For large JSON/YAML files (thousands of lines), this can take several seconds or even freeze the browser.
242
+
243
+ The `JSON` and `YAML` methods instead:
244
+ 1. Parse the data structure
245
+ 2. Compare objects/arrays structurally
246
+ 3. Only run text diff on the parts that actually differ
247
+
248
+ This reduces comparison time from seconds to milliseconds for typical configuration files.
249
+
250
+ ```javascript
251
+ import React from 'react';
252
+ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued';
253
+
254
+ // For JSON - can pass objects directly
255
+ const oldJson = { name: "Original", items: [1, 2, 3] };
256
+ const newJson = { name: "Updated", items: [1, 2, 3, 4] };
257
+
258
+ // For YAML - pass as strings
259
+ const oldYaml = `
260
+ name: Original
261
+ items:
262
+ - 1
263
+ - 2
264
+ `;
265
+ const newYaml = `
266
+ name: Updated
267
+ items:
268
+ - 1
269
+ - 2
270
+ - 3
271
+ `;
272
+
273
+ function JsonDiff() {
274
+ return (
275
+ <ReactDiffViewer
276
+ oldValue={oldJson}
277
+ newValue={newJson}
278
+ compareMethod={DiffMethod.JSON}
279
+ splitView={true}
280
+ />
281
+ );
282
+ }
283
+
284
+ function YamlDiff() {
285
+ return (
286
+ <ReactDiffViewer
287
+ oldValue={oldYaml}
288
+ newValue={newYaml}
289
+ compareMethod={DiffMethod.YAML}
290
+ splitView={true}
291
+ />
292
+ );
293
+ }
294
+ ```
295
+
296
+ ### Other diff methods
297
+
298
+ For regular code or text files, use the standard diff methods:
299
+
177
300
  ```javascript
178
301
  import React, { PureComponent } from 'react';
179
- import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer';
302
+ import ReactDiffViewer, { DiffMethod } from 'react-diff-viewer-continued';
180
303
 
181
304
  const oldCode = `
182
- {
183
- "name": "Original name",
184
- "description": null
185
- }
305
+ const a = 10
306
+ const b = 10
186
307
  `;
187
308
  const newCode = `
188
- {
189
- "name": "My updated name",
190
- "description": "Brand new description",
191
- "status": "running"
192
- }
309
+ const a = 10
310
+ const boo = 10
193
311
  `;
194
312
 
195
313
  class Diff extends PureComponent {
@@ -300,7 +418,7 @@ For keys other than `variables`, the value can either be an object or string int
300
418
 
301
419
  ```javascript
302
420
  import React, { PureComponent } from 'react';
303
- import ReactDiffViewer from 'react-diff-viewer';
421
+ import ReactDiffViewer from 'react-diff-viewer-continued';
304
422
 
305
423
  const oldCode = `
306
424
  const a = 10
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.computeHiddenBlocks = computeHiddenBlocks;
4
- function computeHiddenBlocks(lineInformation, diffLines, extraLines) {
1
+ export function computeHiddenBlocks(lineInformation, diffLines, extraLines) {
5
2
  let newBlockIndex = 0;
6
3
  let currentBlock;
7
4
  const lineBlocks = {};
@@ -13,12 +13,14 @@ export declare enum DiffMethod {
13
13
  TRIMMED_LINES = "diffTrimmedLines",
14
14
  SENTENCES = "diffSentences",
15
15
  CSS = "diffCss",
16
- JSON = "diffJson"
16
+ JSON = "diffJson",
17
+ YAML = "diffYaml"
17
18
  }
18
19
  export interface DiffInformation {
19
20
  value?: string | DiffInformation[];
20
21
  lineNumber?: number;
21
22
  type?: DiffType;
23
+ rawValue?: string;
22
24
  }
23
25
  export interface LineInformation {
24
26
  left?: DiffInformation;
@@ -37,6 +39,15 @@ export interface JsDiffChangeObject {
37
39
  removed?: boolean;
38
40
  value?: string;
39
41
  }
42
+ /**
43
+ * Computes word diff information in the line.
44
+ * [TODO]: Consider adding options argument for JsDiff text block comparison
45
+ *
46
+ * @param oldValue Old word in the line.
47
+ * @param newValue New word in the line.
48
+ * @param compareMethod JsDiff text diff method from https://github.com/kpdecker/jsdiff/tree/v4.0.1#api
49
+ */
50
+ declare const computeDiff: (oldValue: string | Record<string, unknown>, newValue: string | Record<string, unknown>, compareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[])) => ComputedDiffInformation;
40
51
  /**
41
52
  * [TODO]: Think about moving common left and right value assignment to a
42
53
  * common place. Better readability?
@@ -52,5 +63,18 @@ export interface JsDiffChangeObject {
52
63
  * @param linesOffset line number to start counting from
53
64
  * @param showLines lines that are always shown, regardless of diff
54
65
  */
55
- declare const computeLineInformation: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[]) => ComputedLineInformation;
56
- export { computeLineInformation };
66
+ declare const computeLineInformation: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[], deferWordDiff?: boolean) => ComputedLineInformation;
67
+ /**
68
+ * Computes line diff information using a Web Worker to avoid blocking the UI thread.
69
+ * This offloads the expensive `computeLineInformation` logic to a separate thread.
70
+ *
71
+ * @param oldString Old string to compare.
72
+ * @param newString New string to compare with old string.
73
+ * @param disableWordDiff Flag to enable/disable word diff.
74
+ * @param lineCompareMethod JsDiff text diff method from https://github.com/kpdecker/jsdiff/tree/v4.0.1#api
75
+ * @param linesOffset line number to start counting from
76
+ * @param showLines lines that are always shown, regardless of diff
77
+ * @returns Promise<ComputedLineInformation> - Resolves with line-by-line diff data from the worker.
78
+ */
79
+ declare const computeLineInformationWorker: (oldString: string | Record<string, unknown>, newString: string | Record<string, unknown>, disableWordDiff?: boolean, lineCompareMethod?: DiffMethod | ((oldStr: string, newStr: string) => diff.Change[]), linesOffset?: number, showLines?: string[], deferWordDiff?: boolean) => Promise<ComputedLineInformation>;
80
+ export { computeLineInformation, computeLineInformationWorker, computeDiff };