Socket
Socket
Sign inDemoInstall

fast-copy

Package Overview
Dependencies
0
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0-beta.2 to 3.0.0-beta.3

4

CHANGELOG.md

@@ -9,3 +9,5 @@ # fast-copy CHANGELOG

- `copy.strict` is no longer available; it is now available as the explicit `copyStrict` named import
- `FastCopy` TS namespace has been removed in favor of explicit type imports
- Options have been removed
- `isStrict` has been replaced with importing `copyStrict`
- `realm` has been removed, as `instanceof` is no longer used internally

@@ -12,0 +14,0 @@ ## 2.1.7

@@ -1,22 +0,10 @@

import type { Realm } from './utils';
export interface Options {
isStrict?: boolean;
realm?: Realm;
}
export interface StrictOptions extends Omit<Options, 'isStrict'> {
}
/**
* Copy an value deeply as much as possible.
*
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* The value 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.
*/
export declare function copy<Value>(value: Value, options?: Options): Value;
export declare function copy<Value>(value: Value): Value;
/**
* Copy the value with `strict` option pre-applied.
* 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.
*/
export declare function copyStrict(value: any, options?: StrictOptions): any;
export declare function copyStrict<Value>(value: Value): Value;

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

declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export interface Cache {

@@ -8,5 +9,2 @@ _keys?: any[];

}
export declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export declare type ObjectCloner = <Value>(object: Value, realm: Realm, handleCopy: InternalCopier, cache: Cache) => Value;
export declare type Realm = Record<string, any>;
declare function createCacheModern(): Cache;

@@ -17,6 +15,7 @@ /**

export declare const createCache: typeof createCacheModern;
export declare function getArrayCloneLoose(array: any[], prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**
* Get an empty version of the object with the same prototype it has.
*/
export declare function getCleanClone(object: any, realm: Realm): any;
export declare function getCleanClone(object: any, prototype: any): any;
/**

@@ -26,3 +25,3 @@ * Get a copy of the object based on loose rules, meaning all enumerable keys

*/
export declare function getObjectCloneLoose(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneLoose(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**

@@ -32,3 +31,3 @@ * Get a copy of the object based on strict rules, meaning all keys and symbols

*/
export declare function getObjectCloneStrict(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneStrict(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
declare function getRegExpFlagsModern(regExp: RegExp): string;

@@ -35,0 +34,0 @@ /**

@@ -1,22 +0,10 @@

import type { Realm } from './utils';
export interface Options {
isStrict?: boolean;
realm?: Realm;
}
export interface StrictOptions extends Omit<Options, 'isStrict'> {
}
/**
* Copy an value deeply as much as possible.
*
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* The value 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.
*/
export declare function copy<Value>(value: Value, options?: Options): Value;
export declare function copy<Value>(value: Value): Value;
/**
* Copy the value with `strict` option pre-applied.
* 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.
*/
export declare function copyStrict(value: any, options?: StrictOptions): any;
export declare function copyStrict<Value>(value: Value): Value;

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

declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export interface Cache {

@@ -8,5 +9,2 @@ _keys?: any[];

}
export declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export declare type ObjectCloner = <Value>(object: Value, realm: Realm, handleCopy: InternalCopier, cache: Cache) => Value;
export declare type Realm = Record<string, any>;
declare function createCacheModern(): Cache;

@@ -17,6 +15,7 @@ /**

export declare const createCache: typeof createCacheModern;
export declare function getArrayCloneLoose(array: any[], prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**
* Get an empty version of the object with the same prototype it has.
*/
export declare function getCleanClone(object: any, realm: Realm): any;
export declare function getCleanClone(object: any, prototype: any): any;
/**

@@ -26,3 +25,3 @@ * Get a copy of the object based on loose rules, meaning all enumerable keys

*/
export declare function getObjectCloneLoose(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneLoose(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**

@@ -32,3 +31,3 @@ * Get a copy of the object based on strict rules, meaning all keys and symbols

*/
export declare function getObjectCloneStrict(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneStrict(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
declare function getRegExpFlagsModern(regExp: RegExp): string;

@@ -35,0 +34,0 @@ /**

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

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["fast-copy"]={})}(this,(function(e){"use strict";var t=Function.prototype.toString,n=Object.create,r=Object.defineProperty,o=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyNames,i=Object.getOwnPropertySymbols,a=Object.getPrototypeOf,u=Object.prototype,c=u.hasOwnProperty,s=u.propertyIsEnumerable,l="function"==typeof i,p=function(){function e(){this._keys=[],this._values=[]}return e.prototype.has=function(e){return!!~this._keys.indexOf(e)},e.prototype.get=function(e){return this._values[this._keys.indexOf(e)]},e.prototype.set=function(e,t){this._keys.push(e),this._values.push(t)},e}();var y="undefined"!=typeof WeakMap?function(){return new WeakMap}:function(){return new p};function d(e,r){var o=e.__proto__||a(e);if(!o)return n(null);var f=o.constructor;if(f===r.Object)return o===r.Object.prototype?{}:n(o);if(~t.call(f).indexOf("[native code]"))try{return new f}catch(e){}return n(o)}function g(e,t,n,r){var o=d(e,t);for(var f in r.set(e,o),e)c.call(e,f)&&(o[f]=n(e[f],r));if(l)for(var a=i(e),u=0,p=a.length,y=void 0;u<p;++u)y=a[u],s.call(e,y)&&(o[y]=n(e[y],r));return o}var b=l?function(e){return f(e).concat(i(e))}:f;function h(e,t,n,f){var i=d(e,t);f.set(e,i);for(var a=b(e),u=0,c=a.length,s=void 0,l=void 0;u<c;++u)if("callee"!==(s=a[u])&&"caller"!==s)if(l=o(e,s)){l.get||l.set||(l.value=n(e[s],f));try{r(i,s,l)}catch(e){i[s]=l.value}}else i[s]=n(e[s],f);return i}var v="g"===/test/g.flags?function(e){return e.flags}: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},O=Array.isArray,w=Object.assign,_=Object.getPrototypeOf,j=function(){return"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:(console&&console.error&&console.error('Unable to locate global object, returning "this".'),this)}();function k(e,t){var n=!(!t||!t.isStrict),r=t&&t.realm||j,o=n?h:g,f=function(e,t){if(!e||"object"!=typeof e)return e;if(t.has(e))return t.get(e);var i=e.__proto__||_(e),a=i&&i.constructor;if(!a||a===r.Object)return o(e,r,f,t);if(O(e)){if(n)return h(e,r,f,t);var u=new a;t.set(e,u);for(var c=0,s=e.length;c<s;++c)u[c]=f(e[c],t);return u}if(e instanceof r.Date)return new a(e.getTime());if(e instanceof r.RegExp)return(u=new a(e.source,e.flags||v(e))).lastIndex=e.lastIndex,u;if(r.Map&&e instanceof r.Map){var l=new a;return t.set(e,l),e.forEach((function(e,n){l.set(n,f(e,t))})),l}if(r.Set&&e instanceof r.Set){var p=new a;return t.set(e,p),e.forEach((function(e){p.add(f(e,t))})),p}if(r.Blob&&e instanceof r.Blob)return e.slice(0,e.size,e.type);if(r.Buffer&&r.Buffer.isBuffer(e)){u=r.Buffer.allocUnsafe?r.Buffer.allocUnsafe(e.length):new a(e.length);return t.set(e,u),e.copy(u),u}if(r.ArrayBuffer){if(r.ArrayBuffer.isView(e)){u=new a(e.buffer.slice(0));return t.set(e,u),u}if(e instanceof r.ArrayBuffer){u=e.slice(0);return t.set(e,u),u}}return"function"==typeof e.then||e instanceof Error||r.WeakMap&&e instanceof r.WeakMap||r.WeakSet&&e instanceof r.WeakSet?e:o(e,r,f,t)};return f(e,y())}e.copy=k,e.copyStrict=function(e,t){return k(e,w({},t,{isStrict:!0}))},Object.defineProperty(e,"__esModule",{value:!0})}));
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["fast-copy"]={})}(this,(function(e){"use strict";var t=Function.prototype.toString,r=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,c=Object.getOwnPropertySymbols,u=Object.prototype,a=u.hasOwnProperty,f=u.propertyIsEnumerable,s="function"==typeof c,l=function(){function e(){this._keys=[],this._values=[]}return e.prototype.has=function(e){return!!~this._keys.indexOf(e)},e.prototype.get=function(e){return this._values[this._keys.indexOf(e)]},e.prototype.set=function(e,t){this._keys.push(e),this._values.push(t)},e}();var y="undefined"!=typeof WeakMap?function(){return new WeakMap}:function(){return new l};function p(e,t,r,n){var o=new t.constructor;n.set(e,o);for(var i=0,c=e.length;i<c;++i)o[i]=r(e[i],n);return o}function b(e,n){if(!n)return r(null);var o=n.constructor;if(o===Object)return n===Object.prototype?{}:r(n);if(~t.call(o).indexOf("[native code]"))try{return new o}catch(e){}return r(n)}function j(e,t,r,n){var o=b(0,t);for(var i in n.set(e,o),e)a.call(e,i)&&(o[i]=r(e[i],n));if(s)for(var u=c(e),l=0,y=u.length,p=void 0;l<y;++l)p=u[l],f.call(e,p)&&(o[p]=r(e[p],n));return o}var v=s?function(e){return i(e).concat(c(e))}:i;function d(e,t,r,i){var c=b(0,t);i.set(e,c);for(var u=v(e),a=0,f=u.length,s=void 0,l=void 0;a<f;++a)if("callee"!==(s=u[a])&&"caller"!==s)if(l=o(e,s)){l.get||l.set||(l.value=r(e[s],i));try{n(c,s,l)}catch(e){c[s]=l.value}}else c[s]=r(e[s],i);return c}var g,h,O="g"===/test/g.flags?function(e){return e.flags}: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},w=Array.isArray,A=Object.getPrototypeOf,_=Object.prototype.toString,m=((g={})["[object ArrayBuffer]"]=!0,g["[object Float32Array]"]=!0,g["[object Float64Array]"]=!0,g["[object Int8Array]"]=!0,g["[object Int16Array]"]=!0,g["[object Int32Array]"]=!0,g["[object Uint8Array]"]=!0,g["[object Uint8ClampedArray]"]=!0,g["[object Uint16Array]"]=!0,g["[object Uint32Array]"]=!0,g["[object Uint64Array]"]=!0,g),k=((h={})["[object Error]"]=!0,h["[object Promise]"]=!0,h["[object WeakMap]"]=!0,h["[object WeakSet]"]=!0,h);function x(e,t,r){return function e(n,o){if(!n||"object"!=typeof n)return n;if(o.has(n))return o.get(n);var i=n.__proto__||A(n),c=i&&i.constructor;if(!c||c===Object)return t(n,i,e,o);if(w(n))return r(n,i,e,o);var u=_.call(n);if("[object Date]"===u)return new c(n.getTime());if("[object RegExp]"===u)return(a=new c(n.source,n.flags||O(n))).lastIndex=n.lastIndex,a;if("[object Map]"===u){var a=new c(n.entries());return o.set(n,a),a}if("[object Set]"===u){a=new c(n.values());return o.set(n,a),a}if("[object Blob]"===u)return n.slice(0,n.size,n.type);if("[object DataView]"===u){a=new c(n.buffer.slice(0));return o.set(n,a),a}if(m[u]){a=n.slice(0);return o.set(n,a),a}return"function"==typeof n.then||k[u]?n:t(n,i,e,o)}(e,y())}e.copy=function(e){return x(e,j,p)},e.copyStrict=function(e){return x(e,d,d)},Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.min.js.map

@@ -1,22 +0,10 @@

import type { Realm } from './utils';
export interface Options {
isStrict?: boolean;
realm?: Realm;
}
export interface StrictOptions extends Omit<Options, 'isStrict'> {
}
/**
* Copy an value deeply as much as possible.
*
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* The value 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.
*/
export declare function copy<Value>(value: Value, options?: Options): Value;
export declare function copy<Value>(value: Value): Value;
/**
* Copy the value with `strict` option pre-applied.
* 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.
*/
export declare function copyStrict(value: any, options?: StrictOptions): any;
export declare function copyStrict<Value>(value: Value): Value;

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

declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export interface Cache {

@@ -8,5 +9,2 @@ _keys?: any[];

}
export declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export declare type ObjectCloner = <Value>(object: Value, realm: Realm, handleCopy: InternalCopier, cache: Cache) => Value;
export declare type Realm = Record<string, any>;
declare function createCacheModern(): Cache;

@@ -17,6 +15,7 @@ /**

export declare const createCache: typeof createCacheModern;
export declare function getArrayCloneLoose(array: any[], prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**
* Get an empty version of the object with the same prototype it has.
*/
export declare function getCleanClone(object: any, realm: Realm): any;
export declare function getCleanClone(object: any, prototype: any): any;
/**

@@ -26,3 +25,3 @@ * Get a copy of the object based on loose rules, meaning all enumerable keys

*/
export declare function getObjectCloneLoose(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneLoose(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**

@@ -32,3 +31,3 @@ * Get a copy of the object based on strict rules, meaning all keys and symbols

*/
export declare function getObjectCloneStrict(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneStrict(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
declare function getRegExpFlagsModern(regExp: RegExp): string;

@@ -35,0 +34,0 @@ /**

@@ -8,4 +8,4 @@ (function (global, factory) {

var toStringFunction = Function.prototype.toString;
var create = Object.create, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols, getPrototypeOf$1 = Object.getPrototypeOf;
var _a = Object.prototype, hasOwnProperty = _a.hasOwnProperty, propertyIsEnumerable = _a.propertyIsEnumerable;
var create = Object.create, defineProperty = Object.defineProperty, getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;
var _a$1 = Object.prototype, hasOwnProperty = _a$1.hasOwnProperty, propertyIsEnumerable = _a$1.propertyIsEnumerable;
var SYMBOL_PROPERTIES = typeof getOwnPropertySymbols === 'function';

@@ -39,7 +39,14 @@ var LegacyCache = /** @class */ (function () {

var createCache = typeof WeakMap !== 'undefined' ? createCacheModern : createCacheLegacy;
function getArrayCloneLoose(array, prototype, handleCopy, cache) {
var clone = new prototype.constructor();
cache.set(array, clone);
for (var index = 0, length_1 = array.length; index < length_1; ++index) {
clone[index] = handleCopy(array[index], cache);
}
return clone;
}
/**
* Get an empty version of the object with the same prototype it has.
*/
function getCleanClone(object, realm) {
var prototype = object.__proto__ || getPrototypeOf$1(object);
function getCleanClone(object, prototype) {
if (!prototype) {

@@ -49,4 +56,4 @@ return create(null);

var Constructor = prototype.constructor;
if (Constructor === realm.Object) {
return prototype === realm.Object.prototype ? {} : create(prototype);
if (Constructor === Object) {
return prototype === Object.prototype ? {} : create(prototype);
}

@@ -65,4 +72,4 @@ if (~toStringFunction.call(Constructor).indexOf('[native code]')) {

*/
function getObjectCloneLoose(object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
function getObjectCloneLoose(object, prototype, handleCopy, cache) {
var clone = getCleanClone(object, prototype);
// set in the cache immediately to be able to reuse the object recursively

@@ -77,3 +84,3 @@ cache.set(object, clone);

var symbols = getOwnPropertySymbols(object);
for (var index = 0, length_1 = symbols.length, symbol = void 0; index < length_1; ++index) {
for (var index = 0, length_2 = symbols.length, symbol = void 0; index < length_2; ++index) {
symbol = symbols[index];

@@ -97,8 +104,8 @@ if (propertyIsEnumerable.call(object, symbol)) {

*/
function getObjectCloneStrict(object, realm, handleCopy, cache) {
var clone = getCleanClone(object, realm);
function getObjectCloneStrict(object, prototype, handleCopy, cache) {
var clone = getCleanClone(object, prototype);
// set in the cache immediately to be able to reuse the object recursively
cache.set(object, clone);
var properties = getStrictProperties(object);
for (var index = 0, length_2 = properties.length, property = void 0, descriptor = void 0; index < length_2; ++index) {
for (var index = 0, length_3 = properties.length, property = void 0, descriptor = void 0; index < length_3; ++index) {
property = properties[index];

@@ -156,47 +163,27 @@ if (property !== 'callee' && property !== 'caller') {

var _a, _b;
var isArray = Array.isArray;
var assign = Object.assign, getPrototypeOf = Object.getPrototypeOf;
var GLOBAL_THIS = (function () {
if (typeof globalThis !== 'undefined') {
return globalThis;
}
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".');
}
return this;
})();
/**
* Copy an value deeply as much as possible.
*
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* The value 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.
*/
function copy(value, options) {
// manually coalesced instead of default parameters for performance
var isStrict = !!(options && options.isStrict);
var realm = (options && options.realm) || GLOBAL_THIS;
var getObjectClone = isStrict ? getObjectCloneStrict : getObjectCloneLoose;
/**
* @function handleCopy
*
* @description
* copy the value recursively based on its type
*
* @param value the value to copy
* @returns the copied value
*/
var handleCopy = function (value, cache) {
var getPrototypeOf = Object.getPrototypeOf;
var toString = Object.prototype.toString;
var ARRAY_BUFFER_OBJECT_CLASSES = (_a = {},
_a['[object ArrayBuffer]'] = true,
_a['[object Float32Array]'] = true,
_a['[object Float64Array]'] = true,
_a['[object Int8Array]'] = true,
_a['[object Int16Array]'] = true,
_a['[object Int32Array]'] = true,
_a['[object Uint8Array]'] = true,
_a['[object Uint8ClampedArray]'] = true,
_a['[object Uint16Array]'] = true,
_a['[object Uint32Array]'] = true,
_a['[object Uint64Array]'] = true,
_a);
var UNCOPIABLE_OBJECT_CLASSES = (_b = {},
_b['[object Error]'] = true,
_b['[object Promise]'] = true,
_b['[object WeakMap]'] = true,
_b['[object WeakSet]'] = true,
_b);
function performCopy(value, getObjectClone, getArrayClone) {
function handleCopy(value, cache) {
if (!value || typeof value !== 'object') {

@@ -211,24 +198,16 @@ return value;

// plain objects
if (!Constructor || Constructor === realm.Object) {
return getObjectClone(value, realm, handleCopy, cache);
if (!Constructor || Constructor === Object) {
return getObjectClone(value, prototype, handleCopy, cache);
}
// arrays
if (isArray(value)) {
// if strict, include non-standard properties
if (isStrict) {
return getObjectCloneStrict(value, realm, handleCopy, cache);
}
var clone = new Constructor();
cache.set(value, clone);
for (var index = 0, length_1 = value.length; index < length_1; ++index) {
clone[index] = handleCopy(value[index], cache);
}
return clone;
return getArrayClone(value, prototype, handleCopy, cache);
}
var objectClass = toString.call(value);
// dates
if (value instanceof realm.Date) {
if (objectClass === '[object Date]') {
return new Constructor(value.getTime());
}
// regexps
if (value instanceof realm.RegExp) {
if (objectClass === '[object RegExp]') {
var clone = new Constructor(value.source, value.flags || getRegExpFlags(value));

@@ -239,70 +218,56 @@ clone.lastIndex = value.lastIndex;

// maps
if (realm.Map && value instanceof realm.Map) {
var clone_1 = new Constructor();
cache.set(value, clone_1);
value.forEach(function (value, key) {
clone_1.set(key, handleCopy(value, cache));
});
return clone_1;
if (objectClass === '[object Map]') {
var clone = new Constructor(value.entries());
cache.set(value, clone);
return clone;
}
// sets
if (realm.Set && value instanceof realm.Set) {
var clone_2 = new Constructor();
cache.set(value, clone_2);
value.forEach(function (value) {
clone_2.add(handleCopy(value, cache));
});
return clone_2;
if (objectClass === '[object Set]') {
var clone = new Constructor(value.values());
cache.set(value, clone);
return clone;
}
// blobs
if (realm.Blob && value instanceof realm.Blob) {
if (objectClass === '[object Blob]') {
return value.slice(0, value.size, value.type);
}
// buffers (node-only)
if (realm.Buffer && realm.Buffer.isBuffer(value)) {
var clone = realm.Buffer.allocUnsafe
? realm.Buffer.allocUnsafe(value.length)
: new Constructor(value.length);
// dataviews
if (objectClass === '[object DataView]') {
var clone = new Constructor(value.buffer.slice(0));
cache.set(value, clone);
value.copy(clone);
return clone;
}
// arraybuffers / dataviews
if (realm.ArrayBuffer) {
// dataviews
if (realm.ArrayBuffer.isView(value)) {
var clone = new Constructor(value.buffer.slice(0));
cache.set(value, clone);
return clone;
}
// arraybuffers
if (value instanceof realm.ArrayBuffer) {
var clone = value.slice(0);
cache.set(value, clone);
return clone;
}
// array buffers
if (ARRAY_BUFFER_OBJECT_CLASSES[objectClass]) {
var clone = value.slice(0);
cache.set(value, clone);
return clone;
}
// if the value cannot / should not be cloned, don't
// if the value cannot / should not be copied deeply, return the reference
if (
// promise-like
typeof value.then === 'function' ||
// errors
value instanceof Error ||
// weakmaps
(realm.WeakMap && value instanceof realm.WeakMap) ||
// weaksets
(realm.WeakSet && value instanceof realm.WeakSet)) {
// object classes which cannot be introspected for copy
UNCOPIABLE_OBJECT_CLASSES[objectClass]) {
return value;
}
// assume anything left is a custom constructor
return getObjectClone(value, realm, handleCopy, cache);
};
return getObjectClone(value, prototype, handleCopy, cache);
}
return handleCopy(value, createCache());
}
/**
* Copy the value with `strict` option pre-applied.
* Copy an value deeply as much as possible.
*/
function copyStrict(value, options) {
return copy(value, assign({}, options, { isStrict: true }));
function copy(value) {
return performCopy(value, getObjectCloneLoose, getArrayCloneLoose);
}
/**
* 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.
*/
function copyStrict(value) {
return performCopy(value, getObjectCloneStrict, getObjectCloneStrict);
}

@@ -309,0 +274,0 @@ exports.copy = copy;

@@ -1,22 +0,10 @@

import type { Realm } from './utils';
export interface Options {
isStrict?: boolean;
realm?: Realm;
}
export interface StrictOptions extends Omit<Options, 'isStrict'> {
}
/**
* Copy an value deeply as much as possible.
*
* If `strict` is applied, then all properties (including non-enumerable ones)
* are copied with their original property descriptors on both objects and arrays.
*
* The value 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.
*/
export declare function copy<Value>(value: Value, options?: Options): Value;
export declare function copy<Value>(value: Value): Value;
/**
* Copy the value with `strict` option pre-applied.
* 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.
*/
export declare function copyStrict(value: any, options?: StrictOptions): any;
export declare function copyStrict<Value>(value: Value): Value;

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

declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export interface Cache {

@@ -8,5 +9,2 @@ _keys?: any[];

}
export declare type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export declare type ObjectCloner = <Value>(object: Value, realm: Realm, handleCopy: InternalCopier, cache: Cache) => Value;
export declare type Realm = Record<string, any>;
declare function createCacheModern(): Cache;

@@ -17,6 +15,7 @@ /**

export declare const createCache: typeof createCacheModern;
export declare function getArrayCloneLoose(array: any[], prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**
* Get an empty version of the object with the same prototype it has.
*/
export declare function getCleanClone(object: any, realm: Realm): any;
export declare function getCleanClone(object: any, prototype: any): any;
/**

@@ -26,3 +25,3 @@ * Get a copy of the object based on loose rules, meaning all enumerable keys

*/
export declare function getObjectCloneLoose(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneLoose(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
/**

@@ -32,3 +31,3 @@ * Get a copy of the object based on strict rules, meaning all keys and symbols

*/
export declare function getObjectCloneStrict(object: any, realm: Realm, handleCopy: InternalCopier, cache: Cache): any;
export declare function getObjectCloneStrict(object: any, prototype: any, handleCopy: InternalCopier, cache: Cache): any;
declare function getRegExpFlagsModern(regExp: RegExp): string;

@@ -35,0 +34,0 @@ /**

@@ -1,31 +0,2 @@

export interface Cache {
_keys?: any[];
_values?: any[];
has: (value: any) => boolean;
set: (key: any, value: any) => void;
get: (key: any) => any;
}
export type InternalCopier = <Value = any>(value: Value, cache: Cache) => Value;
export type ObjectCloner = <Value>(
object: Value,
realm: Realm,
handleCopy: InternalCopier,
cache: Cache
) => Value;
export interface Options {
isStrict?: boolean;
realm?: Realm;
}
export interface StrictOptions extends Omit<Options, 'isStrict'> {}
export type Realm = Record<string, any>;
export const copy: <Value = any>(value: Value, options?: Options) => Value;
export const copyStrict: <Value = any>(
value: Value,
options?: StrictOptions
) => Value;
export const copy: <Value>(value: Value) => Value;
export const copyStrict: <Value>(value: Value) => Value;

@@ -100,3 +100,3 @@ {

"types": "index.d.ts",
"version": "3.0.0-beta.2"
"version": "3.0.0-beta.3"
}

@@ -14,6 +14,9 @@ # fast-copy

- [Usage](#usage)
- [Options](#options)
- [isStrict](#isstrict)
- [realm](#realm)
- [API](#api)
- [`copy`](#copy)
- [`copyStrict`](#copystrict)
- [Types supported](#types-supported)
- [Aspects of copying](#aspects-of-copying)
- [Error references are copied over (instead of creating a new `*Error` object)](#error-references-are-copied-over-instead-of-creating-a-new-error-object)
- [The constructor of the original object is used, instead of using known globals.](#the-constructor-of-the-original-object-is-used-instead-of-using-known-globals)
- [Benchmarks](#benchmarks)

@@ -47,41 +50,36 @@ - [Simple objects](#simple-objects)

## Options
## API
#### isStrict
### `copy`
Starting in `2.0.0`, you can use the `isStrict` option to copy the object based on strict standards, meaning:
Deeply copy the object passed.
- Properties retain their original property descriptor
- Non-enumerable properties are copied
- Non-standard properties (e.g., keys on an `Array` object) are copied
```ts
import { copy } from 'fast-copy';
This is significantly slower, so you should only use this if your use-case requires it.
```javascript
console.log(copy(object, { isStrict: true }));
const copied = copy({ foo: 'bar' });
```
**NOTE**: This option is also aliased as `copyStrict`.
### `copyStrict`
```javascript
import { copyStrict } from 'fast-copy';
Deeply copy the object passed, but with additional strictness when replicating the original object:
console.log(copyStrict(object));
```
- Properties retain their original property descriptor
- Non-enumerable keys are copied
- Non-standard properties (e.g., keys on an `Array` object) are copied
#### realm
```ts
import { copyStrict } from 'fast-copy';
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.
const object = { foo: 'bar' };
object.nonEnumerable = Object.defineProperty(object, 'bar', {
enumerable: false,
value: 'baz',
});
```html
<iframe srcdoc="<script>var arr = ['foo', 'bar'];</script>"></iframe>
const copied = copy(object);
```
```javascript
const iframe = document.querySelector('iframe');
const arr = iframe.contentWindow.arr;
**NOTE**: This method is significantly slower than [`copy`](#copy), so it is recommended to only use this when you have specific use-cases that require it.
console.log(copy(arr, { realm: iframe.contentWindow })); // ['foo', 'bar']
```
## Types supported

@@ -129,4 +127,16 @@

Circular objects are supported out of the box as well. By default a cache based on `WeakSet` is used, but if `WeakSet` is not available then a standard `Object` fallback is used. The benchmarks quoted below are based on use of `WeakSet`.
Circular objects are supported out of the box. By default, a cache based on `WeakSet` is used, but if `WeakSet` is not available then a fallback is used. The benchmarks quoted below are based on use of `WeakSet`.
## Aspects of copying
Inherently, what is considered a valid copy is subjective because of different requirements and use-cases. For this library, some decisions were explicitly made.
### Error references are copied over (instead of creating a new `*Error` object)
While it would be relatively trivial to copy over the message and stack to a new object of the same `Error` subclass, it is a common practice to "override" the message or stack, and copies would not retain this mutation. As such, the original reference is copied.
### The constructor of the original object is used, instead of using known globals.
Starting in ES2015, native globals can be subclassed like any custom class. When copying, we explicitly reuse the constructor of the original object. However, the expectation is that these subclasses would have the same constructur signature as their native base class. This is a common community practice, however because there is the possibility of inaccuracy if the contract differs, it should be noted.
## Benchmarks

@@ -133,0 +143,0 @@

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

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc