Skip to content

Commit b5f8c58

Browse files
authored
fix: avoid memory leak and concurrency issues (#157)
1 parent 31e4302 commit b5f8c58

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

lib/HtmlDiff.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,20 @@ import { defaults } from './defaults.js';
1515
* @param {Boolean} [options.ignoreSelfClosingSlash=false]
1616
*/
1717
export class HtmlDiff extends Diff {
18-
constructor(options) {
18+
constructor(options, tokens) {
1919
super(options);
2020
this.options = defaults(options);
21+
this._tokenOverride = tokens;
22+
}
23+
24+
/**
25+
* Tokenizes the given HTML
26+
*
27+
* This overrides the default tokenizer from the `diff`
28+
* @param {String} html
29+
* @returns {Array}
30+
*/
31+
tokenize(html) {
32+
return this._tokenOverride[html];
2133
}
2234
}

lib/index.js

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,11 @@ import modifyHtmlAccordingToOptions from './utils/modify.js';
33
import { defaults } from './defaults.js';
44
import handleMasks from './utils/mask.js';
55

6-
let htmlDifferOptions = {};
7-
const modifiedTokens = {};
8-
9-
async function saveModifiedTokens(html) {
10-
const tokens = await modifyHtmlAccordingToOptions(html, htmlDifferOptions);
11-
modifiedTokens[html] = tokens.split(/({{.+?}}(?!})|[{}\(\)\[\]#\*`=:;,.<>"'\/]|\s+)/).filter(i => i);
6+
async function getModifiedTokens(html, options) {
7+
const tokens = await modifyHtmlAccordingToOptions(html, options);
8+
return tokens.split(/({{.+?}}(?!})|[{}\(\)\[\]#\*`=:;,.<>"'\/]|\s+)/).filter(i => i);
129
}
1310

14-
/**
15-
* Tokenizes the given HTML
16-
* @param {String} html
17-
* @returns {Array}
18-
*/
19-
HtmlDiff.prototype.tokenize = function(html) {
20-
return modifiedTokens[html];
21-
};
22-
2311
/**
2412
* @class HtmlDiffer
2513
* @constructor
@@ -33,9 +21,7 @@ HtmlDiff.prototype.tokenize = function(html) {
3321
*/
3422
export class HtmlDiffer {
3523
constructor(options) {
36-
options = defaults(options);
37-
38-
htmlDifferOptions = options;
24+
this.options = defaults(options);
3925
}
4026

4127
/**
@@ -47,11 +33,18 @@ export class HtmlDiffer {
4733
* @returns {Diff}
4834
*/
4935
async diffHtml(html1, html2) {
50-
await saveModifiedTokens(html1);
51-
await saveModifiedTokens(html2);
36+
// precompute the tokenized html here, since it can't do it in `Diff.tokenize()` because
37+
// the sax parser is async
38+
const tokens = {
39+
html1: await getModifiedTokens(html1, this.options),
40+
html2: await getModifiedTokens(html2, this.options)
41+
};
42+
43+
const htmlDiffer = new HtmlDiff(this.options, tokens);
5244

53-
const htmlDiffer = new HtmlDiff(htmlDifferOptions);
54-
const diff = htmlDiffer.diff(html1, html2);
45+
// just pass in keys for the left and right html, the original strings are no longer used
46+
// after tokenize()
47+
const diff = htmlDiffer.diff('html1', 'html2');
5548

5649
return handleMasks(diff);
5750
};

0 commit comments

Comments
 (0)