@mtdt.temp/browser-core
Version:
Datadog browser core utilities.
93 lines • 3.02 kB
JavaScript
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