Skip to content

Commit 7d1462e

Browse files
authored
Disable text diffs by default (#352)
* Update package-lock.json * Fix release workflow * Use @types/diff-match-patch * Add diffMatchPatch to options * Add sideEffects to package.json * Format * Add to README * Exclude diffMatchPatch option for with-text-diffs entry-point * Fix bin * Format
1 parent ca8ecb9 commit 7d1462e

File tree

14 files changed

+143
-182
lines changed

14 files changed

+143
-182
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ jobs:
1717
registry-url: 'https://registry.npmjs.org'
1818
- run: npm ci
1919
- run: npm publish
20+
working-directory: ./packages/jsondiffpatch
2021
env:
2122
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ In a browser, you can load a bundle using a tool like [esm.sh](https://esm.sh) o
187187

188188
```javascript
189189
import * as jsondiffpatch from 'jsondiffpatch';
190+
191+
// Only import if you want text diffs using diff-match-patch
192+
import DiffMatchPatch from 'diff-match-patch';
193+
190194
const jsondiffpatchInstance = jsondiffpatch.create({
191195
// used to match objects when diffing arrays, by default only === operator is used
192196
objectHash: function (obj) {
@@ -200,6 +204,9 @@ const jsondiffpatchInstance = jsondiffpatch.create({
200204
includeValueOnMove: false,
201205
},
202206
textDiff: {
207+
// If using text diffs, it's required to pass in the diff-match-patch library in through this proprty.
208+
// Alternatively, you can import jsondiffpatch using `jsondiffpatch/with-text-diffs` to avoid having to pass in diff-match-patch through the options.
209+
diffMatchPatch: DiffMatchPatch,
203210
// default 60, minimum string length (left and right sides) to use text diff algorythm: google-diff-match-patch
204211
minLength: 60,
205212
},

demos/console-demo/demo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as jsondiffpatch from 'jsondiffpatch';
1+
import * as jsondiffpatch from 'jsondiffpatch/with-text-diffs';
22
import * as consoleFormatter from 'jsondiffpatch/formatters/console';
33

44
const instance = jsondiffpatch.create({

demos/html-demo/demo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as jsondiffpatch from 'jsondiffpatch';
1+
import * as jsondiffpatch from 'jsondiffpatch/with-text-diffs';
22
import * as annotatedFormatter from 'jsondiffpatch/formatters/annotated';
33
import * as htmlFormatter from 'jsondiffpatch/formatters/html';
44

package-lock.json

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/jsondiffpatch/bin/jsondiffpatch

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env node
2+
3+
import { readFileSync } from 'node:fs';
4+
import * as jsondiffpatch from '../lib/with-text-diffs.js';
5+
import * as consoleFormatter from '../lib/formatters/console.js';
6+
7+
const fileLeft = process.argv[2];
8+
const fileRight = process.argv[3];
9+
10+
if (!fileLeft || !fileRight) {
11+
console.log('\n USAGE: jsondiffpatch left.json right.json');
12+
} else {
13+
const left = JSON.parse(readFileSync(fileLeft));
14+
const right = JSON.parse(readFileSync(fileRight));
15+
16+
const delta = jsondiffpatch.diff(left, right);
17+
consoleFormatter.log(delta);
18+
}

packages/jsondiffpatch/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@
77
"Benjamin Eidelman <beneidel@gmail.com>"
88
],
99
"type": "module",
10+
"sideEffects": [
11+
"*.css"
12+
],
1013
"main": "./lib/index.js",
1114
"types": "./lib/index.d.ts",
1215
"exports": {
1316
".": "./lib/index.js",
17+
"./with-text-diffs": "./lib/with-text-diffs.js",
1418
"./formatters/*": "./lib/formatters/*.js",
1519
"./formatters/styles/*.css": "./lib/formatters/styles/*.css"
1620
},
@@ -19,7 +23,7 @@
1923
"lib"
2024
],
2125
"bin": {
22-
"jsondiffpatch": "./bin/jsondiffpatch"
26+
"jsondiffpatch": "./bin/jsondiffpatch.js"
2327
},
2428
"scripts": {
2529
"build": "tsc && ncp ./src/formatters/styles/ ./lib/formatters/styles/",
@@ -39,6 +43,7 @@
3943
"patch"
4044
],
4145
"dependencies": {
46+
"@types/diff-match-patch": "^1.0.36",
4247
"chalk": "^5.3.0",
4348
"diff-match-patch": "^1.0.5"
4449
},

packages/jsondiffpatch/src/diff-match-patch.d.cts

Lines changed: 0 additions & 128 deletions
This file was deleted.

packages/jsondiffpatch/src/filters/texts.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import dmp from 'diff-match-patch';
1+
import type dmp from 'diff-match-patch';
22
import type DiffContext from '../contexts/diff.js';
33
import type PatchContext from '../contexts/patch.js';
44
import type ReverseContext from '../contexts/reverse.js';
@@ -8,13 +8,10 @@ import type {
88
Filter,
99
ModifiedDelta,
1010
MovedDelta,
11+
Options,
1112
TextDiffDelta,
1213
} from '../types.js';
1314

14-
declare global {
15-
const diff_match_patch: typeof dmp | undefined;
16-
}
17-
1815
interface DiffPatch {
1916
diff: (txt1: string, txt2: string) => string;
2017
patch: (txt1: string, string: string) => string;
@@ -24,42 +21,37 @@ const TEXT_DIFF = 2;
2421
const DEFAULT_MIN_LENGTH = 60;
2522
let cachedDiffPatch: DiffPatch | null = null;
2623

27-
function getDiffMatchPatch(required: true): DiffPatch;
28-
function getDiffMatchPatch(required?: boolean): DiffPatch;
29-
function getDiffMatchPatch(required?: boolean) {
24+
function getDiffMatchPatch(
25+
options: Options | undefined,
26+
required: true,
27+
): DiffPatch;
28+
function getDiffMatchPatch(
29+
options: Options | undefined,
30+
required?: boolean,
31+
): DiffPatch | null;
32+
function getDiffMatchPatch(options: Options | undefined, required?: boolean) {
3033
if (!cachedDiffPatch) {
31-
let instance: dmp | null | undefined;
32-
if (typeof diff_match_patch !== 'undefined') {
33-
// already loaded, probably a browser
34-
instance =
35-
typeof diff_match_patch === 'function'
36-
? new diff_match_patch()
37-
: new (diff_match_patch as typeof dmp).diff_match_patch();
38-
} else if (dmp) {
39-
try {
40-
instance = dmp && new dmp();
41-
} catch (err) {
42-
instance = null;
43-
}
44-
}
45-
if (!instance) {
34+
let instance: dmp;
35+
if (options?.textDiff?.diffMatchPatch) {
36+
instance = new options.textDiff.diffMatchPatch();
37+
} else {
4638
if (!required) {
4739
return null;
4840
}
4941
const error: Error & { diff_match_patch_not_found?: boolean } = new Error(
50-
'text diff_match_patch library not found',
42+
'The diff-match-patch library was not provided. Pass the library in through the options or use the `jsondiffpatch/with-text-diffs` entry-point.',
5143
);
5244
// eslint-disable-next-line camelcase
5345
error.diff_match_patch_not_found = true;
5446
throw error;
5547
}
5648
cachedDiffPatch = {
5749
diff: function (txt1, txt2) {
58-
return instance!.patch_toText(instance!.patch_make(txt1, txt2));
50+
return instance.patch_toText(instance.patch_make(txt1, txt2));
5951
},
6052
patch: function (txt1, patch) {
61-
const results = instance!.patch_apply(
62-
instance!.patch_fromText(patch),
53+
const results = instance.patch_apply(
54+
instance.patch_fromText(patch),
6355
txt1,
6456
);
6557
for (let i = 0; i < results[1].length; i++) {
@@ -95,7 +87,7 @@ export const diffFilter: Filter<DiffContext> = function textsDiffFilter(
9587
return;
9688
}
9789
// large text, try to use a text-diff algorithm
98-
const diffMatchPatch = getDiffMatchPatch();
90+
const diffMatchPatch = getDiffMatchPatch(context.options);
9991
if (!diffMatchPatch) {
10092
// diff-match-patch library not available,
10193
// fallback to regular string replace
@@ -125,7 +117,7 @@ export const patchFilter: Filter<PatchContext> = function textsPatchFilter(
125117
const textDiffDelta = nonNestedDelta as TextDiffDelta;
126118

127119
// text-diff, use a text-patch algorithm
128-
const patch = getDiffMatchPatch(true).patch;
120+
const patch = getDiffMatchPatch(context.options, true).patch;
129121
context.setResult(patch(context.left as string, textDiffDelta[0])).exit();
130122
};
131123
patchFilter.filterName = 'texts';

packages/jsondiffpatch/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type dmp from 'diff-match-patch';
12
import type Context from './contexts/context.js';
23
import type DiffContext from './contexts/diff.js';
34

@@ -9,6 +10,7 @@ export interface Options {
910
includeValueOnMove?: boolean;
1011
};
1112
textDiff?: {
13+
diffMatchPatch: typeof dmp;
1214
minLength?: number;
1315
};
1416
propertyFilter?: (name: string, context: DiffContext) => boolean;

0 commit comments

Comments
 (0)