diff.js
3.71 KB
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wrapKeyToObject = wrapKeyToObject;
exports.parseKeys = parseKeys;
exports.diffKeys = diffKeys;
exports.STATUS_REMOVED = exports.STATUS_REMOVE = exports.STATUS_KEEP = exports.STATUS_ADD = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var STATUS_ADD = 'add';
exports.STATUS_ADD = STATUS_ADD;
var STATUS_KEEP = 'keep';
exports.STATUS_KEEP = STATUS_KEEP;
var STATUS_REMOVE = 'remove';
exports.STATUS_REMOVE = STATUS_REMOVE;
var STATUS_REMOVED = 'removed';
exports.STATUS_REMOVED = STATUS_REMOVED;
function wrapKeyToObject(key) {
var keyObj;
if (key && (0, _typeof2.default)(key) === 'object' && 'key' in key) {
keyObj = key;
} else {
keyObj = {
key: key
};
}
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, keyObj), {}, {
key: String(keyObj.key)
});
}
function parseKeys() {
var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
return keys.map(wrapKeyToObject);
}
function diffKeys() {
var prevKeys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
var currentKeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var list = [];
var currentIndex = 0;
var currentLen = currentKeys.length;
var prevKeyObjects = parseKeys(prevKeys);
var currentKeyObjects = parseKeys(currentKeys); // Check prev keys to insert or keep
prevKeyObjects.forEach(function (keyObj) {
var hit = false;
for (var i = currentIndex; i < currentLen; i += 1) {
var currentKeyObj = currentKeyObjects[i];
if (currentKeyObj.key === keyObj.key) {
// New added keys should add before current key
if (currentIndex < i) {
list = list.concat(currentKeyObjects.slice(currentIndex, i).map(function (obj) {
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, obj), {}, {
status: STATUS_ADD
});
}));
currentIndex = i;
}
list.push((0, _objectSpread2.default)((0, _objectSpread2.default)({}, currentKeyObj), {}, {
status: STATUS_KEEP
}));
currentIndex += 1;
hit = true;
break;
}
} // If not hit, it means key is removed
if (!hit) {
list.push((0, _objectSpread2.default)((0, _objectSpread2.default)({}, keyObj), {}, {
status: STATUS_REMOVE
}));
}
}); // Add rest to the list
if (currentIndex < currentLen) {
list = list.concat(currentKeyObjects.slice(currentIndex).map(function (obj) {
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, obj), {}, {
status: STATUS_ADD
});
}));
}
/**
* Merge same key when it remove and add again:
* [1 - add, 2 - keep, 1 - remove] -> [1 - keep, 2 - keep]
*/
var keys = {};
list.forEach(function (_ref) {
var key = _ref.key;
keys[key] = (keys[key] || 0) + 1;
});
var duplicatedKeys = Object.keys(keys).filter(function (key) {
return keys[key] > 1;
});
duplicatedKeys.forEach(function (matchKey) {
// Remove `STATUS_REMOVE` node.
list = list.filter(function (_ref2) {
var key = _ref2.key,
status = _ref2.status;
return key !== matchKey || status !== STATUS_REMOVE;
}); // Update `STATUS_ADD` to `STATUS_KEEP`
list.forEach(function (node) {
if (node.key === matchKey) {
// eslint-disable-next-line no-param-reassign
node.status = STATUS_KEEP;
}
});
});
return list;
}