@newdash/newdash
Version:
javascript/typescript utility library
92 lines (91 loc) • 4.01 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assignMergeValue_1 = __importDefault(require("./assignMergeValue"));
const cloneBuffer_1 = __importDefault(require("./cloneBuffer"));
const cloneTypedArray_1 = __importDefault(require("./cloneTypedArray"));
const copyArray_1 = __importDefault(require("./copyArray"));
const initCloneObject_1 = __importDefault(require("./initCloneObject"));
const isArguments_1 = __importDefault(require("../isArguments"));
const isArrayLikeObject_1 = __importDefault(require("../isArrayLikeObject"));
const isBuffer_1 = __importDefault(require("../isBuffer"));
const isObject_1 = __importDefault(require("../isObject"));
const isPlainObject_1 = __importDefault(require("../isPlainObject"));
const isTypedArray_1 = __importDefault(require("../isTypedArray"));
const toPlainObject_1 = __importDefault(require("../toPlainObject"));
const safeGet_1 = __importDefault(require("./safeGet"));
/**
* A specialized version of `baseMerge` for arrays and objects which performs
* deep merges and tracks traversed objects enabling objects with circular
* references to be merged.
*
* @private
* @param {Object} object The destination object.
* @param {Object} source The source object.
* @param {string} key The key of the value to merge.
* @param {number} srcIndex The index of `source`.
* @param {Function} mergeFunc The function to merge values.
* @param {Function} [customizer] The function to customize assigned values.
* @param {Object} [stack] Tracks traversed source values and their merged
* counterparts.
*/
function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) {
const objValue = (0, safeGet_1.default)(object, key);
const srcValue = (0, safeGet_1.default)(source, key);
const stacked = stack.get(srcValue);
if (stacked) {
(0, assignMergeValue_1.default)(object, key, stacked);
return;
}
let newValue = customizer
? customizer(objValue, srcValue, `${key}`, object, source, stack)
: undefined;
let isCommon = newValue === undefined;
if (isCommon) {
const isArr = Array.isArray(srcValue);
const isBuff = !isArr && (0, isBuffer_1.default)(srcValue);
const isTyped = !isArr && !isBuff && (0, isTypedArray_1.default)(srcValue);
newValue = srcValue;
if (isArr || isBuff || isTyped) {
if (Array.isArray(objValue)) {
newValue = objValue;
}
else if ((0, isArrayLikeObject_1.default)(objValue)) {
newValue = (0, copyArray_1.default)(objValue);
}
else if (isBuff) {
isCommon = false;
newValue = (0, cloneBuffer_1.default)(srcValue, true);
}
else if (isTyped) {
isCommon = false;
newValue = (0, cloneTypedArray_1.default)(srcValue, true);
}
else {
newValue = [];
}
}
else if ((0, isPlainObject_1.default)(srcValue) || (0, isArguments_1.default)(srcValue)) {
newValue = objValue;
if ((0, isArguments_1.default)(objValue)) {
newValue = (0, toPlainObject_1.default)(objValue);
}
else if (typeof objValue === 'function' || !(0, isObject_1.default)(objValue)) {
newValue = (0, initCloneObject_1.default)(srcValue);
}
}
else {
isCommon = false;
}
}
if (isCommon) {
// Recursively merge objects and arrays (susceptible to call stack limits).
stack.set(srcValue, newValue);
mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
stack['delete'](srcValue);
}
(0, assignMergeValue_1.default)(object, key, newValue);
}
exports.default = baseMergeDeep;