Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fast-copy

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-copy - npm Package Compare versions

Comparing version 1.2.4 to 2.0.0

9

CHANGELOG.md
# fast-copy CHANGELOG
## 2.0.0
- Rewrite in TypeScript
- Add strict mode (for more accurate and thorough copying, at the expense of less performance)
#### BREAKING CHANGES
- Second parameter is now an object of [options](README.md#options)
## 1.2.4

@@ -4,0 +13,0 @@

563

dist/fast-copy.cjs.js
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var create = Object.create,
getSymbols = Object.getOwnPropertySymbols,
getPrototypeOf = Object.getPrototypeOf;
var _Object$prototype = Object.prototype,
hasOwnProperty = _Object$prototype.hasOwnProperty,
propertyIsEnumerable = _Object$prototype.propertyIsEnumerable;
var toStringFunction = Function.prototype.toString;
var create = Object.create, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols, getPrototypeOf = Object.getPrototypeOf;
var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, propertyIsEnumerable = _a.propertyIsEnumerable;
/**
* @constant {Object} SUPPORTS cache of values supported
* @enum
*
* @const {Object} SUPPORTS
*
* @property {boolean} SYMBOL_PROPERTIES are symbol properties supported
* @property {boolean} WEAKSET is WeakSet supported
*/
var SUPPORTS = {
FLAGS: typeof /foo/g.flags === 'string',
SYMBOL_PROPERTIES: typeof global.Object.getOwnPropertySymbols === 'function',
WEAKSET: typeof global.WeakSet === 'function'
SYMBOL_PROPERTIES: typeof getOwnPropertySymbols === 'function',
WEAKSET: typeof WeakSet === 'function',
};
/**
* @function getNewCache
* @function createCache
*

@@ -26,343 +24,286 @@ * @description

*
* @returns {Object|Weakset} the new cache object
* @returns the new cache object
*/
var getNewCache = function getNewCache() {
return SUPPORTS.WEAKSET ? new WeakSet() : create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
var createCache = function () {
if (SUPPORTS.WEAKSET) {
return new WeakSet();
}
});
var object = create({
add: function (value) { return object._values.push(value); },
has: function (value) { return !!~object._values.indexOf(value); },
});
object._values = [];
return object;
};
/**
* @function getObjectToCopy
* @function getCleanClone
*
* @description
* get the object to copy, including appropriate prototype
* get an empty version of the object with the same prototype it has
*
* @param {Object} object the object to copy
* @param {function} RealmObject the realm-specific Object constructor
* @param {boolean} isPlainObject is the object a plain object
* @returns {Object} an empty version of the object to copy
* @param object the object to build a clean clone from
* @param realm the realm the object resides in
* @returns the empty cloned object
*/
var getObjectToCopy = function getObjectToCopy(object, RealmObject, isPlainObject) {
if (isPlainObject) {
var getCleanClone = function (object, realm) {
if (!object.constructor) {
return create(null);
}
var prototype = object.__proto__ || getPrototypeOf(object);
return prototype === RealmObject.prototype ? {} : create(prototype);
}
return object.constructor ? new object.constructor() : create(null);
if (object.constructor === realm.Object) {
return prototype === realm.Object.prototype ? {} : create(prototype);
}
if (~toStringFunction.call(object.constructor).indexOf('[native code]')) {
return new object.constructor();
}
return create(prototype);
};
/**
* @function getRegExpFlags
* @function getObjectCloneLoose
*
* @description
* get the flags to apply to the copied regexp
* get a copy of the object based on loose rules, meaning all enumerable keys
* and symbols are copied, but property descriptors are not considered
*
* @param {RegExp} regExp the regexp to get the flags of
* @returns {string} the flags for the regexp
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var getRegExpFlags = function getRegExpFlags(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;
var getObjectCloneLoose = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
clone[key] = handleCopy(object[key], cache);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getOwnPropertySymbols(object);
if (symbols.length) {
for (var index = 0, symbol = void 0; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
clone[symbol] = handleCopy(object[symbol], cache);
}
}
}
}
return clone;
};
/**
* @function isObjectCopyable
* @function getObjectCloneStrict
*
* @description
* is the object able to be copied
* get a copy of the object based on strict rules, meaning all keys and symbols
* are copied based on the original property descriptors
*
* @param {any} object the object to test
* @param {Object|Weakset} cache the cache of copied values
* @returns {boolean} can the object be copied
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var isObjectCopyable = function isObjectCopyable(object, cache) {
return typeof object === 'object' && object !== null && !cache.has(object);
var getObjectCloneStrict = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
var properties = SUPPORTS.SYMBOL_PROPERTIES
? [].concat(getOwnPropertyNames(object), getOwnPropertySymbols(object))
: getOwnPropertyNames(object);
if (properties.length) {
for (var index = 0, property = void 0, descriptor = void 0; index < properties.length; index++) {
property = properties[index];
if (property !== 'callee' && property !== 'caller') {
descriptor = getOwnPropertyDescriptor(object, property);
descriptor.value = handleCopy(object[property], cache);
defineProperty(clone, property, descriptor);
}
}
}
return clone;
};
/**
* @function shouldObjectBeCopied
* @function getRegExpFlags
*
* @description
* should the object be copied
* get the flags to apply to the copied regexp
*
* @param {any} object the object to test
* @param {any} realm the realm to check instanceof in
* @returns {boolean} should the object be copied
* @param regExp the regexp to get the flags of
* @returns the flags for the regexp
*/
var shouldObjectBeCopied = function shouldObjectBeCopied(object, realm) {
return typeof object.then !== 'function' && !(object instanceof realm.Error) && !(realm.WeakMap && object instanceof realm.WeakMap) && !(realm.WeakSet && object instanceof realm.WeakSet);
var getRegExpFlags = function (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 copyArray
*
* @description
* copy the array, deeply copying the values
*
* @param {Array<any>} array the array to copy
* @param {function} copy the function to copy values
* @param {any} realm the realm to check instanceof in
* @returns {Array<any>} the copied array
*/
var copyArray = function copyArray(array, copy, realm) {
var newArray = new array.constructor();
for (var index = 0; index < array.length; index++) {
newArray[index] = copy(array[index], realm);
}
return newArray;
};
// utils
var isArray = Array.isArray;
var GLOBAL_THIS = (function () {
if (typeof self !== 'undefined') {
return self;
}
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
if (console && console.error) {
console.error('Unable to locate global object, returning "this".');
}
})();
/**
* @function copyArrayBuffer
* @function copy
*
* @description
* copy the arrayBuffer, deeply copying the values
* copy an object deeply as much as possible
*
* @param {ArrayBuffer} arrayBuffer the arrayBuffer to copy
* @returns {ArrayBuffer} the copied bufarrayBufferfer
*/
var copyArrayBuffer = function copyArrayBuffer(arrayBuffer) {
return arrayBuffer.slice(0);
};
/**
* @function copyBuffer
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* @description
* copy the buffer, deeply copying the values
* The object is compared to the global constructors in the `realm` provided,
* and the native constructor is always used to ensure that extensions of native
* objects (allows in ES2015+) are maintained.
*
* @param {Buffer} buffer the buffer to copy
* @param {any} realm the realm to check instanceof in
* @returns {Buffer} the copied buffer
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.isStrict] should the copy be strict
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyBuffer = function copyBuffer(buffer, realm) {
var RealmBuffer = realm.Buffer;
var newBuffer = RealmBuffer.allocUnsafe ? RealmBuffer.allocUnsafe(buffer.length) : new RealmBuffer(buffer.length);
buffer.copy(newBuffer);
return newBuffer;
};
/**
* @function copyMap
*
* @description
* copy the map values into a new map
*
* @param {Map} map the map to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Map} the copied map
*/
var copyMap = function copyMap(map, copy, realm) {
var newMap = new map.constructor();
map.forEach(function (value, key) {
return newMap.set(key, copy(value, realm));
});
return newMap;
};
/**
* @function copySet
*
* @description
* copy the set values into a new set
*
* @param {Set} set the set to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Set} the copied set
*/
var copySet = function copySet(set, copy, realm) {
var newSet = new set.constructor();
set.forEach(function (value) {
return newSet.add(copy(value, realm));
});
return newSet;
};
/**
* @function copyObject
*
* @description
* copy the object values into a new object of the same type
*
* @param {Object} object the object to copy
* @param {function} copy the copy method
* @param {any} realm the realm to check instanceof in
* @param {boolean} isPlainObject is the object to copy a plain object
* @returns {Object} the copied object
*/
var copyObject = function copyObject(object, copy, realm, isPlainObject) {
var newObject = getObjectToCopy(object, realm.Object, isPlainObject);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
newObject[key] = copy(object[key], realm);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getSymbols(object);
if (symbols.length) {
for (var index = 0, symbol; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
newObject[symbol] = copy(object[symbol], realm);
function copy(object, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.isStrict, isStrict = _c === void 0 ? false : _c, _d = _b.realm, realm = _d === void 0 ? GLOBAL_THIS : _d;
var RealmArrayBuffer = realm.ArrayBuffer, RealmBuffer = realm.Buffer, RealmMap = realm.Map, RealmSet = realm.Set, RealmWeakMap = realm.WeakMap, RealmWeakSet = realm.WeakSet;
var getObjectClone = isStrict
? getObjectCloneStrict
: getObjectCloneLoose;
/**
* @function handleCopy
*
* @description
* copy the object recursively based on its type
*
* @param object the object to copy
* @returns the copied object
*/
var handleCopy = function (object, cache) {
if (!object || typeof object !== 'object' || cache.has(object)) {
return object;
}
}
}
}
return newObject;
};
var Constructor = object.constructor;
// plain objects
if (Constructor === realm.Object) {
cache.add(object);
return getObjectClone(object, realm, handleCopy, cache);
}
var clone;
// arrays
if (isArray(object)) {
cache.add(object);
// if strict, include non-standard properties
if (isStrict) {
return getObjectCloneStrict(object, realm, handleCopy, cache);
}
clone = new Constructor();
for (var index = 0; index < object.length; index++) {
clone[index] = handleCopy(object[index], cache);
}
return clone;
}
// dates
if (object instanceof realm.Date) {
return new Constructor(object.getTime());
}
// regexps
if (object instanceof realm.RegExp) {
clone = new Constructor(object.source, object.flags || getRegExpFlags(object));
clone.lastIndex = object.lastIndex;
return clone;
}
// maps
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value, key) {
clone.set(key, handleCopy(value, cache));
});
return clone;
}
// sets
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value) {
clone.add(handleCopy(value, cache));
});
return clone;
}
// buffers (node-only)
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
clone = RealmBuffer.allocUnsafe
? RealmBuffer.allocUnsafe(object.length)
: new Constructor(object.length);
object.copy(clone);
return clone;
}
// arraybuffers / dataviews
if (RealmArrayBuffer) {
// dataviews
if (RealmArrayBuffer.isView(object)) {
return new Constructor(object.buffer.slice(0));
}
// arraybuffers
if (object instanceof RealmArrayBuffer) {
return object.slice(0);
}
}
// if the object cannot / should not be cloned, don't
if (
// promise-like
typeof object.then === 'function' ||
// errors
object instanceof Error ||
// weakmaps
(RealmWeakMap && object instanceof RealmWeakMap) ||
// weaksets
(RealmWeakSet && object instanceof RealmWeakSet)) {
return object;
}
cache.add(object);
// assume anything left is a custom constructor
return getObjectClone(object, realm, handleCopy, cache);
};
return handleCopy(object, createCache());
}
/**
* @function copyRegExp
* @function strictCopy
*
* @description
* copy the RegExp to a new RegExp with the same properties
* copy the object with `strict` option pre-applied
*
* @param {RegExp} regExp the RegExp to copy
* @param {function} RealmRegExp the realm-specific RegExp constructor
* @returns {RegExp} the copied RegExp
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyRegExp = function copyRegExp(regExp, RealmRegExp) {
var newRegExp = new RealmRegExp(regExp.source, SUPPORTS.FLAGS ? regExp.flags : getRegExpFlags(regExp));
newRegExp.lastIndex = regExp.lastIndex;
return newRegExp;
copy.strict = function strictCopy(object, options) {
return copy(object, {
isStrict: true,
realm: options ? options.realm : void 0,
});
};
/**
* @function copyTypedArray
*
* @description
* copy the typedArray, deeply copying the values
*
* @param {TypedArray} typedArray the typedArray to copy
* @returns {TypedArray} the copied typedArray
*/
var copyTypedArray = function copyTypedArray(typedArray) {
return new typedArray.constructor(copyArrayBuffer(typedArray.buffer));
};
// utils
var isArray = Array.isArray;
/**
* @function copy
*
* @description
* deeply copy the object to a new object of the same type
*
* @param {any} object the object to copy
* @param {any} [realm=global] the realm to check instanceof in
* @returns {any} the copied object
*/
function copy(object, realm) {
if (realm === void 0) {
realm = global;
}
var _realm = realm,
RealmArrayBuffer = _realm.ArrayBuffer,
RealmBuffer = _realm.Buffer,
RealmDate = _realm.Date,
RealmMap = _realm.Map,
RealmObject = _realm.Object,
RealmRegExp = _realm.RegExp,
RealmSet = _realm.Set;
var cache = getNewCache();
var handleCopy = function handleCopy(object) {
if (!isObjectCopyable(object, cache)) {
return object;
}
if (isArray(object)) {
cache.add(object);
return copyArray(object, handleCopy, realm);
}
if (object.constructor === RealmObject) {
cache.add(object);
return copyObject(object, handleCopy, realm, true);
}
if (object instanceof RealmDate) {
return new RealmDate(object.getTime());
}
if (object instanceof RealmRegExp) {
return copyRegExp(object, RealmRegExp);
}
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
return copyMap(object, handleCopy, realm);
}
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
return copySet(object, handleCopy, realm);
}
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
return copyBuffer(object, realm);
}
if (RealmArrayBuffer) {
if (RealmArrayBuffer.isView(object)) {
return copyTypedArray(object);
}
if (object instanceof RealmArrayBuffer) {
return copyArrayBuffer(object);
}
}
if (shouldObjectBeCopied(object, realm)) {
cache.add(object);
return copyObject(object, handleCopy, realm);
}
return object;
};
return handleCopy(object);
}
exports.default = copy;
module.exports = copy;
//# sourceMappingURL=fast-copy.cjs.js.map

@@ -1,18 +0,18 @@

var create = Object.create,
getSymbols = Object.getOwnPropertySymbols,
getPrototypeOf = Object.getPrototypeOf;
var _Object$prototype = Object.prototype,
hasOwnProperty = _Object$prototype.hasOwnProperty,
propertyIsEnumerable = _Object$prototype.propertyIsEnumerable;
var toStringFunction = Function.prototype.toString;
var create = Object.create, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols, getPrototypeOf = Object.getPrototypeOf;
var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, propertyIsEnumerable = _a.propertyIsEnumerable;
/**
* @constant {Object} SUPPORTS cache of values supported
* @enum
*
* @const {Object} SUPPORTS
*
* @property {boolean} SYMBOL_PROPERTIES are symbol properties supported
* @property {boolean} WEAKSET is WeakSet supported
*/
var SUPPORTS = {
FLAGS: typeof /foo/g.flags === 'string',
SYMBOL_PROPERTIES: typeof global.Object.getOwnPropertySymbols === 'function',
WEAKSET: typeof global.WeakSet === 'function'
SYMBOL_PROPERTIES: typeof getOwnPropertySymbols === 'function',
WEAKSET: typeof WeakSet === 'function',
};
/**
* @function getNewCache
* @function createCache
*

@@ -22,343 +22,286 @@ * @description

*
* @returns {Object|Weakset} the new cache object
* @returns the new cache object
*/
var getNewCache = function getNewCache() {
return SUPPORTS.WEAKSET ? new WeakSet() : create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
var createCache = function () {
if (SUPPORTS.WEAKSET) {
return new WeakSet();
}
});
var object = create({
add: function (value) { return object._values.push(value); },
has: function (value) { return !!~object._values.indexOf(value); },
});
object._values = [];
return object;
};
/**
* @function getObjectToCopy
* @function getCleanClone
*
* @description
* get the object to copy, including appropriate prototype
* get an empty version of the object with the same prototype it has
*
* @param {Object} object the object to copy
* @param {function} RealmObject the realm-specific Object constructor
* @param {boolean} isPlainObject is the object a plain object
* @returns {Object} an empty version of the object to copy
* @param object the object to build a clean clone from
* @param realm the realm the object resides in
* @returns the empty cloned object
*/
var getObjectToCopy = function getObjectToCopy(object, RealmObject, isPlainObject) {
if (isPlainObject) {
var getCleanClone = function (object, realm) {
if (!object.constructor) {
return create(null);
}
var prototype = object.__proto__ || getPrototypeOf(object);
return prototype === RealmObject.prototype ? {} : create(prototype);
}
return object.constructor ? new object.constructor() : create(null);
if (object.constructor === realm.Object) {
return prototype === realm.Object.prototype ? {} : create(prototype);
}
if (~toStringFunction.call(object.constructor).indexOf('[native code]')) {
return new object.constructor();
}
return create(prototype);
};
/**
* @function getRegExpFlags
* @function getObjectCloneLoose
*
* @description
* get the flags to apply to the copied regexp
* get a copy of the object based on loose rules, meaning all enumerable keys
* and symbols are copied, but property descriptors are not considered
*
* @param {RegExp} regExp the regexp to get the flags of
* @returns {string} the flags for the regexp
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var getRegExpFlags = function getRegExpFlags(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;
var getObjectCloneLoose = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
clone[key] = handleCopy(object[key], cache);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getOwnPropertySymbols(object);
if (symbols.length) {
for (var index = 0, symbol = void 0; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
clone[symbol] = handleCopy(object[symbol], cache);
}
}
}
}
return clone;
};
/**
* @function isObjectCopyable
* @function getObjectCloneStrict
*
* @description
* is the object able to be copied
* get a copy of the object based on strict rules, meaning all keys and symbols
* are copied based on the original property descriptors
*
* @param {any} object the object to test
* @param {Object|Weakset} cache the cache of copied values
* @returns {boolean} can the object be copied
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var isObjectCopyable = function isObjectCopyable(object, cache) {
return typeof object === 'object' && object !== null && !cache.has(object);
var getObjectCloneStrict = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
var properties = SUPPORTS.SYMBOL_PROPERTIES
? [].concat(getOwnPropertyNames(object), getOwnPropertySymbols(object))
: getOwnPropertyNames(object);
if (properties.length) {
for (var index = 0, property = void 0, descriptor = void 0; index < properties.length; index++) {
property = properties[index];
if (property !== 'callee' && property !== 'caller') {
descriptor = getOwnPropertyDescriptor(object, property);
descriptor.value = handleCopy(object[property], cache);
defineProperty(clone, property, descriptor);
}
}
}
return clone;
};
/**
* @function shouldObjectBeCopied
* @function getRegExpFlags
*
* @description
* should the object be copied
* get the flags to apply to the copied regexp
*
* @param {any} object the object to test
* @param {any} realm the realm to check instanceof in
* @returns {boolean} should the object be copied
* @param regExp the regexp to get the flags of
* @returns the flags for the regexp
*/
var shouldObjectBeCopied = function shouldObjectBeCopied(object, realm) {
return typeof object.then !== 'function' && !(object instanceof realm.Error) && !(realm.WeakMap && object instanceof realm.WeakMap) && !(realm.WeakSet && object instanceof realm.WeakSet);
var getRegExpFlags = function (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 copyArray
*
* @description
* copy the array, deeply copying the values
*
* @param {Array<any>} array the array to copy
* @param {function} copy the function to copy values
* @param {any} realm the realm to check instanceof in
* @returns {Array<any>} the copied array
*/
var copyArray = function copyArray(array, copy, realm) {
var newArray = new array.constructor();
for (var index = 0; index < array.length; index++) {
newArray[index] = copy(array[index], realm);
}
return newArray;
};
// utils
var isArray = Array.isArray;
var GLOBAL_THIS = (function () {
if (typeof self !== 'undefined') {
return self;
}
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
if (console && console.error) {
console.error('Unable to locate global object, returning "this".');
}
})();
/**
* @function copyArrayBuffer
* @function copy
*
* @description
* copy the arrayBuffer, deeply copying the values
* copy an object deeply as much as possible
*
* @param {ArrayBuffer} arrayBuffer the arrayBuffer to copy
* @returns {ArrayBuffer} the copied bufarrayBufferfer
*/
var copyArrayBuffer = function copyArrayBuffer(arrayBuffer) {
return arrayBuffer.slice(0);
};
/**
* @function copyBuffer
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* @description
* copy the buffer, deeply copying the values
* The object is compared to the global constructors in the `realm` provided,
* and the native constructor is always used to ensure that extensions of native
* objects (allows in ES2015+) are maintained.
*
* @param {Buffer} buffer the buffer to copy
* @param {any} realm the realm to check instanceof in
* @returns {Buffer} the copied buffer
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.isStrict] should the copy be strict
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyBuffer = function copyBuffer(buffer, realm) {
var RealmBuffer = realm.Buffer;
var newBuffer = RealmBuffer.allocUnsafe ? RealmBuffer.allocUnsafe(buffer.length) : new RealmBuffer(buffer.length);
buffer.copy(newBuffer);
return newBuffer;
};
/**
* @function copyMap
*
* @description
* copy the map values into a new map
*
* @param {Map} map the map to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Map} the copied map
*/
var copyMap = function copyMap(map, copy, realm) {
var newMap = new map.constructor();
map.forEach(function (value, key) {
return newMap.set(key, copy(value, realm));
});
return newMap;
};
/**
* @function copySet
*
* @description
* copy the set values into a new set
*
* @param {Set} set the set to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Set} the copied set
*/
var copySet = function copySet(set, copy, realm) {
var newSet = new set.constructor();
set.forEach(function (value) {
return newSet.add(copy(value, realm));
});
return newSet;
};
/**
* @function copyObject
*
* @description
* copy the object values into a new object of the same type
*
* @param {Object} object the object to copy
* @param {function} copy the copy method
* @param {any} realm the realm to check instanceof in
* @param {boolean} isPlainObject is the object to copy a plain object
* @returns {Object} the copied object
*/
var copyObject = function copyObject(object, copy, realm, isPlainObject) {
var newObject = getObjectToCopy(object, realm.Object, isPlainObject);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
newObject[key] = copy(object[key], realm);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getSymbols(object);
if (symbols.length) {
for (var index = 0, symbol; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
newObject[symbol] = copy(object[symbol], realm);
function copy(object, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.isStrict, isStrict = _c === void 0 ? false : _c, _d = _b.realm, realm = _d === void 0 ? GLOBAL_THIS : _d;
var RealmArrayBuffer = realm.ArrayBuffer, RealmBuffer = realm.Buffer, RealmMap = realm.Map, RealmSet = realm.Set, RealmWeakMap = realm.WeakMap, RealmWeakSet = realm.WeakSet;
var getObjectClone = isStrict
? getObjectCloneStrict
: getObjectCloneLoose;
/**
* @function handleCopy
*
* @description
* copy the object recursively based on its type
*
* @param object the object to copy
* @returns the copied object
*/
var handleCopy = function (object, cache) {
if (!object || typeof object !== 'object' || cache.has(object)) {
return object;
}
}
}
}
return newObject;
};
var Constructor = object.constructor;
// plain objects
if (Constructor === realm.Object) {
cache.add(object);
return getObjectClone(object, realm, handleCopy, cache);
}
var clone;
// arrays
if (isArray(object)) {
cache.add(object);
// if strict, include non-standard properties
if (isStrict) {
return getObjectCloneStrict(object, realm, handleCopy, cache);
}
clone = new Constructor();
for (var index = 0; index < object.length; index++) {
clone[index] = handleCopy(object[index], cache);
}
return clone;
}
// dates
if (object instanceof realm.Date) {
return new Constructor(object.getTime());
}
// regexps
if (object instanceof realm.RegExp) {
clone = new Constructor(object.source, object.flags || getRegExpFlags(object));
clone.lastIndex = object.lastIndex;
return clone;
}
// maps
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value, key) {
clone.set(key, handleCopy(value, cache));
});
return clone;
}
// sets
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value) {
clone.add(handleCopy(value, cache));
});
return clone;
}
// buffers (node-only)
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
clone = RealmBuffer.allocUnsafe
? RealmBuffer.allocUnsafe(object.length)
: new Constructor(object.length);
object.copy(clone);
return clone;
}
// arraybuffers / dataviews
if (RealmArrayBuffer) {
// dataviews
if (RealmArrayBuffer.isView(object)) {
return new Constructor(object.buffer.slice(0));
}
// arraybuffers
if (object instanceof RealmArrayBuffer) {
return object.slice(0);
}
}
// if the object cannot / should not be cloned, don't
if (
// promise-like
typeof object.then === 'function' ||
// errors
object instanceof Error ||
// weakmaps
(RealmWeakMap && object instanceof RealmWeakMap) ||
// weaksets
(RealmWeakSet && object instanceof RealmWeakSet)) {
return object;
}
cache.add(object);
// assume anything left is a custom constructor
return getObjectClone(object, realm, handleCopy, cache);
};
return handleCopy(object, createCache());
}
/**
* @function copyRegExp
* @function strictCopy
*
* @description
* copy the RegExp to a new RegExp with the same properties
* copy the object with `strict` option pre-applied
*
* @param {RegExp} regExp the RegExp to copy
* @param {function} RealmRegExp the realm-specific RegExp constructor
* @returns {RegExp} the copied RegExp
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyRegExp = function copyRegExp(regExp, RealmRegExp) {
var newRegExp = new RealmRegExp(regExp.source, SUPPORTS.FLAGS ? regExp.flags : getRegExpFlags(regExp));
newRegExp.lastIndex = regExp.lastIndex;
return newRegExp;
copy.strict = function strictCopy(object, options) {
return copy(object, {
isStrict: true,
realm: options ? options.realm : void 0,
});
};
/**
* @function copyTypedArray
*
* @description
* copy the typedArray, deeply copying the values
*
* @param {TypedArray} typedArray the typedArray to copy
* @returns {TypedArray} the copied typedArray
*/
var copyTypedArray = function copyTypedArray(typedArray) {
return new typedArray.constructor(copyArrayBuffer(typedArray.buffer));
};
// utils
var isArray = Array.isArray;
/**
* @function copy
*
* @description
* deeply copy the object to a new object of the same type
*
* @param {any} object the object to copy
* @param {any} [realm=global] the realm to check instanceof in
* @returns {any} the copied object
*/
function copy(object, realm) {
if (realm === void 0) {
realm = global;
}
var _realm = realm,
RealmArrayBuffer = _realm.ArrayBuffer,
RealmBuffer = _realm.Buffer,
RealmDate = _realm.Date,
RealmMap = _realm.Map,
RealmObject = _realm.Object,
RealmRegExp = _realm.RegExp,
RealmSet = _realm.Set;
var cache = getNewCache();
var handleCopy = function handleCopy(object) {
if (!isObjectCopyable(object, cache)) {
return object;
}
if (isArray(object)) {
cache.add(object);
return copyArray(object, handleCopy, realm);
}
if (object.constructor === RealmObject) {
cache.add(object);
return copyObject(object, handleCopy, realm, true);
}
if (object instanceof RealmDate) {
return new RealmDate(object.getTime());
}
if (object instanceof RealmRegExp) {
return copyRegExp(object, RealmRegExp);
}
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
return copyMap(object, handleCopy, realm);
}
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
return copySet(object, handleCopy, realm);
}
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
return copyBuffer(object, realm);
}
if (RealmArrayBuffer) {
if (RealmArrayBuffer.isView(object)) {
return copyTypedArray(object);
}
if (object instanceof RealmArrayBuffer) {
return copyArrayBuffer(object);
}
}
if (shouldObjectBeCopied(object, realm)) {
cache.add(object);
return copyObject(object, handleCopy, realm);
}
return object;
};
return handleCopy(object);
}
export default copy;
//# sourceMappingURL=fast-copy.esm.js.map
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global['fast-copy'] = {}));
}(this, function (exports) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global['fast-copy'] = factory());
}(this, function () { 'use strict';
var create = Object.create,
getSymbols = Object.getOwnPropertySymbols,
getPrototypeOf = Object.getPrototypeOf;
var _Object$prototype = Object.prototype,
hasOwnProperty = _Object$prototype.hasOwnProperty,
propertyIsEnumerable = _Object$prototype.propertyIsEnumerable;
var toStringFunction = Function.prototype.toString;
var create = Object.create, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols, getPrototypeOf = Object.getPrototypeOf;
var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, propertyIsEnumerable = _a.propertyIsEnumerable;
/**
* @constant {Object} SUPPORTS cache of values supported
* @enum
*
* @const {Object} SUPPORTS
*
* @property {boolean} SYMBOL_PROPERTIES are symbol properties supported
* @property {boolean} WEAKSET is WeakSet supported
*/
var SUPPORTS = {
FLAGS: typeof /foo/g.flags === 'string',
SYMBOL_PROPERTIES: typeof global.Object.getOwnPropertySymbols === 'function',
WEAKSET: typeof global.WeakSet === 'function'
SYMBOL_PROPERTIES: typeof getOwnPropertySymbols === 'function',
WEAKSET: typeof WeakSet === 'function',
};
/**
* @function getNewCache
* @function createCache
*

@@ -28,347 +28,288 @@ * @description

*
* @returns {Object|Weakset} the new cache object
* @returns the new cache object
*/
var getNewCache = function getNewCache() {
return SUPPORTS.WEAKSET ? new WeakSet() : create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
var createCache = function () {
if (SUPPORTS.WEAKSET) {
return new WeakSet();
}
});
var object = create({
add: function (value) { return object._values.push(value); },
has: function (value) { return !!~object._values.indexOf(value); },
});
object._values = [];
return object;
};
/**
* @function getObjectToCopy
* @function getCleanClone
*
* @description
* get the object to copy, including appropriate prototype
* get an empty version of the object with the same prototype it has
*
* @param {Object} object the object to copy
* @param {function} RealmObject the realm-specific Object constructor
* @param {boolean} isPlainObject is the object a plain object
* @returns {Object} an empty version of the object to copy
* @param object the object to build a clean clone from
* @param realm the realm the object resides in
* @returns the empty cloned object
*/
var getObjectToCopy = function getObjectToCopy(object, RealmObject, isPlainObject) {
if (isPlainObject) {
var getCleanClone = function (object, realm) {
if (!object.constructor) {
return create(null);
}
var prototype = object.__proto__ || getPrototypeOf(object);
return prototype === RealmObject.prototype ? {} : create(prototype);
}
return object.constructor ? new object.constructor() : create(null);
if (object.constructor === realm.Object) {
return prototype === realm.Object.prototype ? {} : create(prototype);
}
if (~toStringFunction.call(object.constructor).indexOf('[native code]')) {
return new object.constructor();
}
return create(prototype);
};
/**
* @function getRegExpFlags
* @function getObjectCloneLoose
*
* @description
* get the flags to apply to the copied regexp
* get a copy of the object based on loose rules, meaning all enumerable keys
* and symbols are copied, but property descriptors are not considered
*
* @param {RegExp} regExp the regexp to get the flags of
* @returns {string} the flags for the regexp
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var getRegExpFlags = function getRegExpFlags(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;
var getObjectCloneLoose = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
clone[key] = handleCopy(object[key], cache);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getOwnPropertySymbols(object);
if (symbols.length) {
for (var index = 0, symbol = void 0; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
clone[symbol] = handleCopy(object[symbol], cache);
}
}
}
}
return clone;
};
/**
* @function isObjectCopyable
* @function getObjectCloneStrict
*
* @description
* is the object able to be copied
* get a copy of the object based on strict rules, meaning all keys and symbols
* are copied based on the original property descriptors
*
* @param {any} object the object to test
* @param {Object|Weakset} cache the cache of copied values
* @returns {boolean} can the object be copied
* @param object the object to clone
* @param realm the realm the object resides in
* @param handleCopy the function that handles copying the object
* @returns the copied object
*/
var isObjectCopyable = function isObjectCopyable(object, cache) {
return typeof object === 'object' && object !== null && !cache.has(object);
var getObjectCloneStrict = function (object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
var properties = SUPPORTS.SYMBOL_PROPERTIES
? [].concat(getOwnPropertyNames(object), getOwnPropertySymbols(object))
: getOwnPropertyNames(object);
if (properties.length) {
for (var index = 0, property = void 0, descriptor = void 0; index < properties.length; index++) {
property = properties[index];
if (property !== 'callee' && property !== 'caller') {
descriptor = getOwnPropertyDescriptor(object, property);
descriptor.value = handleCopy(object[property], cache);
defineProperty(clone, property, descriptor);
}
}
}
return clone;
};
/**
* @function shouldObjectBeCopied
* @function getRegExpFlags
*
* @description
* should the object be copied
* get the flags to apply to the copied regexp
*
* @param {any} object the object to test
* @param {any} realm the realm to check instanceof in
* @returns {boolean} should the object be copied
* @param regExp the regexp to get the flags of
* @returns the flags for the regexp
*/
var shouldObjectBeCopied = function shouldObjectBeCopied(object, realm) {
return typeof object.then !== 'function' && !(object instanceof realm.Error) && !(realm.WeakMap && object instanceof realm.WeakMap) && !(realm.WeakSet && object instanceof realm.WeakSet);
var getRegExpFlags = function (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 copyArray
*
* @description
* copy the array, deeply copying the values
*
* @param {Array<any>} array the array to copy
* @param {function} copy the function to copy values
* @param {any} realm the realm to check instanceof in
* @returns {Array<any>} the copied array
*/
var copyArray = function copyArray(array, copy, realm) {
var newArray = new array.constructor();
for (var index = 0; index < array.length; index++) {
newArray[index] = copy(array[index], realm);
}
return newArray;
};
// utils
var isArray = Array.isArray;
var GLOBAL_THIS = (function () {
if (typeof self !== 'undefined') {
return self;
}
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
if (console && console.error) {
console.error('Unable to locate global object, returning "this".');
}
})();
/**
* @function copyArrayBuffer
* @function copy
*
* @description
* copy the arrayBuffer, deeply copying the values
* copy an object deeply as much as possible
*
* @param {ArrayBuffer} arrayBuffer the arrayBuffer to copy
* @returns {ArrayBuffer} the copied bufarrayBufferfer
*/
var copyArrayBuffer = function copyArrayBuffer(arrayBuffer) {
return arrayBuffer.slice(0);
};
/**
* @function copyBuffer
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* @description
* copy the buffer, deeply copying the values
* The object is compared to the global constructors in the `realm` provided,
* and the native constructor is always used to ensure that extensions of native
* objects (allows in ES2015+) are maintained.
*
* @param {Buffer} buffer the buffer to copy
* @param {any} realm the realm to check instanceof in
* @returns {Buffer} the copied buffer
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.isStrict] should the copy be strict
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyBuffer = function copyBuffer(buffer, realm) {
var RealmBuffer = realm.Buffer;
var newBuffer = RealmBuffer.allocUnsafe ? RealmBuffer.allocUnsafe(buffer.length) : new RealmBuffer(buffer.length);
buffer.copy(newBuffer);
return newBuffer;
};
/**
* @function copyMap
*
* @description
* copy the map values into a new map
*
* @param {Map} map the map to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Map} the copied map
*/
var copyMap = function copyMap(map, copy, realm) {
var newMap = new map.constructor();
map.forEach(function (value, key) {
return newMap.set(key, copy(value, realm));
});
return newMap;
};
/**
* @function copySet
*
* @description
* copy the set values into a new set
*
* @param {Set} set the set to copy
* @param {function} copy the copy object method
* @param {Object} realm the realm the constructor resides in
* @returns {Set} the copied set
*/
var copySet = function copySet(set, copy, realm) {
var newSet = new set.constructor();
set.forEach(function (value) {
return newSet.add(copy(value, realm));
});
return newSet;
};
/**
* @function copyObject
*
* @description
* copy the object values into a new object of the same type
*
* @param {Object} object the object to copy
* @param {function} copy the copy method
* @param {any} realm the realm to check instanceof in
* @param {boolean} isPlainObject is the object to copy a plain object
* @returns {Object} the copied object
*/
var copyObject = function copyObject(object, copy, realm, isPlainObject) {
var newObject = getObjectToCopy(object, realm.Object, isPlainObject);
for (var key in object) {
if (hasOwnProperty.call(object, key)) {
newObject[key] = copy(object[key], realm);
}
}
if (SUPPORTS.SYMBOL_PROPERTIES) {
var symbols = getSymbols(object);
if (symbols.length) {
for (var index = 0, symbol; index < symbols.length; index++) {
symbol = symbols[index];
if (propertyIsEnumerable.call(object, symbol)) {
newObject[symbol] = copy(object[symbol], realm);
function copy(object, _a) {
var _b = _a === void 0 ? {} : _a, _c = _b.isStrict, isStrict = _c === void 0 ? false : _c, _d = _b.realm, realm = _d === void 0 ? GLOBAL_THIS : _d;
var RealmArrayBuffer = realm.ArrayBuffer, RealmBuffer = realm.Buffer, RealmMap = realm.Map, RealmSet = realm.Set, RealmWeakMap = realm.WeakMap, RealmWeakSet = realm.WeakSet;
var getObjectClone = isStrict
? getObjectCloneStrict
: getObjectCloneLoose;
/**
* @function handleCopy
*
* @description
* copy the object recursively based on its type
*
* @param object the object to copy
* @returns the copied object
*/
var handleCopy = function (object, cache) {
if (!object || typeof object !== 'object' || cache.has(object)) {
return object;
}
}
}
}
return newObject;
};
var Constructor = object.constructor;
// plain objects
if (Constructor === realm.Object) {
cache.add(object);
return getObjectClone(object, realm, handleCopy, cache);
}
var clone;
// arrays
if (isArray(object)) {
cache.add(object);
// if strict, include non-standard properties
if (isStrict) {
return getObjectCloneStrict(object, realm, handleCopy, cache);
}
clone = new Constructor();
for (var index = 0; index < object.length; index++) {
clone[index] = handleCopy(object[index], cache);
}
return clone;
}
// dates
if (object instanceof realm.Date) {
return new Constructor(object.getTime());
}
// regexps
if (object instanceof realm.RegExp) {
clone = new Constructor(object.source, object.flags || getRegExpFlags(object));
clone.lastIndex = object.lastIndex;
return clone;
}
// maps
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value, key) {
clone.set(key, handleCopy(value, cache));
});
return clone;
}
// sets
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
clone = new Constructor();
object.forEach(function (value) {
clone.add(handleCopy(value, cache));
});
return clone;
}
// buffers (node-only)
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
clone = RealmBuffer.allocUnsafe
? RealmBuffer.allocUnsafe(object.length)
: new Constructor(object.length);
object.copy(clone);
return clone;
}
// arraybuffers / dataviews
if (RealmArrayBuffer) {
// dataviews
if (RealmArrayBuffer.isView(object)) {
return new Constructor(object.buffer.slice(0));
}
// arraybuffers
if (object instanceof RealmArrayBuffer) {
return object.slice(0);
}
}
// if the object cannot / should not be cloned, don't
if (
// promise-like
typeof object.then === 'function' ||
// errors
object instanceof Error ||
// weakmaps
(RealmWeakMap && object instanceof RealmWeakMap) ||
// weaksets
(RealmWeakSet && object instanceof RealmWeakSet)) {
return object;
}
cache.add(object);
// assume anything left is a custom constructor
return getObjectClone(object, realm, handleCopy, cache);
};
return handleCopy(object, createCache());
}
/**
* @function copyRegExp
* @function strictCopy
*
* @description
* copy the RegExp to a new RegExp with the same properties
* copy the object with `strict` option pre-applied
*
* @param {RegExp} regExp the RegExp to copy
* @param {function} RealmRegExp the realm-specific RegExp constructor
* @returns {RegExp} the copied RegExp
* @param object the object to copy
* @param [options] the options for copying with
* @param [options.realm] the realm (this) object the object is copied from
* @returns the copied object
*/
var copyRegExp = function copyRegExp(regExp, RealmRegExp) {
var newRegExp = new RealmRegExp(regExp.source, SUPPORTS.FLAGS ? regExp.flags : getRegExpFlags(regExp));
newRegExp.lastIndex = regExp.lastIndex;
return newRegExp;
copy.strict = function strictCopy(object, options) {
return copy(object, {
isStrict: true,
realm: options ? options.realm : void 0,
});
};
/**
* @function copyTypedArray
*
* @description
* copy the typedArray, deeply copying the values
*
* @param {TypedArray} typedArray the typedArray to copy
* @returns {TypedArray} the copied typedArray
*/
var copyTypedArray = function copyTypedArray(typedArray) {
return new typedArray.constructor(copyArrayBuffer(typedArray.buffer));
};
return copy;
// utils
var isArray = Array.isArray;
/**
* @function copy
*
* @description
* deeply copy the object to a new object of the same type
*
* @param {any} object the object to copy
* @param {any} [realm=global] the realm to check instanceof in
* @returns {any} the copied object
*/
function copy(object, realm) {
if (realm === void 0) {
realm = global;
}
var _realm = realm,
RealmArrayBuffer = _realm.ArrayBuffer,
RealmBuffer = _realm.Buffer,
RealmDate = _realm.Date,
RealmMap = _realm.Map,
RealmObject = _realm.Object,
RealmRegExp = _realm.RegExp,
RealmSet = _realm.Set;
var cache = getNewCache();
var handleCopy = function handleCopy(object) {
if (!isObjectCopyable(object, cache)) {
return object;
}
if (isArray(object)) {
cache.add(object);
return copyArray(object, handleCopy, realm);
}
if (object.constructor === RealmObject) {
cache.add(object);
return copyObject(object, handleCopy, realm, true);
}
if (object instanceof RealmDate) {
return new RealmDate(object.getTime());
}
if (object instanceof RealmRegExp) {
return copyRegExp(object, RealmRegExp);
}
if (RealmMap && object instanceof RealmMap) {
cache.add(object);
return copyMap(object, handleCopy, realm);
}
if (RealmSet && object instanceof RealmSet) {
cache.add(object);
return copySet(object, handleCopy, realm);
}
if (RealmBuffer && RealmBuffer.isBuffer(object)) {
return copyBuffer(object, realm);
}
if (RealmArrayBuffer) {
if (RealmArrayBuffer.isView(object)) {
return copyTypedArray(object);
}
if (object instanceof RealmArrayBuffer) {
return copyArrayBuffer(object);
}
}
if (shouldObjectBeCopied(object, realm)) {
cache.add(object);
return copyObject(object, handleCopy, realm);
}
return object;
};
return handleCopy(object);
}
exports.default = copy;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=fast-copy.js.map

@@ -1,1 +0,1 @@

!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e=e||self)["fast-copy"]={})}(this,function(e){"use strict";var n=Object.create,t=Object.getOwnPropertySymbols,r=Object.getPrototypeOf,o=Object.prototype,f=o.hasOwnProperty,u=o.propertyIsEnumerable,i="string"==typeof/foo/g.flags,c="function"==typeof global.Object.getOwnPropertySymbols,a="function"==typeof global.WeakSet,s=function(){return a?new WeakSet:n({_values:[],add:function(e){this._values.push(e)},has:function(e){return!!~this._values.indexOf(e)}})},l=function(e,n){return"object"==typeof e&&null!==e&&!n.has(e)},p=function(e,n){return!("function"==typeof e.then||e instanceof n.Error||n.WeakMap&&e instanceof n.WeakMap||n.WeakSet&&e instanceof n.WeakSet)},d=function(e,n,t){for(var r=new e.constructor,o=0;o<e.length;o++)r[o]=n(e[o],t);return r},y=function(e){return e.slice(0)},g=function(e,n){var t=n.Buffer,r=t.allocUnsafe?t.allocUnsafe(e.length):new t(e.length);return e.copy(r),r},b=function(e,n,t){var r=new e.constructor;return e.forEach(function(e,o){return r.set(o,n(e,t))}),r},v=function(e,n,t){var r=new e.constructor;return e.forEach(function(e){return r.add(n(e,t))}),r},h=function(e,o,i,a){var s=function(e,t,o){if(o){var f=e.__proto__||r(e);return f===t.prototype?{}:n(f)}return e.constructor?new e.constructor:n(null)}(e,i.Object,a);for(var l in e)f.call(e,l)&&(s[l]=o(e[l],i));if(c){var p=t(e);if(p.length)for(var d,y=0;y<p.length;y++)d=p[y],u.call(e,d)&&(s[d]=o(e[d],i))}return s},w=function(e,n){var t=new n(e.source,i?e.flags:function(e){var n="";return e.global&&(n+="g"),e.ignoreCase&&(n+="i"),e.multiline&&(n+="m"),e.unicode&&(n+="u"),e.sticky&&(n+="y"),n}(e));return t.lastIndex=e.lastIndex,t},O=function(e){return new e.constructor(y(e.buffer))},j=Array.isArray;e.default=function(e,n){void 0===n&&(n=global);var t=n,r=t.ArrayBuffer,o=t.Buffer,f=t.Date,u=t.Map,i=t.Object,c=t.RegExp,a=t.Set,_=s();return function e(t){if(!l(t,_))return t;if(j(t))return _.add(t),d(t,e,n);if(t.constructor===i)return _.add(t),h(t,e,n,!0);if(t instanceof f)return new f(t.getTime());if(t instanceof c)return w(t,c);if(u&&t instanceof u)return _.add(t),b(t,e,n);if(a&&t instanceof a)return _.add(t),v(t,e,n);if(o&&o.isBuffer(t))return g(t,n);if(r){if(r.isView(t))return O(t);if(t instanceof r)return y(t)}return p(t,n)?(_.add(t),h(t,e,n)):t}(e)},Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self)["fast-copy"]=t()}(this,function(){"use strict";var e=Function.prototype.toString,t=Object.create,n=Object.defineProperty,r=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.getOwnPropertySymbols,f=Object.getPrototypeOf,c=Object.prototype,a=c.hasOwnProperty,u=c.propertyIsEnumerable,l="function"==typeof i,s="function"==typeof WeakSet,d=function(){if(s)return new WeakSet;var e=t({add:function(t){return e._values.push(t)},has:function(t){return!!~e._values.indexOf(t)}});return e._values=[],e},p=function(n,r){if(!n.constructor)return t(null);var o=n.__proto__||f(n);return n.constructor===r.Object?o===r.Object.prototype?{}:t(o):~e.call(n.constructor).indexOf("[native code]")?new n.constructor:t(o)},y=function(e,t,n,r){var o=p(e,t);for(var f in e)a.call(e,f)&&(o[f]=n(e[f],r));if(l){var c=i(e);if(c.length)for(var s=0,d=void 0;s<c.length;s++)d=c[s],u.call(e,d)&&(o[d]=n(e[d],r))}return o},v=function(e,t,f,c){var a=p(e,t),u=l?[].concat(o(e),i(e)):o(e);if(u.length)for(var s=0,d=void 0,y=void 0;s<u.length;s++)"callee"!==(d=u[s])&&"caller"!==d&&((y=r(e,d)).value=f(e[d],c),n(a,d,y));return a},g=function(e){var t="";return e.global&&(t+="g"),e.ignoreCase&&(t+="i"),e.multiline&&(t+="m"),e.unicode&&(t+="u"),e.sticky&&(t+="y"),t},b=Array.isArray,w="undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:void(console&&console.error&&console.error('Unable to locate global object, returning "this".'));function O(e,t){var n=void 0===t?{}:t,r=n.isStrict,o=void 0!==r&&r,i=n.realm,f=void 0===i?w:i,c=f.ArrayBuffer,a=f.Buffer,u=f.Map,l=f.Set,s=f.WeakMap,p=f.WeakSet,O=o?v:y,h=function(e,t){if(!e||"object"!=typeof e||t.has(e))return e;var n,r=e.constructor;if(r===f.Object)return t.add(e),O(e,f,h,t);if(b(e)){if(t.add(e),o)return v(e,f,h,t);n=new r;for(var i=0;i<e.length;i++)n[i]=h(e[i],t);return n}if(e instanceof f.Date)return new r(e.getTime());if(e instanceof f.RegExp)return(n=new r(e.source,e.flags||g(e))).lastIndex=e.lastIndex,n;if(u&&e instanceof u)return t.add(e),n=new r,e.forEach(function(e,r){n.set(r,h(e,t))}),n;if(l&&e instanceof l)return t.add(e),n=new r,e.forEach(function(e){n.add(h(e,t))}),n;if(a&&a.isBuffer(e))return n=a.allocUnsafe?a.allocUnsafe(e.length):new r(e.length),e.copy(n),n;if(c){if(c.isView(e))return new r(e.buffer.slice(0));if(e instanceof c)return e.slice(0)}return"function"==typeof e.then||e instanceof Error||s&&e instanceof s||p&&e instanceof p?e:(t.add(e),O(e,f,h,t))};return h(e,d())}return O.strict=function(e,t){return O(e,{isStrict:!0,realm:t?t.realm:void 0})},O});

@@ -1,3 +0,7 @@

declare module 'fast-copy' {
declare export default function copy(object: T): T;
declare module "fast-copy" {
declare export default {
(object: T, options?: O): T,
strict<T>(object: T, options?: O): T
};
}

@@ -1,1 +0,36 @@

export default function copy<T>(object: T): T;
declare namespace FastCopy {
export interface Constructor extends Function {
new (...args: any[]): any;
}
// @ts-ignore
export type Realm = Window | Global;
export interface Cache {
_values?: any[];
add: (value: any) => void;
has: (value: any) => boolean;
}
export type Copier = (object: any, cache: Cache) => any;
export type ObjectCloner = (
object: any,
realm: Realm,
handleCopy: Copier,
cache: Cache,
) => any;
export type Options = {
isStrict?: boolean;
realm?: Realm;
};
}
declare function copy<T>(object: any, options?: FastCopy.Options): T;
declare namespace copy {
function strictCopy<T>(object: any, options?: FastCopy.Options): T;
}
export default copy;
{
"author": "tony_quetano@planttheidea.com",
"ava": {
"failFast": true,
"files": [
"test/*.js"
],
"require": [
"@babel/register"
],
"sources": [
"src/*.js"
],
"verbose": true
},
"browser": "dist/fast-copy.js",

@@ -22,44 +9,34 @@ "bugs": {

"devDependencies": {
"@babel/cli": "^7.0.0",
"@babel/core": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@babel/register": "^7.0.0",
"ava": "^1.0.0-beta.8",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.0",
"benchmark": "^2.1.4",
"@types/jest": "^23.3.13",
"@types/lodash": "^4.14.120",
"@types/node": "^10.12.19",
"@types/ramda": "^0.25.47",
"@types/react": "^16.7.22",
"benchee": "^1.0.3",
"cli-table2": "^0.2.0",
"clone": "^2.1.2",
"decircularize": "^1.0.0",
"deep-clone": "^3.0.3",
"deep-eql": "^4.0.0",
"deep-equal": "^1.0.1",
"deepclone": "^1.0.2",
"eslint": "^5.7.0",
"eslint-config-rapid7": "^3.1.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.1.1",
"fast-clone": "^1.5.3",
"fast-deep-equal": "^2.0.1",
"fast-deepclone": "^1.0.0",
"fast-equals": "^1.6.1",
"fast-deepclone": "^1.0.1",
"html-webpack-plugin": "^3.2.0",
"in-publish": "^2.0.0",
"jest": "^24.0.0",
"lodash": "^4.17.11",
"nano-equal": "^2.0.2",
"nyc": "^13.1.0",
"optimize-js-plugin": "^0.0.4",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-fast-compare": "^2.0.2",
"rollup": "^1.1.2",
"rollup-plugin-babel": "^4.0.1",
"nyc": "^13.0.1",
"ramda": "^0.26.1",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"rollup": "^1.1.0",
"rollup-plugin-node-resolve": "^4.0.0",
"rollup-plugin-terser": "^4.0.3",
"shallow-equal-fuzzy": "^0.0.2",
"sinon": "^7.0.0",
"underscore": "^1.9.1",
"webpack": "^4.20.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.9"
"rollup-plugin-typescript2": "^0.19.2",
"ts-jest": "^23.10.4",
"ts-loader": "^5.3.3",
"tslint": "^5.11.0",
"tslint-config-airbnb": "^5.11.0",
"tslint-loader": "^3.5.4",
"typescript": "^3.2.4",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.0",
"webpack-dev-server": "^3.1.5"
},

@@ -85,15 +62,15 @@ "homepage": "https://github.com/planttheidea/fast-copy#readme",

"clean": "rimraf dist",
"dev": "NODE_ENV=development webpack-dev-server --colors --progress --config=webpack/webpack.config.dev.js",
"dev": "NODE_ENV=development webpack-dev-server --colors --progress --config=webpack/webpack.config.js",
"dist": "npm run clean && npm run build",
"lint": "NODE_ENV=test eslint src --max-warnings 0",
"lint:fix": "NODE_ENV=test eslint src --fix",
"lint": "NODE_ENV=test tslint 'src/*.ts'",
"lint:fix": "npm run lint -- --fix",
"prepublish": "if in-publish; then npm run prepublish:compile; fi",
"prepublish:compile": "npm run lint && npm run test:coverage && npm run dist",
"start": "npm run dev",
"test": "NODE_PATH=. BABEL_ENV=test ava",
"test:coverage": "nyc npm test",
"test:watch": "npm test -- --watch"
"test": "NODE_PATH=. jest",
"test:coverage": "npm run test -- --coverage",
"test:watch": "npm run test -- --watch"
},
"types": "index.d.ts",
"version": "1.2.4"
"version": "2.0.0"
}

@@ -12,3 +12,5 @@ # fast-copy

- [Usage](#usage)
- [Multiple realms](#multiple-realms)
- [Options](#options)
- [isStrict](#isstrict)
- [realm](#realm)
- [Types supported](#types-supported)

@@ -39,6 +41,20 @@ - [Benchmarks](#benchmarks)

#### Multiple realms
## Options
Under the hood, `fast-copy` uses `instanceof` to determine object types, which can cause false negatives when used in combination with `iframe`-based objects. To handle this edge case, you can pass the optional second parameter of `realm` to the `copy` method, which identifies which realm the object comes from and will use that realm to drive both comparisons and constructors for the copies.
#### isStrict
Starting in `2.0.0`, you can use the `isStrict` option to copy the object based on strict standards, meaning:
- Properties retain their original property descriptor
- Non-enumerable properties are copied
- Non-standard properties (e.g., keys on an `Array` object) are copied
This is significantly slower, so you should only use this if you believe it necessary.
**NOTE**: This option is also aliased as `copy.strict`.
#### realm
Under the hood, `fast-copy` uses `instanceof` to determine object types, which can cause false negatives when used in combination with `iframe`-based objects. To handle this edge case, you can pass the `realm` in options, which identifies which realm the object comes from and will use that realm to drive both comparisons and constructors for the copies.
```html

@@ -104,10 +120,12 @@ <iframe srcdoc="<script>var arr = ['foo', 'bar'];</script>"></iframe>

| | Operations / second | Relative margin of error |
| ---------------- | ------------------- | ------------------------ |
| **fast-copy** | **1,725,552** | **0.89%** |
| clone | 1,114,295 | 0.82% |
| lodash.cloneDeep | 904,031 | 0.51% |
| fast-deepclone | 716,908 | 0.87% |
| fast-clone | 497,748 | 0.88% |
| deepclone | 420,962 | 0.59% |
| | Operations / second |
| ------------------ | ------------------- |
| **fast-copy** | **2,692,822** |
| clone | 1,420,277 |
| lodash.cloneDeep | 1,277,213 |
| fast-deepclone | 768,982 |
| ramda | 719,948 |
| fast-clone | 567,342 |
| deepclone | 509,547 |
| fast-copy (strict) | 420,804 |

@@ -118,11 +136,28 @@ #### Complex objects

| | Operations / second | Relative margin of error |
| ---------------- | ------------------- | ------------------------ |
| **fast-copy** | **113,553** | **0.76%** |
| fast-deepclone | 101,356 | 0.76% |
| deepclone | 54,401 | 0.80% |
| clone | 51,183 | 0.79% |
| fast-clone | 46,165 | 0.66% |
| lodash.cloneDeep | 39,395 | 0.78% |
| | Operations / second |
| ------------------ | ------------------- |
| **fast-copy** | **109,352** |
| fast-deepclone | 101,808 |
| ramda | 93,103 |
| deepclone | 74,270 |
| fast-clone | 49,911 |
| clone | 46,355 |
| lodash.cloneDeep | 43,900 |
| fast-copy (strict) | 33,440 |
#### Big data
_Very large number of properties with high amount of nesting, mainly objects and arrays_
| | Operations / second |
| ------------------ | ------------------- |
| **fast-copy** | 123 |
| fast-deepclone | 101 |
| fast-clone | 93 |
| lodash.cloneDeep | 92 |
| deepclone | 66 |
| clone | 50 |
| fast-copy (strict) | 42 |
| ramda | 5 |
#### Circular objects

@@ -132,10 +167,12 @@

| | Operations / second | Relative margin of error |
| -------------------------- | ------------------- | ------------------------ |
| **fast-copy** | **1,011,337** | **0.80%** |
| clone | 644,481 | 0.67% |
| lodash.cloneDeep | 577,534 | 0.48% |
| fast-deepclone | 359,288 | 0.79% |
| deepclone | 371,971 | 0.55% |
| fast-clone (not supported) | 0 | 0.00% |
| | Operations / second |
| -------------------------- | ------------------- |
| **fast-copy** | **1,143,074** |
| ramda | 750,430 |
| clone | 722,632 |
| lodash.cloneDeep | 580,005 |
| deepclone | 490,824 |
| fast-deepclone | 446,585 |
| fast-copy (strict) | 321,678 |
| fast-clone (not supported) | 0 |

@@ -146,10 +183,12 @@ #### Special objects

| | Operations / second | Relative margin of error |
| ---------------- | ------------------- | ------------------------ |
| **fast-copy** | **56,013** | **0.97%** |
| clone | 42,107 | 0.87% |
| lodash.cloneDeep | 36,113 | 0.74% |
| fast-deepclone | 25,278 | 1.45% |
| fast-clone | 21,450 | 0.86% |
| deepclone | 12,768 | 0.77% |
| | Operations / second |
| ------------------ | ------------------- |
| **fast-copy** | **78,422** |
| clone | 52,165 |
| lodash.cloneDeep | 39,648 |
| ramda | 32,372 |
| fast-deepclone | 27,518 |
| fast-clone | 27,495 |
| deepclone | 16,552 |
| fast-copy (strict) | 12,509 |

@@ -156,0 +195,0 @@ ## Development

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc