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

fast-equals

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-equals - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

es/constants.js

5

CHANGELOG.md
# fast-equals CHANGELOG
## 1.5.0
* Add [`circularDeepEqual`](README.md#circulardeepequal) and [`circularShallowEqual`](README.md#circularshallowequal) methods
* Add `meta` third parameter to `comparator` calls, for use with `createCustomEqual` method
## 1.4.1

@@ -4,0 +9,0 @@

322

dist/fast-equals.js

@@ -8,2 +8,35 @@ (function (global, factory) {

/**
* @constant {boolean} HAS_MAP_SUPPORT
*/
var HAS_MAP_SUPPORT = typeof Map === 'function';
/**
* @constant {boolean} HAS_SET_SUPPORT
*/
var HAS_SET_SUPPORT = typeof Set === 'function';
/**
* @constant {boolean} HAS_WEAKSET_SUPPORT
*/
var HAS_WEAKSET_SUPPORT = typeof WeakSet === 'function';
// constants
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @function addObjectToCache
*
* @description
* add object to cache if it is indeed an object
*
* @param {any} object the object to potentially add to the cache
* @param {Object|WeakSet} cache the cache to add to
* @returns {void}
*/
var addObjectToCache = function addObjectToCache(object, cache) {
return object && typeof object === 'object' && cache.add(object);
};
/**
* @function sameValueZeroEqual

@@ -14,4 +47,4 @@ *

*
* @param {*} objectA the object to compare against
* @param {*} objectB the object to test
* @param {any} objectA the object to compare against
* @param {any} objectB the object to test
* @returns {boolean} are the objects equal by the SameValueZero principle

@@ -24,2 +57,15 @@ */

/**
* @function isPlainObject
*
* @description
* is the object a plain object
*
* @param {any} object the object to test
* @returns {boolean} is the object a plain object
*/
var isPlainObject = function isPlainObject(object) {
return object.constructor === Object;
};
/**
* @function isPromiseLike

@@ -51,2 +97,53 @@ *

/**
* @function getNewCache
*
* @description
* get a new cache object to prevent circular references
*
* @returns {Object|Weakset} the new cache object
*/
var getNewCache = function getNewCache() {
return HAS_WEAKSET_SUPPORT ? new WeakSet() : Object.create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
}
});
};
/**
* @function createCircularEqual
*
* @description
* create a custom isEqual handler specific to circular objects
*
* @param {funtion} [isEqual] the isEqual comparator to use instead of isDeepEqual
* @returns {function(any, any): boolean}
*/
var createCircularEqual = function createCircularEqual(isEqual) {
return function (isDeepEqual) {
var comparator = isEqual || isDeepEqual;
return function (objectA, objectB) {
var cache = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getNewCache();
var cacheHasA = cache.has(objectA);
var cacheHasB = cache.has(objectB);
if (cacheHasA || cacheHasB) {
return cacheHasA && cacheHasB;
}
addObjectToCache(objectA, cache);
addObjectToCache(objectB, cache);
return comparator(objectA, objectB, cache);
};
};
};
/**
* @function toPairs

@@ -71,31 +168,102 @@ *

/**
* @function areIterablesEqual
* @function areArraysEqual
*
* @description
* determine if the iterables are equivalent in value
* are the arrays equal in value
*
* @param {Map|Set} objectA the object to test
* @param {Map|Set} objectB the object to test against
* @param {function} comparator the comparator to determine deep equality
* @param {boolean} shouldCompareKeys should the keys be tested in the equality comparison
* @returns {boolean} are the objects equal in value
* @param {Array<any>} arrayA the array to test
* @param {Array<any>} arrayB the array to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the arrays equal
*/
var areIterablesEqual = function areIterablesEqual(objectA, objectB, comparator, shouldCompareKeys) {
if (objectA.size !== objectB.size) {
var areArraysEqual = function areArraysEqual(arrayA, arrayB, isEqual, meta) {
if (arrayA.length !== arrayB.length) {
return false;
}
var pairsA = toPairs(objectA);
var pairsB = toPairs(objectB);
for (var index = 0; index < arrayA.length; index++) {
if (!isEqual(arrayA[index], arrayB[index], meta)) {
return false;
}
}
return shouldCompareKeys ? comparator(pairsA.keys, pairsB.keys) && comparator(pairsA.values, pairsB.values) : comparator(pairsA.values, pairsB.values);
return true;
};
// utils
var createAreIterablesEqual = function createAreIterablesEqual(shouldCompareKeys) {
/**
* @function areIterablesEqual
*
* @description
* determine if the iterables are equivalent in value
*
* @param {Array<Array<any>>} pairsA the pairs to test
* @param {Array<Array<any>>} pairsB the pairs to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the cache possibly being used
* @returns {boolean} are the objects equal in value
*/
var areIterablesEqual = shouldCompareKeys ? function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.keys, pairsB.keys) && isEqual(pairsA.values, pairsB.values, meta);
} : function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.values, pairsB.values, meta);
};
var HAS_MAP_SUPPORT = typeof Map === 'function';
var HAS_SET_SUPPORT = typeof Set === 'function';
return function (iterableA, iterableB, isEqual, meta) {
return iterableA.size === iterableB.size && areIterablesEqual(toPairs(iterableA), toPairs(iterableB), isEqual, meta);
};
};
/**
* @function areArraysEqual
*
* @description
* are the objects equal in value
*
* @param {Array<any>} objectA the object to test
* @param {Array<any>} objectB the object to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the objects equal
*/
var areObjectsEqual = function areObjectsEqual(objectA, objectB, isEqual, meta) {
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (var index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && isReactElement(objectA) && isReactElement(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key], meta)) {
return false;
}
}
return true;
};
// constants
var isArray = Array.isArray;
var areMapsEqual = createAreIterablesEqual(true);
var areSetsEqual = createAreIterablesEqual(false);
var createComparator = function createComparator(createIsEqual) {
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator; // eslint-disable-line
// eslint-disable-next-line no-use-before-define
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator;

@@ -108,7 +276,8 @@ /**

*
* @param {*} objectA the object to test against
* @param {*} objectB the object to test
* @param {any} objectA the object to test against
* @param {any} objectB the object to test
* @param {any} [meta] an optional meta object that is passed through to all equality test calls
* @returns {boolean} are objectA and objectB equivalent in value
*/
function comparator(objectA, objectB) {
function comparator(objectA, objectB, meta) {
if (sameValueZeroEqual(objectA, objectB)) {

@@ -120,91 +289,54 @@ return true;

if (typeOfA !== typeof objectB) {
if (typeOfA !== typeof objectB || typeOfA !== 'object' || !objectA || !objectB) {
return false;
}
if (typeOfA === 'object' && objectA && objectB) {
var arrayA = Array.isArray(objectA);
var arrayB = Array.isArray(objectB);
if (isPlainObject(objectA) && isPlainObject(objectB)) {
return areObjectsEqual(objectA, objectB, isEqual, meta);
}
var index = void 0;
var arrayA = isArray(objectA);
var arrayB = isArray(objectB);
if (arrayA || arrayB) {
if (arrayA !== arrayB || objectA.length !== objectB.length) {
return false;
}
if (arrayA || arrayB) {
return arrayA === arrayB && areArraysEqual(objectA, objectB, isEqual, meta);
}
for (index = 0; index < objectA.length; index++) {
if (!isEqual(objectA[index], objectB[index])) {
return false;
}
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
return true;
}
if (dateA || dateB) {
return dateA === dateB && sameValueZeroEqual(objectA.getTime(), objectB.getTime());
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if (dateA || dateB) {
return dateA === dateB && sameValueZeroEqual(objectA.getTime(), objectB.getTime());
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if (isPromiseLike(objectA) || isPromiseLike(objectB)) {
return objectA === objectB;
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
if (HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if (isPromiseLike(objectA) || isPromiseLike(objectB)) {
return objectA === objectB;
if (mapA || mapB) {
return mapA === mapB && areMapsEqual(objectA, objectB, comparator, meta);
}
}
if (HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if (HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (mapA || mapB) {
return mapA === mapB && areIterablesEqual(objectA, objectB, comparator, true);
}
if (setA || setB) {
return setA === setB && areSetsEqual(objectA, objectB, comparator, meta);
}
if (HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (setA || setB) {
return setA === setB && areIterablesEqual(objectA, objectB, comparator, false);
}
}
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!Object.prototype.hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && isReactElement(objectA) && isReactElement(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key])) {
return false;
}
}
return true;
}
return false;
return areObjectsEqual(objectA, objectB, isEqual, meta);
}

@@ -217,2 +349,4 @@

var circularDeepEqual = createComparator(createCircularEqual());
var circularShallowEqual = createComparator(createCircularEqual(sameValueZeroEqual));
var deepEqual = createComparator();

@@ -224,2 +358,4 @@ var shallowEqual = createComparator(function () {

var index = {
circularDeep: circularDeepEqual,
circularShallow: circularShallowEqual,
createCustom: createComparator,

@@ -233,2 +369,4 @@ deep: deepEqual,

exports.sameValueZeroEqual = sameValueZeroEqual;
exports.circularDeepEqual = circularDeepEqual;
exports.circularShallowEqual = circularShallowEqual;
exports.deepEqual = deepEqual;

@@ -235,0 +373,0 @@ exports.shallowEqual = shallowEqual;

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

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.fe={})}(this,function(e){"use strict";var t=function(e,t){return e===t||e!=e&&t!=t},n=function(e){return"function"==typeof e.then},r=function(e){return!(!e.$$typeof||!e._store)},i=function(e){var t={keys:new Array(e.size),values:new Array(e.size)},n=0;return e.forEach(function(e,r){t.keys[n]=r,t.values[n++]=e}),t},o=function(e,t,n,r){if(e.size!==t.size)return!1;var o=i(e),u=i(t);return r?n(o.keys,u.keys)&&n(o.values,u.values):n(o.values,u.values)},u="function"==typeof Map,a="function"==typeof Set,f=function(e){var i="function"==typeof e?e(f):f;function f(e,s){if(t(e,s))return!0;var l=typeof e;if(l!==typeof s)return!1;if("object"===l&&e&&s){var c=Array.isArray(e),y=Array.isArray(s),p=void 0;if(c||y){if(c!==y||e.length!==s.length)return!1;for(p=0;p<e.length;p++)if(!i(e[p],s[p]))return!1;return!0}var v=e instanceof Date,d=s instanceof Date;if(v||d)return v===d&&t(e.getTime(),s.getTime());var g=e instanceof RegExp,h=s instanceof RegExp;if(g||h)return g===h&&e.source===s.source&&e.global===s.global&&e.ignoreCase===s.ignoreCase&&e.multiline===s.multiline&&e.lastIndex===s.lastIndex;if(n(e)||n(s))return e===s;if(u){var m=e instanceof Map,b=s instanceof Map;if(m||b)return m===b&&o(e,s,f,!0)}if(a){var x=e instanceof Set,E=s instanceof Set;if(x||E)return x===E&&o(e,s,f,!1)}var j=Object.keys(e);if(j.length!==Object.keys(s).length)return!1;var k=void 0;for(p=0;p<j.length;p++){if(k=j[p],!Object.prototype.hasOwnProperty.call(s,k))return!1;if(("_owner"!==k||!r(e)||!r(s))&&!i(e[k],s[k]))return!1}return!0}return!1}return f},s=f(),l=f(function(){return t}),c={createCustom:f,deep:s,sameValueZero:t,shallow:l};e.createCustomEqual=f,e.sameValueZeroEqual=t,e.deepEqual=s,e.shallowEqual=l,e.default=c,Object.defineProperty(e,"__esModule",{value:!0})});
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.fe={})}(this,function(e){"use strict";var n="function"==typeof Map,t="function"==typeof Set,r="function"==typeof WeakSet,u=Object.prototype.hasOwnProperty,o=function(e,n){return e&&"object"==typeof e&&n.add(e)},i=function(e,n){return e===n||e!=e&&n!=n},a=function(e){return e.constructor===Object},f=function(e){return"function"==typeof e.then},c=function(e){return!(!e.$$typeof||!e._store)},s=function(e){return function(n){var t=e||n;return function(e,n){var u=arguments.length>2&&void 0!==arguments[2]?arguments[2]:r?new WeakSet:Object.create({_values:[],add:function(e){this._values.push(e)},has:function(e){return!!~this._values.indexOf(e)}}),i=u.has(e),a=u.has(n);return i||a?i&&a:(o(e,u),o(n,u),t(e,n,u))}}},l=function(e){var n={keys:new Array(e.size),values:new Array(e.size)},t=0;return e.forEach(function(e,r){n.keys[t]=r,n.values[t++]=e}),n},p=function(e,n,t,r){if(e.length!==n.length)return!1;for(var u=0;u<e.length;u++)if(!t(e[u],n[u],r))return!1;return!0},v=function(e){var n=e?function(e,n,t,r){return t(e.keys,n.keys)&&t(e.values,n.values,r)}:function(e,n,t,r){return t(e.values,n.values,r)};return function(e,t,r,u){return e.size===t.size&&n(l(e),l(t),r,u)}},y=function(e,n,t,r){var o=Object.keys(e);if(o.length!==Object.keys(n).length)return!1;for(var i=void 0,a=0;a<o.length;a++){if(i=o[a],!u.call(n,i))return!1;if(("_owner"!==i||!c(e)||!c(n))&&!t(e[i],n[i],r))return!1}return!0},d=Array.isArray,h=v(!0),g=v(!1),b=function(e){var r="function"==typeof e?e(u):u;function u(e,o,c){if(i(e,o))return!0;var s=typeof e;if(s!==typeof o||"object"!==s||!e||!o)return!1;if(a(e)&&a(o))return y(e,o,r,c);var l=d(e),v=d(o);if(l||v)return l===v&&p(e,o,r,c);var b=e instanceof Date,m=o instanceof Date;if(b||m)return b===m&&i(e.getTime(),o.getTime());var j=e instanceof RegExp,w=o instanceof RegExp;if(j||w)return j===w&&e.source===o.source&&e.global===o.global&&e.ignoreCase===o.ignoreCase&&e.multiline===o.multiline&&e.lastIndex===o.lastIndex;if(f(e)||f(o))return e===o;if(n){var E=e instanceof Map,k=o instanceof Map;if(E||k)return E===k&&h(e,o,u,c)}if(t){var x=e instanceof Set,O=o instanceof Set;if(x||O)return x===O&&g(e,o,u,c)}return y(e,o,r,c)}return u},m=b(s()),j=b(s(i)),w=b(),E=b(function(){return i}),k={circularDeep:m,circularShallow:j,createCustom:b,deep:w,sameValueZero:i,shallow:E};e.createCustomEqual=b,e.sameValueZeroEqual=i,e.circularDeepEqual=m,e.circularShallowEqual=j,e.deepEqual=w,e.shallowEqual=E,e.default=k,Object.defineProperty(e,"__esModule",{value:!0})});

@@ -0,9 +1,15 @@

// constants
import { HAS_MAP_SUPPORT, HAS_SET_SUPPORT } from './constants';
// utils
import { areIterablesEqual, isPromiseLike, isReactElement, sameValueZeroEqual } from './utils';
import { areArraysEqual, areObjectsEqual, createAreIterablesEqual, isPlainObject, isPromiseLike, isReactElement, sameValueZeroEqual } from './utils';
var HAS_MAP_SUPPORT = typeof Map === 'function';
var HAS_SET_SUPPORT = typeof Set === 'function';
var isArray = Array.isArray;
var areMapsEqual = createAreIterablesEqual(true);
var areSetsEqual = createAreIterablesEqual(false);
var createComparator = function createComparator(createIsEqual) {
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator; // eslint-disable-line
// eslint-disable-next-line no-use-before-define
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator;

@@ -16,7 +22,8 @@ /**

*
* @param {*} objectA the object to test against
* @param {*} objectB the object to test
* @param {any} objectA the object to test against
* @param {any} objectB the object to test
* @param {any} [meta] an optional meta object that is passed through to all equality test calls
* @returns {boolean} are objectA and objectB equivalent in value
*/
function comparator(objectA, objectB) {
function comparator(objectA, objectB, meta) {
if (sameValueZeroEqual(objectA, objectB)) {

@@ -28,91 +35,54 @@ return true;

if (typeOfA !== typeof objectB) {
if (typeOfA !== typeof objectB || typeOfA !== 'object' || !objectA || !objectB) {
return false;
}
if (typeOfA === 'object' && objectA && objectB) {
var arrayA = Array.isArray(objectA);
var arrayB = Array.isArray(objectB);
if (isPlainObject(objectA) && isPlainObject(objectB)) {
return areObjectsEqual(objectA, objectB, isEqual, meta);
}
var index = void 0;
var arrayA = isArray(objectA);
var arrayB = isArray(objectB);
if (arrayA || arrayB) {
if (arrayA !== arrayB || objectA.length !== objectB.length) {
return false;
}
if (arrayA || arrayB) {
return arrayA === arrayB && areArraysEqual(objectA, objectB, isEqual, meta);
}
for (index = 0; index < objectA.length; index++) {
if (!isEqual(objectA[index], objectB[index])) {
return false;
}
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
return true;
}
if (dateA || dateB) {
return dateA === dateB && sameValueZeroEqual(objectA.getTime(), objectB.getTime());
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if (dateA || dateB) {
return dateA === dateB && sameValueZeroEqual(objectA.getTime(), objectB.getTime());
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if (isPromiseLike(objectA) || isPromiseLike(objectB)) {
return objectA === objectB;
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
if (HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if (isPromiseLike(objectA) || isPromiseLike(objectB)) {
return objectA === objectB;
if (mapA || mapB) {
return mapA === mapB && areMapsEqual(objectA, objectB, comparator, meta);
}
}
if (HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if (HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (mapA || mapB) {
return mapA === mapB && areIterablesEqual(objectA, objectB, comparator, true);
}
if (setA || setB) {
return setA === setB && areSetsEqual(objectA, objectB, comparator, meta);
}
if (HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (setA || setB) {
return setA === setB && areIterablesEqual(objectA, objectB, comparator, false);
}
}
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!Object.prototype.hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && isReactElement(objectA) && isReactElement(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key])) {
return false;
}
}
return true;
}
return false;
return areObjectsEqual(objectA, objectB, isEqual, meta);
}

@@ -119,0 +89,0 @@

@@ -5,6 +5,8 @@ // comparator

// utils
import { sameValueZeroEqual } from './utils';
import { createCircularEqual, sameValueZeroEqual } from './utils';
export { createCustomEqual, sameValueZeroEqual };
export var circularDeepEqual = createCustomEqual(createCircularEqual());
export var circularShallowEqual = createCustomEqual(createCircularEqual(sameValueZeroEqual));
export var deepEqual = createCustomEqual();

@@ -16,2 +18,4 @@ export var shallowEqual = createCustomEqual(function () {

export default {
circularDeep: circularDeepEqual,
circularShallow: circularShallowEqual,
createCustom: createCustomEqual,

@@ -18,0 +22,0 @@ deep: deepEqual,

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

// constants
import { HAS_WEAKSET_SUPPORT } from './constants';
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @function addObjectToCache
*
* @description
* add object to cache if it is indeed an object
*
* @param {any} object the object to potentially add to the cache
* @param {Object|WeakSet} cache the cache to add to
* @returns {void}
*/
export var addObjectToCache = function addObjectToCache(object, cache) {
return object && typeof object === 'object' && cache.add(object);
};
/**
* @function sameValueZeroEqual

@@ -7,4 +26,4 @@ *

*
* @param {*} objectA the object to compare against
* @param {*} objectB the object to test
* @param {any} objectA the object to compare against
* @param {any} objectB the object to test
* @returns {boolean} are the objects equal by the SameValueZero principle

@@ -17,2 +36,15 @@ */

/**
* @function isPlainObject
*
* @description
* is the object a plain object
*
* @param {any} object the object to test
* @returns {boolean} is the object a plain object
*/
export var isPlainObject = function isPlainObject(object) {
return object.constructor === Object;
};
/**
* @function isPromiseLike

@@ -44,2 +76,53 @@ *

/**
* @function getNewCache
*
* @description
* get a new cache object to prevent circular references
*
* @returns {Object|Weakset} the new cache object
*/
export var getNewCache = function getNewCache() {
return HAS_WEAKSET_SUPPORT ? new WeakSet() : Object.create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
}
});
};
/**
* @function createCircularEqual
*
* @description
* create a custom isEqual handler specific to circular objects
*
* @param {funtion} [isEqual] the isEqual comparator to use instead of isDeepEqual
* @returns {function(any, any): boolean}
*/
export var createCircularEqual = function createCircularEqual(isEqual) {
return function (isDeepEqual) {
var comparator = isEqual || isDeepEqual;
return function (objectA, objectB) {
var cache = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getNewCache();
var cacheHasA = cache.has(objectA);
var cacheHasB = cache.has(objectB);
if (cacheHasA || cacheHasB) {
return cacheHasA && cacheHasB;
}
addObjectToCache(objectA, cache);
addObjectToCache(objectB, cache);
return comparator(objectA, objectB, cache);
};
};
};
/**
* @function toPairs

@@ -64,22 +147,90 @@ *

/**
* @function areIterablesEqual
* @function areArraysEqual
*
* @description
* determine if the iterables are equivalent in value
* are the arrays equal in value
*
* @param {Map|Set} objectA the object to test
* @param {Map|Set} objectB the object to test against
* @param {function} comparator the comparator to determine deep equality
* @param {boolean} shouldCompareKeys should the keys be tested in the equality comparison
* @returns {boolean} are the objects equal in value
* @param {Array<any>} arrayA the array to test
* @param {Array<any>} arrayB the array to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the arrays equal
*/
export var areIterablesEqual = function areIterablesEqual(objectA, objectB, comparator, shouldCompareKeys) {
if (objectA.size !== objectB.size) {
export var areArraysEqual = function areArraysEqual(arrayA, arrayB, isEqual, meta) {
if (arrayA.length !== arrayB.length) {
return false;
}
var pairsA = toPairs(objectA);
var pairsB = toPairs(objectB);
for (var index = 0; index < arrayA.length; index++) {
if (!isEqual(arrayA[index], arrayB[index], meta)) {
return false;
}
}
return shouldCompareKeys ? comparator(pairsA.keys, pairsB.keys) && comparator(pairsA.values, pairsB.values) : comparator(pairsA.values, pairsB.values);
return true;
};
export var createAreIterablesEqual = function createAreIterablesEqual(shouldCompareKeys) {
/**
* @function areIterablesEqual
*
* @description
* determine if the iterables are equivalent in value
*
* @param {Array<Array<any>>} pairsA the pairs to test
* @param {Array<Array<any>>} pairsB the pairs to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the cache possibly being used
* @returns {boolean} are the objects equal in value
*/
var areIterablesEqual = shouldCompareKeys ? function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.keys, pairsB.keys) && isEqual(pairsA.values, pairsB.values, meta);
} : function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.values, pairsB.values, meta);
};
return function (iterableA, iterableB, isEqual, meta) {
return iterableA.size === iterableB.size && areIterablesEqual(toPairs(iterableA), toPairs(iterableB), isEqual, meta);
};
};
/**
* @function areArraysEqual
*
* @description
* are the objects equal in value
*
* @param {Array<any>} objectA the object to test
* @param {Array<any>} objectB the object to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the objects equal
*/
export var areObjectsEqual = function areObjectsEqual(objectA, objectB, isEqual, meta) {
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (var index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && isReactElement(objectA) && isReactElement(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key], meta)) {
return false;
}
}
return true;
};

@@ -1,4 +0,6 @@

declare type Comparator = (objectA: any, objectB: any) => boolean;
declare type Comparator = (objectA: any, objectB: any, meta: any) => boolean;
export declare function createCustomEqual(createIsEqual?: Comparator): Comparator;
export declare function circularDeepEqual(objectA: any, objectB: any): boolean;
export declare function circularShallowEqual(objectA: any, objectB: any): boolean;
export declare function deepEqual(objectA: any, objectB: any): boolean;

@@ -9,8 +11,10 @@ export declare function shallowEqual(objectA: any, objectB: any): boolean;

type module = {
createCustom: typeof createCustomEqual,
deep: typeof deepEqual,
shallow: typeof shallowEqual,
sameValueZero: typeof sameValueZeroEqual,
circularDeep: typeof circularDeepEqual;
circularShallow: typeof circularShallowEqual;
createCustom: typeof createCustomEqual;
deep: typeof deepEqual;
shallow: typeof shallowEqual;
sameValueZero: typeof sameValueZeroEqual;
};
export default module;

@@ -5,10 +5,18 @@ 'use strict';

var _constants = require('./constants');
var _utils = require('./utils');
var HAS_MAP_SUPPORT = typeof Map === 'function'; // utils
// constants
var isArray = Array.isArray;
var HAS_SET_SUPPORT = typeof Set === 'function';
// utils
var areMapsEqual = (0, _utils.createAreIterablesEqual)(true);
var areSetsEqual = (0, _utils.createAreIterablesEqual)(false);
var createComparator = function createComparator(createIsEqual) {
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator; // eslint-disable-line
// eslint-disable-next-line no-use-before-define
var isEqual = typeof createIsEqual === 'function' ? createIsEqual(comparator) : comparator;

@@ -21,7 +29,8 @@ /**

*
* @param {*} objectA the object to test against
* @param {*} objectB the object to test
* @param {any} objectA the object to test against
* @param {any} objectB the object to test
* @param {any} [meta] an optional meta object that is passed through to all equality test calls
* @returns {boolean} are objectA and objectB equivalent in value
*/
function comparator(objectA, objectB) {
function comparator(objectA, objectB, meta) {
if ((0, _utils.sameValueZeroEqual)(objectA, objectB)) {

@@ -33,91 +42,54 @@ return true;

if (typeOfA !== typeof objectB) {
if (typeOfA !== typeof objectB || typeOfA !== 'object' || !objectA || !objectB) {
return false;
}
if (typeOfA === 'object' && objectA && objectB) {
var arrayA = Array.isArray(objectA);
var arrayB = Array.isArray(objectB);
if ((0, _utils.isPlainObject)(objectA) && (0, _utils.isPlainObject)(objectB)) {
return (0, _utils.areObjectsEqual)(objectA, objectB, isEqual, meta);
}
var index = void 0;
var arrayA = isArray(objectA);
var arrayB = isArray(objectB);
if (arrayA || arrayB) {
if (arrayA !== arrayB || objectA.length !== objectB.length) {
return false;
}
if (arrayA || arrayB) {
return arrayA === arrayB && (0, _utils.areArraysEqual)(objectA, objectB, isEqual, meta);
}
for (index = 0; index < objectA.length; index++) {
if (!isEqual(objectA[index], objectB[index])) {
return false;
}
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
return true;
}
if (dateA || dateB) {
return dateA === dateB && (0, _utils.sameValueZeroEqual)(objectA.getTime(), objectB.getTime());
}
var dateA = objectA instanceof Date;
var dateB = objectB instanceof Date;
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if (dateA || dateB) {
return dateA === dateB && (0, _utils.sameValueZeroEqual)(objectA.getTime(), objectB.getTime());
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
var regexpA = objectA instanceof RegExp;
var regexpB = objectB instanceof RegExp;
if ((0, _utils.isPromiseLike)(objectA) || (0, _utils.isPromiseLike)(objectB)) {
return objectA === objectB;
}
if (regexpA || regexpB) {
return regexpA === regexpB && objectA.source === objectB.source && objectA.global === objectB.global && objectA.ignoreCase === objectB.ignoreCase && objectA.multiline === objectB.multiline && objectA.lastIndex === objectB.lastIndex;
}
if (_constants.HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if ((0, _utils.isPromiseLike)(objectA) || (0, _utils.isPromiseLike)(objectB)) {
return objectA === objectB;
if (mapA || mapB) {
return mapA === mapB && areMapsEqual(objectA, objectB, comparator, meta);
}
}
if (HAS_MAP_SUPPORT) {
var mapA = objectA instanceof Map;
var mapB = objectB instanceof Map;
if (_constants.HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (mapA || mapB) {
return mapA === mapB && (0, _utils.areIterablesEqual)(objectA, objectB, comparator, true);
}
if (setA || setB) {
return setA === setB && areSetsEqual(objectA, objectB, comparator, meta);
}
if (HAS_SET_SUPPORT) {
var setA = objectA instanceof Set;
var setB = objectB instanceof Set;
if (setA || setB) {
return setA === setB && (0, _utils.areIterablesEqual)(objectA, objectB, comparator, false);
}
}
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!Object.prototype.hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && (0, _utils.isReactElement)(objectA) && (0, _utils.isReactElement)(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key])) {
return false;
}
}
return true;
}
return false;
return (0, _utils.areObjectsEqual)(objectA, objectB, isEqual, meta);
}

@@ -124,0 +96,0 @@

'use strict';
exports.__esModule = true;
exports.shallowEqual = exports.deepEqual = exports.sameValueZeroEqual = exports.createCustomEqual = undefined;
exports.shallowEqual = exports.deepEqual = exports.circularShallowEqual = exports.circularDeepEqual = exports.sameValueZeroEqual = exports.createCustomEqual = undefined;

@@ -20,2 +20,4 @@ var _comparator = require('./comparator');

var circularDeepEqual = exports.circularDeepEqual = (0, _comparator2.default)((0, _utils.createCircularEqual)());
var circularShallowEqual = exports.circularShallowEqual = (0, _comparator2.default)((0, _utils.createCircularEqual)(_utils.sameValueZeroEqual));
var deepEqual = exports.deepEqual = (0, _comparator2.default)();

@@ -27,2 +29,4 @@ var shallowEqual = exports.shallowEqual = (0, _comparator2.default)(function () {

exports.default = {
circularDeep: circularDeepEqual,
circularShallow: circularShallowEqual,
createCustom: _comparator2.default,

@@ -29,0 +33,0 @@ deep: deepEqual,

'use strict';
exports.__esModule = true;
exports.areObjectsEqual = exports.createAreIterablesEqual = exports.areArraysEqual = exports.toPairs = exports.createCircularEqual = exports.getNewCache = exports.isReactElement = exports.isPromiseLike = exports.isPlainObject = exports.sameValueZeroEqual = exports.addObjectToCache = undefined;
var _constants = require('./constants');
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @function addObjectToCache
*
* @description
* add object to cache if it is indeed an object
*
* @param {any} object the object to potentially add to the cache
* @param {Object|WeakSet} cache the cache to add to
* @returns {void}
*/
// constants
var addObjectToCache = exports.addObjectToCache = function addObjectToCache(object, cache) {
return object && typeof object === 'object' && cache.add(object);
};
/**
* @function sameValueZeroEqual

@@ -10,4 +31,4 @@ *

*
* @param {*} objectA the object to compare against
* @param {*} objectB the object to test
* @param {any} objectA the object to compare against
* @param {any} objectB the object to test
* @returns {boolean} are the objects equal by the SameValueZero principle

@@ -20,2 +41,15 @@ */

/**
* @function isPlainObject
*
* @description
* is the object a plain object
*
* @param {any} object the object to test
* @returns {boolean} is the object a plain object
*/
var isPlainObject = exports.isPlainObject = function isPlainObject(object) {
return object.constructor === Object;
};
/**
* @function isPromiseLike

@@ -47,2 +81,53 @@ *

/**
* @function getNewCache
*
* @description
* get a new cache object to prevent circular references
*
* @returns {Object|Weakset} the new cache object
*/
var getNewCache = exports.getNewCache = function getNewCache() {
return _constants.HAS_WEAKSET_SUPPORT ? new WeakSet() : Object.create({
_values: [],
add: function add(value) {
this._values.push(value);
},
has: function has(value) {
return !!~this._values.indexOf(value);
}
});
};
/**
* @function createCircularEqual
*
* @description
* create a custom isEqual handler specific to circular objects
*
* @param {funtion} [isEqual] the isEqual comparator to use instead of isDeepEqual
* @returns {function(any, any): boolean}
*/
var createCircularEqual = exports.createCircularEqual = function createCircularEqual(isEqual) {
return function (isDeepEqual) {
var comparator = isEqual || isDeepEqual;
return function (objectA, objectB) {
var cache = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getNewCache();
var cacheHasA = cache.has(objectA);
var cacheHasB = cache.has(objectB);
if (cacheHasA || cacheHasB) {
return cacheHasA && cacheHasB;
}
addObjectToCache(objectA, cache);
addObjectToCache(objectB, cache);
return comparator(objectA, objectB, cache);
};
};
};
/**
* @function toPairs

@@ -67,22 +152,90 @@ *

/**
* @function areIterablesEqual
* @function areArraysEqual
*
* @description
* determine if the iterables are equivalent in value
* are the arrays equal in value
*
* @param {Map|Set} objectA the object to test
* @param {Map|Set} objectB the object to test against
* @param {function} comparator the comparator to determine deep equality
* @param {boolean} shouldCompareKeys should the keys be tested in the equality comparison
* @returns {boolean} are the objects equal in value
* @param {Array<any>} arrayA the array to test
* @param {Array<any>} arrayB the array to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the arrays equal
*/
var areIterablesEqual = exports.areIterablesEqual = function areIterablesEqual(objectA, objectB, comparator, shouldCompareKeys) {
if (objectA.size !== objectB.size) {
var areArraysEqual = exports.areArraysEqual = function areArraysEqual(arrayA, arrayB, isEqual, meta) {
if (arrayA.length !== arrayB.length) {
return false;
}
var pairsA = toPairs(objectA);
var pairsB = toPairs(objectB);
for (var index = 0; index < arrayA.length; index++) {
if (!isEqual(arrayA[index], arrayB[index], meta)) {
return false;
}
}
return shouldCompareKeys ? comparator(pairsA.keys, pairsB.keys) && comparator(pairsA.values, pairsB.values) : comparator(pairsA.values, pairsB.values);
return true;
};
var createAreIterablesEqual = exports.createAreIterablesEqual = function createAreIterablesEqual(shouldCompareKeys) {
/**
* @function areIterablesEqual
*
* @description
* determine if the iterables are equivalent in value
*
* @param {Array<Array<any>>} pairsA the pairs to test
* @param {Array<Array<any>>} pairsB the pairs to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the cache possibly being used
* @returns {boolean} are the objects equal in value
*/
var areIterablesEqual = shouldCompareKeys ? function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.keys, pairsB.keys) && isEqual(pairsA.values, pairsB.values, meta);
} : function (pairsA, pairsB, isEqual, meta) {
return isEqual(pairsA.values, pairsB.values, meta);
};
return function (iterableA, iterableB, isEqual, meta) {
return iterableA.size === iterableB.size && areIterablesEqual(toPairs(iterableA), toPairs(iterableB), isEqual, meta);
};
};
/**
* @function areArraysEqual
*
* @description
* are the objects equal in value
*
* @param {Array<any>} objectA the object to test
* @param {Array<any>} objectB the object to test against
* @param {function} isEqual the comparator to determine equality
* @param {any} meta the meta object to pass through
* @returns {boolean} are the objects equal
*/
var areObjectsEqual = exports.areObjectsEqual = function areObjectsEqual(objectA, objectB, isEqual, meta) {
var keysA = Object.keys(objectA);
if (keysA.length !== Object.keys(objectB).length) {
return false;
}
var key = void 0;
for (var index = 0; index < keysA.length; index++) {
key = keysA[index];
if (!hasOwnProperty.call(objectB, key)) {
return false;
}
// if a react element, ignore the "_owner" key because its not necessary for equality comparisons
if (key === '_owner' && isReactElement(objectA) && isReactElement(objectB)) {
continue;
}
if (!isEqual(objectA[key], objectB[key], meta)) {
return false;
}
}
return true;
};

@@ -26,3 +26,3 @@ {

"babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.1",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",

@@ -56,3 +56,3 @@ "babel-preset-stage-2": "^6.24.1",

"underscore": "^1.9.0",
"webpack": "^4.8.1",
"webpack": "^4.8.3",
"webpack-cli": "^2.1.3",

@@ -98,3 +98,3 @@ "webpack-dev-server": "^3.1.4"

},
"version": "1.4.1"
"version": "1.5.0"
}

@@ -7,3 +7,3 @@ # fast-equals

Perform [blazing fast](#benchmarks) equality comparisons (either deep or shallow) on two objects passed. It has no dependencies, and is ~995 bytes when minified and gzipped.
Perform [blazing fast](#benchmarks) equality comparisons (either deep or shallow) on two objects passed. It has no dependencies, and is ~1.3kB when minified and gzipped.

@@ -19,3 +19,3 @@ Unlike most equality validation libraries, the following types are handled out-of-the-box:

You can also create a custom nested comparator, for specific scenarios ([see below](#createcustomequal)).
Starting with version `1.5.0`, circular objects are supported for both deep and shallow equality (see [`circularDeepEqual`](#circulardeepequal) and [`circularShallowEqual`](#circularshallowequal)). You can also create a custom nested comparator, for specific scenarios ([see below](#createcustomequal)).

@@ -29,2 +29,4 @@ ## Table of contents

* [sameValueZeroEqual](#samevaluezeroequal)
* [circularDeepEqual](#circulardeepequal)
* [circularShallowEqual](#circularshallowequal)
* [createCustomEqual](#createcustomequal)

@@ -110,2 +112,39 @@ * [Benchmarks](#benchmarks)

#### circularDeepEqual
_Aliased on the default export as `fe.circularDeep`_
Performs the same comparison as `deepEqual` but supports circular objects. It is slower than `deepEqual`, so only use if you know circular objects are present.
```javascript
function Circular(value) {
this.me = {
deeply: {
nested: {
reference: this
}
},
value
};
}
console.log(circularDeepEqual(new Circular("foo"), new Circular("foo"))); // true
console.log(circularDeepEqual(new Circular("foo"), new Circular("bar"))); // false
```
#### circularShallowEqual
_Aliased on the default export as `fe.circularShallow`_
Performs the same comparison as `shallowequal` but supports circular objects. It is slower than `shallowEqual`, so only use if you know circular objects are present.
```javascript
const array = ["foo"];
array.push(array);
console.log(circularShallowEqual(array, ["foo", array])); // true
console.log(circularShallowEqual(array, [array])); // false
```
#### createCustomEqual

@@ -117,24 +156,30 @@

A common use case for this is to handle circular objects (which `fast-equals` does not handle by default). Example:
The signature is as follows:
```javascript
createCustomEqual(deepEqual: function) => (objectA: any, objectB: any, meta: any) => boolean;
```
The `meta` parameter is whatever you want it to be. It will be passed through to all equality checks, and is meant specifically for use with custom equality methods. For example, with the `circularDeepEqual` and `circularShallowEqual` methods, it is used to pass through a cache of processed objects.
An example for a custom equality comparison that also checks against values in the meta object:
```javascript
import { createCustomEqual } from "fast-equals";
import decircularize from "decircularize";
const isDeepEqualCircular = createCustomEqual(comparator => {
return (objectA, objectB) => {
return comparator(decircularize(objectA), decircularize(objectB));
const isDeepEqualOrFooMatchesMeta = createCustomEqual(deepEqual => {
return (objectA, objectB, meta) => {
return (
objectA.foo === meta ||
objectB.foo === meta ||
deepEqual(objectA, objectB, meta)
);
};
});
const objectA = {};
const objectB = {};
const objectA = { foo: "bar" };
const objectB = { foo: "baz" };
const meta = "bar";
objectA.a = objectA;
objectA.b = objectB;
objectB.a = objectA;
objectB.b = objectB;
console.log(isDeepEqualCircular(objectA, objectB)); // true
console.log(isDeepEqualOrFooMatchesMeta(objectA, objectB)); // true
```

@@ -144,3 +189,3 @@

All benchmarks are based on averages of running comparisons based on the following object types:
All benchmarks were performed on an i7 8-core Arch Linux laptop with 16GB of memory using NodeJS version `8.11.1`, and are based on averages of running comparisons based deep equality on the following object types:

@@ -156,14 +201,15 @@ * Primitives (`String`, `Number`, `null`, `undefined`)

| | Operations / second | Relative margin of error |
| ---------------------- | ------------------- | ------------------------ |
| **fast-equals** | **146,995** | **0.50%** |
| nano-equal | 107,419 | 0.98% |
| fast-deep-equal | 105,428 | 0.67% |
| shallow-equal-fuzzy | 104,629 | 1.25% |
| react-fast-compare | 101,649 | 1.16% |
| underscore.isEqual | 67,090 | 0.57% |
| deep-equal | 30,527 | 0.61% |
| lodash.isEqual | 27,763 | 0.60% |
| deep-eql | 17,028 | 0.75% |
| assert.deepStrictEqual | 1,593 | 0.89% |
| | Operations / second | Relative margin of error |
| -------------------------- | ------------------- | ------------------------ |
| **fast-equals** | **137,723** | **0.72%** |
| nano-equal | 105,151 | 0.89% |
| shallow-equal-fuzzy | 101,882 | 0.88% |
| react-fast-compare | 98,816 | 0.88% |
| fast-deep-equal | 92,431 | 0.81% |
| underscore.isEqual | 61,933 | 0.74% |
| **fast-equals (circular)** | **55,108** | **0.83%** |
| deep-equal | 30,677 | 0.49% |
| lodash.isEqual | 26,706 | 0.63% |
| deep-eql | 16,651 | 0.50% |
| assert.deepStrictEqual | 1,551 | 0.86% |

@@ -170,0 +216,0 @@ Caveats that impact the benchmark (and accuracy of comparison):

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