@datadog/mobile-react-native
Version:
A client-side React Native module to interact with Datadog
90 lines (85 loc) • 2.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.deepClone = void 0;
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/
const isDate = (type, _) => {
return type === 'Date';
};
const isArray = (type, _) => {
return type === 'Array';
};
const isObject = (type, _) => {
return type === 'Object';
};
const isSet = (type, _) => {
return type === 'Set';
};
const isMap = (type, _) => {
return type === 'Map';
};
/**
* Be careful when changing this value, it can lead to performance issues: https://github.com/DataDog/dd-sdk-reactnative/issues/514.
* Benchmark of average execution time for an action event mapper with different max depth on iOS simulator:
* 7: 40ms
* 6: 15ms
* 5: 4ms
* 4: <1ms
*/
const MAX_DEPTH = 4;
/**
* Simple deep clone inspired from https://github.com/angus-c/just/blob/master/packages/collection-clone/index.cjs
* Functions and RegExp will be returned as they are.
* Maps and Sets are cloned even though they won't be accepted by React Native, just in case they are mutated by the user to avoid side effects.
*
* We added support for circular references by limiting the number of depth levels to 8.
* @param originalObject
* @returns
*/
const deepClone = (originalObject, depth = 0) => {
const type = {}.toString.call(originalObject).slice(8, -1);
if (isDate(type, originalObject)) {
return new Date(originalObject.getTime());
}
if (isSet(type, originalObject)) {
return new Set([...originalObject].map(value => deepClone(value)));
}
if (isMap(type, originalObject)) {
return new Map([...originalObject].map(kv => [deepClone(kv[0]), deepClone(kv[1])]));
}
if (isArray(type, originalObject)) {
if (depth >= MAX_DEPTH) {
// Break the circular reference here
return originalObject;
}
const result = [];
// eslint-disable-next-line guard-for-in
for (const key in originalObject) {
// include prototype properties
result[key] = deepClone(originalObject[key], depth + 1);
}
return result;
}
if (isObject(type, originalObject)) {
if (depth >= MAX_DEPTH) {
// Break the circular reference here
return originalObject;
}
const result = {};
// eslint-disable-next-line guard-for-in
for (const key in originalObject) {
// include prototype properties
result[key] = deepClone(originalObject[key], depth + 1);
}
return result;
}
// primitives and non-supported objects (e.g. functions) land here
return originalObject;
};
exports.deepClone = deepClone;
//# sourceMappingURL=deepClone.js.map