UNPKG

datum-merge

Version:

Simplified diff and merging for deeply nested objects

144 lines (143 loc) 4.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UpdateCode = void 0; exports.mergeScalarField = mergeScalarField; exports.mergeVectorField = mergeVectorField; 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", 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 = target.hasOwnProperty(label); const targetHas = targetKey && !(0, type_utils_1.isNullish)(target[label]); if (!targetHas && !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.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 = target.hasOwnProperty(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; } 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 = (0, lodash_es_1.unionWith)(target[label], sourceVals, datum_utils_1.deepEquals); break; case exports.UpdateCode.XD: targetVals = (0, lodash_es_1.differenceWith)(target[label], sourceVals, datum_utils_1.deepEquals); break; case exports.UpdateCode.XI: targetVals = (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; } ;