import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _typeof from "@babel/runtime/helpers/esm/typeof"; export var STATUS_ADD = 'add'; export var STATUS_KEEP = 'keep'; export var STATUS_REMOVE = 'remove'; export var STATUS_REMOVED = 'removed'; export function wrapKeyToObject(key) { var keyObj; if (key && _typeof(key) === 'object' && 'key' in key) { keyObj = key; } else { keyObj = { key: key }; } return _objectSpread(_objectSpread({}, keyObj), {}, { key: String(keyObj.key) }); } export function parseKeys() { var keys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return keys.map(wrapKeyToObject); } export 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 _objectSpread(_objectSpread({}, obj), {}, { status: STATUS_ADD }); })); currentIndex = i; } list.push(_objectSpread(_objectSpread({}, currentKeyObj), {}, { status: STATUS_KEEP })); currentIndex += 1; hit = true; break; } } // If not hit, it means key is removed if (!hit) { list.push(_objectSpread(_objectSpread({}, keyObj), {}, { status: STATUS_REMOVE })); } }); // Add rest to the list if (currentIndex < currentLen) { list = list.concat(currentKeyObjects.slice(currentIndex).map(function (obj) { return _objectSpread(_objectSpread({}, 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; }