-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
61 lines (50 loc) · 2.26 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const deepDiff = require('deep-diff');
const R = require('ramda');
const KIND_ADDED = 'N';
const KIND_ARRAY = 'A';
const KIND_DELETED = 'D';
const KIND_EDITED = 'E';
class ObjectDiffer {
diff(objLeft, objRight) {
const diffs = deepDiff(objLeft, objRight);
// verify change happened in an array
return diffs.map(diff => {
const isNestedChange = diff.path.length > 2;
const isArrayElementChange = R.any(R.is(Number), diff.path);
if (!isNestedChange || !isArrayElementChange || diff.kind === KIND_ARRAY || diff.kind === KIND_EDITED || diff.kind === KIND_DELETED) {
return diff;
}
return this._createDiffForChangedArrayElement(objLeft, objRight, diff.path, diff);
}).reduce((diffs, diff) => {
const isArrayElementChange = R.any(R.is(Number), diff.path);
if ((diff.kind === KIND_DELETED || diff.kind === KIND_ARRAY || diff.kind === KIND_EDITED) && isArrayElementChange/*TODO && R.last(diffs) === diff*/) {
const diffAdapted = this._createDiffForChangedArrayElement(objLeft, objRight, diff.path, diff);
if (R.equals(
R.dissocPath(['item','path'], R.dissocPath(['item', 'lhs'], diffAdapted)),
R.dissocPath(['item','path'], R.dissocPath(['item', 'lhs'], R.last(diffs) || {}))
)
){
return diffs;
}
return R.append(diffAdapted, diffs);
}
return R.append(diff, diffs);
}, []);
}
_createDiffForChangedArrayElement(objLeft, objRight, path, diff) {
const elementPosition = R.findLastIndex(R.is(Number), path);
const pathToElement = R.slice(0, elementPosition + 1, path);
const elementModifiedLeft = R.path(pathToElement, objLeft);
const elementModifiedRight = R.path(pathToElement, objRight);
return {
"kind": KIND_ARRAY,
"path": pathToElement,
"item": R.merge(diff, {
lhs: elementModifiedLeft,
rhs: elementModifiedRight,
path: R.slice(elementPosition + 1, Infinity, path)
})
};
}
}
module.exports = new ObjectDiffer();