var toStringFunction = Function.prototype.toString; var create = Object.create; var toStringObject = Object.prototype.toString; /** * @classdesc Fallback cache for when WeakMap is not natively supported */ var LegacyCache = /** @class */ (function () { function LegacyCache() { this._keys = []; this._values = []; } LegacyCache.prototype.has = function (key) { return !!~this._keys.indexOf(key); }; LegacyCache.prototype.get = function (key) { return this._values[this._keys.indexOf(key)]; }; LegacyCache.prototype.set = function (key, value) { this._keys.push(key); this._values.push(value); }; return LegacyCache; }()); function createCacheLegacy() { return new LegacyCache(); } function createCacheModern() { return new WeakMap(); } /** * Get a new cache object to prevent circular references. */ var createCache = typeof WeakMap !== 'undefined' ? createCacheModern : createCacheLegacy; /** * Get an empty version of the object with the same prototype it has. */ function getCleanClone(prototype) { if (!prototype) { return create(null); } var Constructor = prototype.constructor; if (Constructor === Object) { return prototype === Object.prototype ? {} : create(prototype); } if (~toStringFunction.call(Constructor).indexOf('[native code]')) { try { return new Constructor(); } catch (_a) { } } return create(prototype); } function getRegExpFlagsLegacy(regExp) { var flags = ''; if (regExp.global) { flags += 'g'; } if (regExp.ignoreCase) { flags += 'i'; } if (regExp.multiline) { flags += 'm'; } if (regExp.unicode) { flags += 'u'; } if (regExp.sticky) { flags += 'y'; } return flags; } function getRegExpFlagsModern(regExp) { return regExp.flags; } /** * Get the flags to apply to the copied regexp. */ var getRegExpFlags = /test/g.flags === 'g' ? getRegExpFlagsModern : getRegExpFlagsLegacy; function getTagLegacy(value) { var type = toStringObject.call(value); return type.substring(8, type.length - 1); } function getTagModern(value) { return value[Symbol.toStringTag] || getTagLegacy(value); } /** * Get the tag of the value passed, so that the correct copier can be used. */ var getTag = typeof Symbol !== 'undefined' ? getTagModern : getTagLegacy; var defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols; var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, propertyIsEnumerable = _a.propertyIsEnumerable; var SUPPORTS_SYMBOL = typeof getOwnPropertySymbols === 'function'; function getStrictPropertiesModern(object) { return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object)); } /** * Get the properites used when copying objects strictly. This includes both keys and symbols. */ var getStrictProperties = SUPPORTS_SYMBOL ? getStrictPropertiesModern : getOwnPropertyNames; /** * Striclty copy all properties contained on the object. */ function copyOwnPropertiesStrict(value, clone, state) { var properties = getStrictProperties(value); for (var index = 0, length_1 = properties.length, property = void 0, descriptor = void 0; index < length_1; ++index) { property = properties[index]; if (property === 'callee' || property === 'caller') { continue; } descriptor = getOwnPropertyDescriptor(value, property); if (!descriptor) { // In extra edge cases where the property descriptor cannot be retrived, fall back to // the loose assignment. clone[property] = state.copier(value[property], state); continue; } // Only clone the value if actually a value, not a getter / setter. if (!descriptor.get && !descriptor.set) { descriptor.value = state.copier(descriptor.value, state); } try { defineProperty(clone, property, descriptor); } catch (error) { // Tee above can fail on node in edge cases, so fall back to the loose assignment. clone[property] = descriptor.value; } } return clone; } /** * Deeply copy the indexed values in the array. */ function copyArrayLoose(array, state) { var clone = new state.Constructor(); // set in the cache immediately to be able to reuse the object recursively state.cache.set(array, clone); for (var index = 0, length_2 = array.length; index < length_2; ++index) { clone[index] = state.copier(array[index], state); } return clone; } /** * Deeply copy the indexed values in the array, as well as any custom properties. */ function copyArrayStrict(array, state) { var clone = new state.Constructor(); // set in the cache immediately to be able to reuse the object recursively state.cache.set(array, clone); return copyOwnPropertiesStrict(array, clone, state); } /** * Copy the contents of the ArrayBuffer. */ function copyArrayBuffer(arrayBuffer, _state) { return arrayBuffer.slice(0); } /** * Create a new Blob with the contents of the original. */ function copyBlob(blob, _state) { return blob.slice(0, blob.size, blob.type); } /** * Create a new DataView with the contents of the original. */ function copyDataView(dataView, state) { return new state.Constructor(copyArrayBuffer(dataView.buffer)); } /** * Create a new Date based on the time of the original. */ function copyDate(date, state) { return new state.Constructor(date.getTime()); } /** * Deeply copy the keys and values of the original. */ function copyMapLoose(map, state) { var clone = new state.Constructor(); // set in the cache immediately to be able to reuse the object recursively state.cache.set(map, clone); map.forEach(function (value, key) { clone.set(key, state.copier(value, state)); }); return clone; } /** * Deeply copy the keys and values of the original, as well as any custom properties. */ function copyMapStrict(map, state) { return copyOwnPropertiesStrict(map, copyMapLoose(map, state), state); } function copyObjectLooseLegacy(object, state) { var clone = getCleanClone(state.prototype); // set in the cache immediately to be able to reuse the object recursively state.cache.set(object, clone); for (var key in object) { if (hasOwnProperty.call(object, key)) { clone[key] = state.copier(object[key], state); } } return clone; } function copyObjectLooseModern(object, state) { var clone = getCleanClone(state.prototype); // set in the cache immediately to be able to reuse the object recursively state.cache.set(object, clone); for (var key in object) { if (hasOwnProperty.call(object, key)) { clone[key] = state.copier(object[key], state); } } var symbols = getOwnPropertySymbols(object); for (var index = 0, length_3 = symbols.length, symbol = void 0; index < length_3; ++index) { symbol = symbols[index]; if (propertyIsEnumerable.call(object, symbol)) { clone[symbol] = state.copier(object[symbol], state); } } return clone; } /** * Deeply copy the properties (keys and symbols) and values of the original. */ var copyObjectLoose = SUPPORTS_SYMBOL ? copyObjectLooseModern : copyObjectLooseLegacy; /** * Deeply copy the properties (keys and symbols) and values of the original, as well * as any hidden or non-enumerable properties. */ function copyObjectStrict(object, state) { var clone = getCleanClone(state.prototype); // set in the cache immediately to be able to reuse the object recursively state.cache.set(object, clone); return copyOwnPropertiesStrict(object, clone, state); } /** * Create a new primitive wrapper from the value of the original. */ function copyPrimitiveWrapper(primitiveObject, state) { return new state.Constructor(primitiveObject.valueOf()); } /** * Create a new RegExp based on the value and flags of the original. */ function copyRegExp(regExp, state) { var clone = new state.Constructor(regExp.source, getRegExpFlags(regExp)); clone.lastIndex = regExp.lastIndex; return clone; } /** * Return the original value (an identity function). * * @note * THis is used for objects that cannot be copied, such as WeakMap. */ function copySelf(value, _state) { return value; } /** * Deeply copy the values of the original. */ function copySetLoose(set, state) { var clone = new state.Constructor(); // set in the cache immediately to be able to reuse the object recursively state.cache.set(set, clone); set.forEach(function (value) { clone.add(state.copier(value, state)); }); return clone; } /** * Deeply copy the values of the original, as well as any custom properties. */ function copySetStrict(set, state) { return copyOwnPropertiesStrict(set, copySetLoose(set, state), state); } var isArray = Array.isArray; var assign = Object.assign; var getPrototypeOf = Object.getPrototypeOf || (function (obj) { return obj.__proto__; }); var DEFAULT_LOOSE_OPTIONS = { array: copyArrayLoose, arrayBuffer: copyArrayBuffer, blob: copyBlob, dataView: copyDataView, date: copyDate, error: copySelf, map: copyMapLoose, object: copyObjectLoose, regExp: copyRegExp, set: copySetLoose, }; var DEFAULT_STRICT_OPTIONS = assign({}, DEFAULT_LOOSE_OPTIONS, { array: copyArrayStrict, map: copyMapStrict, object: copyObjectStrict, set: copySetStrict, }); /** * Get the copiers used for each specific object tag. */ function getTagSpecificCopiers(options) { return { Arguments: options.object, Array: options.array, ArrayBuffer: options.arrayBuffer, Blob: options.blob, Boolean: copyPrimitiveWrapper, DataView: options.dataView, Date: options.date, Error: options.error, Float32Array: options.arrayBuffer, Float64Array: options.arrayBuffer, Int8Array: options.arrayBuffer, Int16Array: options.arrayBuffer, Int32Array: options.arrayBuffer, Map: options.map, Number: copyPrimitiveWrapper, Object: options.object, Promise: copySelf, RegExp: options.regExp, Set: options.set, String: copyPrimitiveWrapper, WeakMap: copySelf, WeakSet: copySelf, Uint8Array: options.arrayBuffer, Uint8ClampedArray: options.arrayBuffer, Uint16Array: options.arrayBuffer, Uint32Array: options.arrayBuffer, Uint64Array: options.arrayBuffer, }; } /** * Create a custom copier based on the object-specific copy methods passed. */ function createCopier(options) { var normalizedOptions = assign({}, DEFAULT_LOOSE_OPTIONS, options); var tagSpecificCopiers = getTagSpecificCopiers(normalizedOptions); var array = tagSpecificCopiers.Array, object = tagSpecificCopiers.Object; function copier(value, state) { state.prototype = state.Constructor = undefined; if (!value || typeof value !== 'object') { return value; } if (state.cache.has(value)) { return state.cache.get(value); } state.prototype = getPrototypeOf(value); state.Constructor = state.prototype && state.prototype.constructor; // plain objects if (!state.Constructor || state.Constructor === Object) { return object(value, state); } // arrays if (isArray(value)) { return array(value, state); } var tagSpecificCopier = tagSpecificCopiers[getTag(value)]; if (tagSpecificCopier) { return tagSpecificCopier(value, state); } return typeof value.then === 'function' ? value : object(value, state); } return function copy(value) { return copier(value, { Constructor: undefined, cache: createCache(), copier: copier, prototype: undefined, }); }; } /** * Create a custom copier based on the object-specific copy methods passed, defaulting to the * same internals as `copyStrict`. */ function createStrictCopier(options) { return createCopier(assign({}, DEFAULT_STRICT_OPTIONS, options)); } /** * Copy an value deeply as much as possible, where strict recreation of object properties * are maintained. All properties (including non-enumerable ones) are copied with their * original property descriptors on both objects and arrays. */ var copyStrict = createStrictCopier({}); /** * Copy an value deeply as much as possible. */ var index = createCopier({}); export { copyStrict, createCopier, createStrictCopier, index as default }; //# sourceMappingURL=index.mjs.map