UNPKG

datum-merge

Version:

Simplified diff and merging for deeply nested objects

186 lines (185 loc) 7.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UpdateCode = void 0; exports.mergeScalarField = mergeScalarField; exports.mergeVectorField = mergeVectorField; exports.mergeVectors = mergeVectors; const lodash_es_1 = require("lodash-es"); const type_utils_1 = require("./type-utils"); const datum_utils_1 = require("./datum-utils"); exports.UpdateCode = { T: "T", C: "C", N: "N", Y: "Y", F: "F", B: "B", U: "U", H: "H", I: "I", D: "D", XR: "XR", XM: "XM", XD: "XD", XI: "XI", XS: "XS", XF: "XF", }; function mergeScalarField(target, source, label, mergeCode) { const sourceHas = !(0, type_utils_1.isNullish)(source[label]); const targetKey = Object.prototype.hasOwnProperty.call(target, label); const targetHas = targetKey && !(0, type_utils_1.isNullish)(target[label]); if (!targetKey && !sourceHas) { return false; } if (targetHas && sourceHas) { if ((0, type_utils_1.typeOfValue)(target[label]) !== (0, type_utils_1.typeOfValue)(source[label])) { throw new TypeError("scalar type mismatch for " + label); } if (target[label] === source[label]) { return false; } } let migrateVal = false; switch (mergeCode) { case exports.UpdateCode.N: return false; case exports.UpdateCode.Y: target[label] = (0, datum_utils_1.deepClone)(source[label]); return true; case exports.UpdateCode.F: migrateVal = true; break; case exports.UpdateCode.B: if (sourceHas) migrateVal = true; break; case exports.UpdateCode.U: if (targetHas) migrateVal = true; break; case exports.UpdateCode.I: if (!targetHas) migrateVal = true; break; case exports.UpdateCode.H: if (targetHas && sourceHas) migrateVal = true; break; case exports.UpdateCode.D: if (targetHas && !sourceHas) migrateVal = true; break; case exports.UpdateCode.XR: case exports.UpdateCode.XS: case exports.UpdateCode.XF: case exports.UpdateCode.XM: case exports.UpdateCode.XD: case exports.UpdateCode.XI: return mergeVectorField(target, source, label, mergeCode); } if (!migrateVal) { return false; } target[label] = !sourceHas || (0, type_utils_1.isPrimitive)(source[label]) ? source[label] : (0, datum_utils_1.deepClone)(source[label]); if ((0, type_utils_1.emptyValue)(target[label])) { delete target[label]; return targetKey; } return true; } ; function mergeVectorField(target, source, label, mergeCode) { var _a, _b; let sourceVals = source[label]; if ((0, type_utils_1.isNullish)(sourceVals)) { return false; } let sourceVec = (0, type_utils_1.isArrayOfAny)(sourceVals); const targetKey = Object.prototype.hasOwnProperty.call(target, label); const targetHas = targetKey && !(0, type_utils_1.isNullish)(target[label]); const targetVec = (0, type_utils_1.isArrayOfAny)(target[label]); if (targetHas && !targetVec) { throw new TypeError("type change to vector for " + label); } if (!sourceVec) { sourceVals = [sourceVals]; sourceVec = true; } const skipEquals = (!targetHas || (0, type_utils_1.isArrayOf)(target[label], type_utils_1.isPrimitive)) && (0, type_utils_1.isArrayOf)(sourceVals, type_utils_1.isPrimitive); let targetVals; switch (mergeCode) { case exports.UpdateCode.N: return false; case exports.UpdateCode.Y: target[label] = (0, datum_utils_1.deepClone)(sourceVals); return true; case exports.UpdateCode.XR: targetVals = [...sourceVals]; break; case exports.UpdateCode.XS: targetVals = (0, lodash_es_1.concat)((_a = target[label]) !== null && _a !== void 0 ? _a : [], sourceVals); break; case exports.UpdateCode.XF: targetVals = (0, lodash_es_1.concat)(sourceVals, (_b = target[label]) !== null && _b !== void 0 ? _b : []); break; case exports.UpdateCode.B: case exports.UpdateCode.XM: targetVals = skipEquals ? (0, lodash_es_1.union)(target[label], sourceVals) : (0, lodash_es_1.unionWith)(target[label], sourceVals, datum_utils_1.deepEquals); break; case exports.UpdateCode.XD: targetVals = skipEquals ? (0, lodash_es_1.difference)(target[label], sourceVals) : (0, lodash_es_1.differenceWith)(target[label], sourceVals, datum_utils_1.deepEquals); break; case exports.UpdateCode.XI: targetVals = skipEquals ? (0, lodash_es_1.intersection)(target[label], sourceVals) : (0, lodash_es_1.intersectionWith)(target[label], sourceVals, datum_utils_1.deepEquals); break; default: return false; } if (!(targetVals === null || targetVals === void 0 ? void 0 : targetVals.length)) { delete target[label]; return targetKey; } const changed = !(0, datum_utils_1.areArraysEqual)(targetVals, target[label]); target[label] = !changed ? targetVals : (0, datum_utils_1.deepClone)(targetVals); return changed; } ; function mergeVectors(mergeCode, arr1, arr2, equalsCond) { if (!(arr1 === null || arr1 === void 0 ? void 0 : arr1.length) && !(arr2 === null || arr2 === void 0 ? void 0 : arr2.length)) return []; if (equalsCond === false) { equalsCond = undefined; } else if (typeof equalsCond !== "function") { equalsCond = (0, type_utils_1.isArrayOf)(arr1, type_utils_1.isPrimitive) && (0, type_utils_1.isArrayOf)(arr2, type_utils_1.isPrimitive) ? undefined : datum_utils_1.deepEquals; } if (equalsCond) { switch (mergeCode) { case exports.UpdateCode.XM: return (0, lodash_es_1.unionWith)(arr1, arr2, equalsCond); case exports.UpdateCode.XI: return (0, lodash_es_1.intersectionWith)(arr1, arr2, equalsCond); case exports.UpdateCode.XD: return (0, lodash_es_1.differenceWith)(arr1, arr2, equalsCond); } } switch (mergeCode) { case exports.UpdateCode.XM: return (0, lodash_es_1.union)(arr1, arr2); case exports.UpdateCode.XI: return (0, lodash_es_1.intersection)(arr1, arr2); case exports.UpdateCode.XD: return (0, lodash_es_1.difference)(arr1, arr2); case exports.UpdateCode.XS: return (0, lodash_es_1.concat)(arr1 !== null && arr1 !== void 0 ? arr1 : [], arr2 !== null && arr2 !== void 0 ? arr2 : []); } throw new Error("invalid merge code " + mergeCode); }