UNPKG

@mtdt.temp/browser-core

Version:
93 lines 3.02 kB
import { getType } from './utils/typeUtils'; /** * Iterate over source and affect its sub values into destination, recursively. * If the source and destination can't be merged, return source. */ export function mergeInto(destination, source, circularReferenceChecker = createCircularReferenceChecker()) { // ignore the source if it is undefined if (source === undefined) { return destination; } if (typeof source !== 'object' || source === null) { // primitive values - just return source return source; } else if (source instanceof Date) { return new Date(source.getTime()); } else if (source instanceof RegExp) { const flags = source.flags || // old browsers compatibility [ source.global ? 'g' : '', source.ignoreCase ? 'i' : '', source.multiline ? 'm' : '', source.sticky ? 'y' : '', source.unicode ? 'u' : '', ].join(''); return new RegExp(source.source, flags); } if (circularReferenceChecker.hasAlreadyBeenSeen(source)) { // remove circular references return undefined; } else if (Array.isArray(source)) { const merged = Array.isArray(destination) ? destination : []; for (let i = 0; i < source.length; ++i) { merged[i] = mergeInto(merged[i], source[i], circularReferenceChecker); } return merged; } const merged = getType(destination) === 'object' ? destination : {}; for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { merged[key] = mergeInto(merged[key], source[key], circularReferenceChecker); } } return merged; } /** * A simplistic implementation of a deep clone algorithm. * Caveats: * - It doesn't maintain prototype chains - don't use with instances of custom classes. * - It doesn't handle Map and Set */ export function deepClone(value) { return mergeInto(undefined, value); } export function combine(...sources) { let destination; for (const source of sources) { // Ignore any undefined or null sources. if (source === undefined || source === null) { continue; } destination = mergeInto(destination, source); } return destination; } function createCircularReferenceChecker() { if (typeof WeakSet !== 'undefined') { const set = new WeakSet(); return { hasAlreadyBeenSeen(value) { const has = set.has(value); if (!has) { set.add(value); } return has; }, }; } const array = []; return { hasAlreadyBeenSeen(value) { const has = array.indexOf(value) >= 0; if (!has) { array.push(value); } return has; }, }; } //# sourceMappingURL=mergeInto.js.map