fast-equals
Advanced tools
Comparing version 2.0.1 to 2.0.2
# fast-equals CHANGELOG | ||
## 2.0.2 | ||
- Optimize iterables comparisons to not double-iterate | ||
- Optimize loop-based comparisons for speed | ||
- Improve cache handling in circular handlers | ||
- Improve stability of memory by reducing variable instantiation | ||
## 2.0.1 | ||
@@ -4,0 +11,0 @@ |
@@ -8,65 +8,2 @@ 'use strict'; | ||
/** | ||
* @function addToCache | ||
* | ||
* add object to cache if an object | ||
* | ||
* @param value the value to potentially add to cache | ||
* @param cache the cache to add to | ||
*/ | ||
function addToCache(value, cache) { | ||
if (value && typeof value === 'object') { | ||
cache.add(value); | ||
} | ||
} | ||
/** | ||
* @function hasPair | ||
* | ||
* @description | ||
* does the `pairToMatch` exist in the list of `pairs` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param pairs the pairs to compare against | ||
* @param pairToMatch the pair to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the pair exist in the pairs provided | ||
*/ | ||
function hasPair(pairs, pairToMatch, isEqual, meta) { | ||
var length = pairs.length; | ||
var pair; | ||
for (var index = 0; index < length; index++) { | ||
pair = pairs[index]; | ||
if (isEqual(pair[0], pairToMatch[0], meta) && | ||
isEqual(pair[1], pairToMatch[1], meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function hasValue | ||
* | ||
* @description | ||
* does the `valueToMatch` exist in the list of `values` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param values the values to compare against | ||
* @param valueToMatch the value to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the value exist in the values provided | ||
*/ | ||
function hasValue(values, valueToMatch, isEqual, meta) { | ||
var length = values.length; | ||
for (var index = 0; index < length; index++) { | ||
if (isEqual(values[index], valueToMatch, meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function sameValueZeroEqual | ||
* | ||
* @description | ||
* are the values passed strictly equal or both NaN | ||
@@ -82,5 +19,2 @@ * | ||
/** | ||
* @function isPlainObject | ||
* | ||
* @description | ||
* is the value a plain object | ||
@@ -95,5 +29,2 @@ * | ||
/** | ||
* @function isPromiseLike | ||
* | ||
* @description | ||
* is the value promise-like (meaning it is thenable) | ||
@@ -108,5 +39,2 @@ * | ||
/** | ||
* @function isReactElement | ||
* | ||
* @description | ||
* is the value passed a react element | ||
@@ -121,5 +49,2 @@ * | ||
/** | ||
* @function getNewCacheFallback | ||
* | ||
* @description | ||
* in cases where WeakSet is not supported, creates a new custom | ||
@@ -131,16 +56,13 @@ * object that mimics the necessary API aspects for cache purposes | ||
function getNewCacheFallback() { | ||
return Object.create({ | ||
_values: [], | ||
var values = []; | ||
return { | ||
add: function (value) { | ||
this._values.push(value); | ||
values.push(value); | ||
}, | ||
has: function (value) { | ||
return this._values.indexOf(value) !== -1; | ||
return values.indexOf(value) !== -1; | ||
}, | ||
}); | ||
}; | ||
} | ||
/** | ||
* @function getNewCache | ||
* | ||
* @description | ||
* get a new cache object to prevent circular references | ||
@@ -159,5 +81,2 @@ * | ||
/** | ||
* @function createCircularEqualCreator | ||
* | ||
* @description | ||
* create a custom isEqual handler specific to circular objects | ||
@@ -173,9 +92,17 @@ * | ||
if (cache === void 0) { cache = getNewCache(); } | ||
var hasA = cache.has(a); | ||
var hasB = cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
var isCacheableA = !!a && typeof a === 'object'; | ||
var isCacheableB = !!b && typeof b === 'object'; | ||
if (isCacheableA || isCacheableB) { | ||
var hasA = isCacheableA && cache.has(a); | ||
var hasB = isCacheableB && cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
} | ||
if (isCacheableA) { | ||
cache.add(a); | ||
} | ||
if (isCacheableA) { | ||
cache.add(b); | ||
} | ||
} | ||
addToCache(a, cache); | ||
addToCache(b, cache); | ||
return _comparator(a, b, cache); | ||
@@ -186,39 +113,2 @@ }; | ||
/** | ||
* @function toPairs | ||
* | ||
* @description | ||
* convert the map passed into pairs (meaning an array of [key, value] tuples) | ||
* | ||
* @param map the map to convert to [key, value] pairs (entries) | ||
* @returns the [key, value] pairs | ||
*/ | ||
function toPairs(map) { | ||
var pairs = new Array(map.size); | ||
var index = 0; | ||
map.forEach(function (value, key) { | ||
pairs[index++] = [key, value]; | ||
}); | ||
return pairs; | ||
} | ||
/** | ||
* @function toValues | ||
* | ||
* @description | ||
* convert the set passed into values | ||
* | ||
* @param set the set to convert to values | ||
* @returns the values | ||
*/ | ||
function toValues(set) { | ||
var values = new Array(set.size); | ||
var index = 0; | ||
set.forEach(function (value) { | ||
values[index++] = value; | ||
}); | ||
return values; | ||
} | ||
/** | ||
* @function areArraysEqual | ||
* | ||
* @description | ||
* are the arrays equal in value | ||
@@ -233,7 +123,7 @@ * | ||
function areArraysEqual(a, b, isEqual, meta) { | ||
var length = a.length; | ||
if (b.length !== length) { | ||
var index = a.length; | ||
if (b.length !== index) { | ||
return false; | ||
} | ||
for (var index = 0; index < length; index++) { | ||
while (index-- > 0) { | ||
if (!isEqual(a[index], b[index], meta)) { | ||
@@ -246,5 +136,2 @@ return false; | ||
/** | ||
* @function areMapsEqual | ||
* | ||
* @description | ||
* are the maps equal in value | ||
@@ -259,15 +146,16 @@ * | ||
function areMapsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue, aKey) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue, bKey) { | ||
if (!isValueEqual && isEqual(aKey, bKey, meta)) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var pairsA = toPairs(a); | ||
var pairsB = toPairs(b); | ||
var length = pairsA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasPair(pairsB, pairsA[index], isEqual, meta) || | ||
!hasPair(pairsA, pairsB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
@@ -277,5 +165,2 @@ var OWNER = '_owner'; | ||
/** | ||
* @function areObjectsEqual | ||
* | ||
* @description | ||
* are the objects equal in value | ||
@@ -291,20 +176,22 @@ * | ||
var keysA = keys(a); | ||
var length = keysA.length; | ||
if (keys(b).length !== length) { | ||
var index = keysA.length; | ||
if (keys(b).length !== index) { | ||
return false; | ||
} | ||
var key; | ||
for (var index = 0; index < length; index++) { | ||
key = keysA[index]; | ||
if (!hasOwnProperty(b, key)) { | ||
return false; | ||
} | ||
if (key === OWNER && isReactElement(a)) { | ||
if (!isReactElement(b)) { | ||
if (index) { | ||
var key = void 0; | ||
while (index-- > 0) { | ||
key = keysA[index]; | ||
if (key === OWNER) { | ||
var reactElementA = isReactElement(a); | ||
var reactElementB = isReactElement(b); | ||
if ((reactElementA || reactElementB) && | ||
reactElementA !== reactElementB) { | ||
return false; | ||
} | ||
} | ||
if (!hasOwnProperty(b, key) || !isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
else if (!isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
@@ -314,5 +201,2 @@ return true; | ||
/** | ||
* @function areRegExpsEqual | ||
* | ||
* @description | ||
* are the regExps equal in value | ||
@@ -334,5 +218,2 @@ * | ||
/** | ||
* @function areSetsEqual | ||
* | ||
* @description | ||
* are the sets equal in value | ||
@@ -347,21 +228,20 @@ * | ||
function areSetsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue) { | ||
if (!isValueEqual) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var valuesA = toValues(a); | ||
var valuesB = toValues(b); | ||
var length = valuesA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasValue(valuesB, valuesA[index], isEqual, meta) || | ||
!hasValue(valuesA, valuesB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
var isArray = Array.isArray; | ||
var HAS_MAP_SUPPORT = typeof Map === 'function'; | ||
var HAS_SET_SUPPORT = typeof Set === 'function'; | ||
var OBJECT_TYPEOF = 'object'; | ||
function createComparator(createIsEqual) { | ||
@@ -375,5 +255,2 @@ var isEqual = | ||
/** | ||
* @function comparator | ||
* | ||
* @description | ||
* compare the value of the two objects and return true if they are equivalent in values | ||
@@ -387,23 +264,23 @@ * | ||
function comparator(a, b, meta) { | ||
if (sameValueZeroEqual(a, b)) { | ||
if (a === b) { | ||
return true; | ||
} | ||
if (a && b && typeof a === OBJECT_TYPEOF && typeof b === OBJECT_TYPEOF) { | ||
if (a && b && typeof a === 'object' && typeof b === 'object') { | ||
if (isPlainObject(a) && isPlainObject(b)) { | ||
return areObjectsEqual(a, b, isEqual, meta); | ||
} | ||
var arrayA = isArray(a); | ||
var arrayB = isArray(b); | ||
if (arrayA || arrayB) { | ||
return arrayA === arrayB && areArraysEqual(a, b, isEqual, meta); | ||
var aShape = Array.isArray(a); | ||
var bShape = Array.isArray(b); | ||
if (aShape || bShape) { | ||
return aShape === bShape && areArraysEqual(a, b, isEqual, meta); | ||
} | ||
var aDate = a instanceof Date; | ||
var bDate = b instanceof Date; | ||
if (aDate || bDate) { | ||
return aDate === bDate && sameValueZeroEqual(a.getTime(), b.getTime()); | ||
aShape = a instanceof Date; | ||
bShape = b instanceof Date; | ||
if (aShape || bShape) { | ||
return (aShape === bShape && sameValueZeroEqual(a.getTime(), b.getTime())); | ||
} | ||
var aRegExp = a instanceof RegExp; | ||
var bRegExp = b instanceof RegExp; | ||
if (aRegExp || bRegExp) { | ||
return aRegExp === bRegExp && areRegExpsEqual(a, b); | ||
aShape = a instanceof RegExp; | ||
bShape = b instanceof RegExp; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areRegExpsEqual(a, b); | ||
} | ||
@@ -414,13 +291,13 @@ if (isPromiseLike(a) || isPromiseLike(b)) { | ||
if (HAS_MAP_SUPPORT) { | ||
var aMap = a instanceof Map; | ||
var bMap = b instanceof Map; | ||
if (aMap || bMap) { | ||
return aMap === bMap && areMapsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Map; | ||
bShape = b instanceof Map; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areMapsEqual(a, b, isEqual, meta); | ||
} | ||
} | ||
if (HAS_SET_SUPPORT) { | ||
var aSet = a instanceof Set; | ||
var bSet = b instanceof Set; | ||
if (aSet || bSet) { | ||
return aSet === bSet && areSetsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Set; | ||
bShape = b instanceof Set; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areSetsEqual(a, b, isEqual, meta); | ||
} | ||
@@ -430,3 +307,3 @@ } | ||
} | ||
return false; | ||
return a !== a && b !== b; | ||
} | ||
@@ -436,3 +313,2 @@ return comparator; | ||
// comparator | ||
var deepEqual = createComparator(); | ||
@@ -439,0 +315,0 @@ var shallowEqual = createComparator(function () { return sameValueZeroEqual; }); |
var HAS_WEAKSET_SUPPORT = typeof WeakSet === 'function'; | ||
var keys = Object.keys; | ||
/** | ||
* @function addToCache | ||
* | ||
* add object to cache if an object | ||
* | ||
* @param value the value to potentially add to cache | ||
* @param cache the cache to add to | ||
*/ | ||
function addToCache(value, cache) { | ||
if (value && typeof value === 'object') { | ||
cache.add(value); | ||
} | ||
} | ||
/** | ||
* @function hasPair | ||
* | ||
* @description | ||
* does the `pairToMatch` exist in the list of `pairs` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param pairs the pairs to compare against | ||
* @param pairToMatch the pair to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the pair exist in the pairs provided | ||
*/ | ||
function hasPair(pairs, pairToMatch, isEqual, meta) { | ||
var length = pairs.length; | ||
var pair; | ||
for (var index = 0; index < length; index++) { | ||
pair = pairs[index]; | ||
if (isEqual(pair[0], pairToMatch[0], meta) && | ||
isEqual(pair[1], pairToMatch[1], meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function hasValue | ||
* | ||
* @description | ||
* does the `valueToMatch` exist in the list of `values` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param values the values to compare against | ||
* @param valueToMatch the value to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the value exist in the values provided | ||
*/ | ||
function hasValue(values, valueToMatch, isEqual, meta) { | ||
var length = values.length; | ||
for (var index = 0; index < length; index++) { | ||
if (isEqual(values[index], valueToMatch, meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function sameValueZeroEqual | ||
* | ||
* @description | ||
* are the values passed strictly equal or both NaN | ||
@@ -77,5 +14,2 @@ * | ||
/** | ||
* @function isPlainObject | ||
* | ||
* @description | ||
* is the value a plain object | ||
@@ -90,5 +24,2 @@ * | ||
/** | ||
* @function isPromiseLike | ||
* | ||
* @description | ||
* is the value promise-like (meaning it is thenable) | ||
@@ -103,5 +34,2 @@ * | ||
/** | ||
* @function isReactElement | ||
* | ||
* @description | ||
* is the value passed a react element | ||
@@ -116,5 +44,2 @@ * | ||
/** | ||
* @function getNewCacheFallback | ||
* | ||
* @description | ||
* in cases where WeakSet is not supported, creates a new custom | ||
@@ -126,16 +51,13 @@ * object that mimics the necessary API aspects for cache purposes | ||
function getNewCacheFallback() { | ||
return Object.create({ | ||
_values: [], | ||
var values = []; | ||
return { | ||
add: function (value) { | ||
this._values.push(value); | ||
values.push(value); | ||
}, | ||
has: function (value) { | ||
return this._values.indexOf(value) !== -1; | ||
return values.indexOf(value) !== -1; | ||
}, | ||
}); | ||
}; | ||
} | ||
/** | ||
* @function getNewCache | ||
* | ||
* @description | ||
* get a new cache object to prevent circular references | ||
@@ -154,5 +76,2 @@ * | ||
/** | ||
* @function createCircularEqualCreator | ||
* | ||
* @description | ||
* create a custom isEqual handler specific to circular objects | ||
@@ -168,9 +87,17 @@ * | ||
if (cache === void 0) { cache = getNewCache(); } | ||
var hasA = cache.has(a); | ||
var hasB = cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
var isCacheableA = !!a && typeof a === 'object'; | ||
var isCacheableB = !!b && typeof b === 'object'; | ||
if (isCacheableA || isCacheableB) { | ||
var hasA = isCacheableA && cache.has(a); | ||
var hasB = isCacheableB && cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
} | ||
if (isCacheableA) { | ||
cache.add(a); | ||
} | ||
if (isCacheableA) { | ||
cache.add(b); | ||
} | ||
} | ||
addToCache(a, cache); | ||
addToCache(b, cache); | ||
return _comparator(a, b, cache); | ||
@@ -181,39 +108,2 @@ }; | ||
/** | ||
* @function toPairs | ||
* | ||
* @description | ||
* convert the map passed into pairs (meaning an array of [key, value] tuples) | ||
* | ||
* @param map the map to convert to [key, value] pairs (entries) | ||
* @returns the [key, value] pairs | ||
*/ | ||
function toPairs(map) { | ||
var pairs = new Array(map.size); | ||
var index = 0; | ||
map.forEach(function (value, key) { | ||
pairs[index++] = [key, value]; | ||
}); | ||
return pairs; | ||
} | ||
/** | ||
* @function toValues | ||
* | ||
* @description | ||
* convert the set passed into values | ||
* | ||
* @param set the set to convert to values | ||
* @returns the values | ||
*/ | ||
function toValues(set) { | ||
var values = new Array(set.size); | ||
var index = 0; | ||
set.forEach(function (value) { | ||
values[index++] = value; | ||
}); | ||
return values; | ||
} | ||
/** | ||
* @function areArraysEqual | ||
* | ||
* @description | ||
* are the arrays equal in value | ||
@@ -228,7 +118,7 @@ * | ||
function areArraysEqual(a, b, isEqual, meta) { | ||
var length = a.length; | ||
if (b.length !== length) { | ||
var index = a.length; | ||
if (b.length !== index) { | ||
return false; | ||
} | ||
for (var index = 0; index < length; index++) { | ||
while (index-- > 0) { | ||
if (!isEqual(a[index], b[index], meta)) { | ||
@@ -241,5 +131,2 @@ return false; | ||
/** | ||
* @function areMapsEqual | ||
* | ||
* @description | ||
* are the maps equal in value | ||
@@ -254,15 +141,16 @@ * | ||
function areMapsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue, aKey) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue, bKey) { | ||
if (!isValueEqual && isEqual(aKey, bKey, meta)) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var pairsA = toPairs(a); | ||
var pairsB = toPairs(b); | ||
var length = pairsA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasPair(pairsB, pairsA[index], isEqual, meta) || | ||
!hasPair(pairsA, pairsB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
@@ -272,5 +160,2 @@ var OWNER = '_owner'; | ||
/** | ||
* @function areObjectsEqual | ||
* | ||
* @description | ||
* are the objects equal in value | ||
@@ -286,20 +171,22 @@ * | ||
var keysA = keys(a); | ||
var length = keysA.length; | ||
if (keys(b).length !== length) { | ||
var index = keysA.length; | ||
if (keys(b).length !== index) { | ||
return false; | ||
} | ||
var key; | ||
for (var index = 0; index < length; index++) { | ||
key = keysA[index]; | ||
if (!hasOwnProperty(b, key)) { | ||
return false; | ||
} | ||
if (key === OWNER && isReactElement(a)) { | ||
if (!isReactElement(b)) { | ||
if (index) { | ||
var key = void 0; | ||
while (index-- > 0) { | ||
key = keysA[index]; | ||
if (key === OWNER) { | ||
var reactElementA = isReactElement(a); | ||
var reactElementB = isReactElement(b); | ||
if ((reactElementA || reactElementB) && | ||
reactElementA !== reactElementB) { | ||
return false; | ||
} | ||
} | ||
if (!hasOwnProperty(b, key) || !isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
else if (!isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
@@ -309,5 +196,2 @@ return true; | ||
/** | ||
* @function areRegExpsEqual | ||
* | ||
* @description | ||
* are the regExps equal in value | ||
@@ -329,5 +213,2 @@ * | ||
/** | ||
* @function areSetsEqual | ||
* | ||
* @description | ||
* are the sets equal in value | ||
@@ -342,21 +223,20 @@ * | ||
function areSetsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue) { | ||
if (!isValueEqual) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var valuesA = toValues(a); | ||
var valuesB = toValues(b); | ||
var length = valuesA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasValue(valuesB, valuesA[index], isEqual, meta) || | ||
!hasValue(valuesA, valuesB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
var isArray = Array.isArray; | ||
var HAS_MAP_SUPPORT = typeof Map === 'function'; | ||
var HAS_SET_SUPPORT = typeof Set === 'function'; | ||
var OBJECT_TYPEOF = 'object'; | ||
function createComparator(createIsEqual) { | ||
@@ -370,5 +250,2 @@ var isEqual = | ||
/** | ||
* @function comparator | ||
* | ||
* @description | ||
* compare the value of the two objects and return true if they are equivalent in values | ||
@@ -382,23 +259,23 @@ * | ||
function comparator(a, b, meta) { | ||
if (sameValueZeroEqual(a, b)) { | ||
if (a === b) { | ||
return true; | ||
} | ||
if (a && b && typeof a === OBJECT_TYPEOF && typeof b === OBJECT_TYPEOF) { | ||
if (a && b && typeof a === 'object' && typeof b === 'object') { | ||
if (isPlainObject(a) && isPlainObject(b)) { | ||
return areObjectsEqual(a, b, isEqual, meta); | ||
} | ||
var arrayA = isArray(a); | ||
var arrayB = isArray(b); | ||
if (arrayA || arrayB) { | ||
return arrayA === arrayB && areArraysEqual(a, b, isEqual, meta); | ||
var aShape = Array.isArray(a); | ||
var bShape = Array.isArray(b); | ||
if (aShape || bShape) { | ||
return aShape === bShape && areArraysEqual(a, b, isEqual, meta); | ||
} | ||
var aDate = a instanceof Date; | ||
var bDate = b instanceof Date; | ||
if (aDate || bDate) { | ||
return aDate === bDate && sameValueZeroEqual(a.getTime(), b.getTime()); | ||
aShape = a instanceof Date; | ||
bShape = b instanceof Date; | ||
if (aShape || bShape) { | ||
return (aShape === bShape && sameValueZeroEqual(a.getTime(), b.getTime())); | ||
} | ||
var aRegExp = a instanceof RegExp; | ||
var bRegExp = b instanceof RegExp; | ||
if (aRegExp || bRegExp) { | ||
return aRegExp === bRegExp && areRegExpsEqual(a, b); | ||
aShape = a instanceof RegExp; | ||
bShape = b instanceof RegExp; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areRegExpsEqual(a, b); | ||
} | ||
@@ -409,13 +286,13 @@ if (isPromiseLike(a) || isPromiseLike(b)) { | ||
if (HAS_MAP_SUPPORT) { | ||
var aMap = a instanceof Map; | ||
var bMap = b instanceof Map; | ||
if (aMap || bMap) { | ||
return aMap === bMap && areMapsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Map; | ||
bShape = b instanceof Map; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areMapsEqual(a, b, isEqual, meta); | ||
} | ||
} | ||
if (HAS_SET_SUPPORT) { | ||
var aSet = a instanceof Set; | ||
var bSet = b instanceof Set; | ||
if (aSet || bSet) { | ||
return aSet === bSet && areSetsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Set; | ||
bShape = b instanceof Set; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areSetsEqual(a, b, isEqual, meta); | ||
} | ||
@@ -425,3 +302,3 @@ } | ||
} | ||
return false; | ||
return a !== a && b !== b; | ||
} | ||
@@ -431,3 +308,2 @@ return comparator; | ||
// comparator | ||
var deepEqual = createComparator(); | ||
@@ -434,0 +310,0 @@ var shallowEqual = createComparator(function () { return sameValueZeroEqual; }); |
(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-equals'] = {})); | ||
}(this, function (exports) { 'use strict'; | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['fast-equals'] = {})); | ||
}(this, (function (exports) { 'use strict'; | ||
@@ -10,65 +10,2 @@ var HAS_WEAKSET_SUPPORT = typeof WeakSet === 'function'; | ||
/** | ||
* @function addToCache | ||
* | ||
* add object to cache if an object | ||
* | ||
* @param value the value to potentially add to cache | ||
* @param cache the cache to add to | ||
*/ | ||
function addToCache(value, cache) { | ||
if (value && typeof value === 'object') { | ||
cache.add(value); | ||
} | ||
} | ||
/** | ||
* @function hasPair | ||
* | ||
* @description | ||
* does the `pairToMatch` exist in the list of `pairs` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param pairs the pairs to compare against | ||
* @param pairToMatch the pair to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the pair exist in the pairs provided | ||
*/ | ||
function hasPair(pairs, pairToMatch, isEqual, meta) { | ||
var length = pairs.length; | ||
var pair; | ||
for (var index = 0; index < length; index++) { | ||
pair = pairs[index]; | ||
if (isEqual(pair[0], pairToMatch[0], meta) && | ||
isEqual(pair[1], pairToMatch[1], meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function hasValue | ||
* | ||
* @description | ||
* does the `valueToMatch` exist in the list of `values` provided based on the | ||
* `isEqual` check | ||
* | ||
* @param values the values to compare against | ||
* @param valueToMatch the value to match | ||
* @param isEqual the equality comparator used | ||
* @param meta the meta provided | ||
* @returns does the value exist in the values provided | ||
*/ | ||
function hasValue(values, valueToMatch, isEqual, meta) { | ||
var length = values.length; | ||
for (var index = 0; index < length; index++) { | ||
if (isEqual(values[index], valueToMatch, meta)) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
/** | ||
* @function sameValueZeroEqual | ||
* | ||
* @description | ||
* are the values passed strictly equal or both NaN | ||
@@ -84,5 +21,2 @@ * | ||
/** | ||
* @function isPlainObject | ||
* | ||
* @description | ||
* is the value a plain object | ||
@@ -97,5 +31,2 @@ * | ||
/** | ||
* @function isPromiseLike | ||
* | ||
* @description | ||
* is the value promise-like (meaning it is thenable) | ||
@@ -110,5 +41,2 @@ * | ||
/** | ||
* @function isReactElement | ||
* | ||
* @description | ||
* is the value passed a react element | ||
@@ -123,5 +51,2 @@ * | ||
/** | ||
* @function getNewCacheFallback | ||
* | ||
* @description | ||
* in cases where WeakSet is not supported, creates a new custom | ||
@@ -133,16 +58,13 @@ * object that mimics the necessary API aspects for cache purposes | ||
function getNewCacheFallback() { | ||
return Object.create({ | ||
_values: [], | ||
var values = []; | ||
return { | ||
add: function (value) { | ||
this._values.push(value); | ||
values.push(value); | ||
}, | ||
has: function (value) { | ||
return this._values.indexOf(value) !== -1; | ||
return values.indexOf(value) !== -1; | ||
}, | ||
}); | ||
}; | ||
} | ||
/** | ||
* @function getNewCache | ||
* | ||
* @description | ||
* get a new cache object to prevent circular references | ||
@@ -161,5 +83,2 @@ * | ||
/** | ||
* @function createCircularEqualCreator | ||
* | ||
* @description | ||
* create a custom isEqual handler specific to circular objects | ||
@@ -175,9 +94,17 @@ * | ||
if (cache === void 0) { cache = getNewCache(); } | ||
var hasA = cache.has(a); | ||
var hasB = cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
var isCacheableA = !!a && typeof a === 'object'; | ||
var isCacheableB = !!b && typeof b === 'object'; | ||
if (isCacheableA || isCacheableB) { | ||
var hasA = isCacheableA && cache.has(a); | ||
var hasB = isCacheableB && cache.has(b); | ||
if (hasA || hasB) { | ||
return hasA && hasB; | ||
} | ||
if (isCacheableA) { | ||
cache.add(a); | ||
} | ||
if (isCacheableA) { | ||
cache.add(b); | ||
} | ||
} | ||
addToCache(a, cache); | ||
addToCache(b, cache); | ||
return _comparator(a, b, cache); | ||
@@ -188,39 +115,2 @@ }; | ||
/** | ||
* @function toPairs | ||
* | ||
* @description | ||
* convert the map passed into pairs (meaning an array of [key, value] tuples) | ||
* | ||
* @param map the map to convert to [key, value] pairs (entries) | ||
* @returns the [key, value] pairs | ||
*/ | ||
function toPairs(map) { | ||
var pairs = new Array(map.size); | ||
var index = 0; | ||
map.forEach(function (value, key) { | ||
pairs[index++] = [key, value]; | ||
}); | ||
return pairs; | ||
} | ||
/** | ||
* @function toValues | ||
* | ||
* @description | ||
* convert the set passed into values | ||
* | ||
* @param set the set to convert to values | ||
* @returns the values | ||
*/ | ||
function toValues(set) { | ||
var values = new Array(set.size); | ||
var index = 0; | ||
set.forEach(function (value) { | ||
values[index++] = value; | ||
}); | ||
return values; | ||
} | ||
/** | ||
* @function areArraysEqual | ||
* | ||
* @description | ||
* are the arrays equal in value | ||
@@ -235,7 +125,7 @@ * | ||
function areArraysEqual(a, b, isEqual, meta) { | ||
var length = a.length; | ||
if (b.length !== length) { | ||
var index = a.length; | ||
if (b.length !== index) { | ||
return false; | ||
} | ||
for (var index = 0; index < length; index++) { | ||
while (index-- > 0) { | ||
if (!isEqual(a[index], b[index], meta)) { | ||
@@ -248,5 +138,2 @@ return false; | ||
/** | ||
* @function areMapsEqual | ||
* | ||
* @description | ||
* are the maps equal in value | ||
@@ -261,15 +148,16 @@ * | ||
function areMapsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue, aKey) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue, bKey) { | ||
if (!isValueEqual && isEqual(aKey, bKey, meta)) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var pairsA = toPairs(a); | ||
var pairsB = toPairs(b); | ||
var length = pairsA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasPair(pairsB, pairsA[index], isEqual, meta) || | ||
!hasPair(pairsA, pairsB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
@@ -279,5 +167,2 @@ var OWNER = '_owner'; | ||
/** | ||
* @function areObjectsEqual | ||
* | ||
* @description | ||
* are the objects equal in value | ||
@@ -293,20 +178,22 @@ * | ||
var keysA = keys(a); | ||
var length = keysA.length; | ||
if (keys(b).length !== length) { | ||
var index = keysA.length; | ||
if (keys(b).length !== index) { | ||
return false; | ||
} | ||
var key; | ||
for (var index = 0; index < length; index++) { | ||
key = keysA[index]; | ||
if (!hasOwnProperty(b, key)) { | ||
return false; | ||
} | ||
if (key === OWNER && isReactElement(a)) { | ||
if (!isReactElement(b)) { | ||
if (index) { | ||
var key = void 0; | ||
while (index-- > 0) { | ||
key = keysA[index]; | ||
if (key === OWNER) { | ||
var reactElementA = isReactElement(a); | ||
var reactElementB = isReactElement(b); | ||
if ((reactElementA || reactElementB) && | ||
reactElementA !== reactElementB) { | ||
return false; | ||
} | ||
} | ||
if (!hasOwnProperty(b, key) || !isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
else if (!isEqual(a[key], b[key], meta)) { | ||
return false; | ||
} | ||
} | ||
@@ -316,5 +203,2 @@ return true; | ||
/** | ||
* @function areRegExpsEqual | ||
* | ||
* @description | ||
* are the regExps equal in value | ||
@@ -336,5 +220,2 @@ * | ||
/** | ||
* @function areSetsEqual | ||
* | ||
* @description | ||
* are the sets equal in value | ||
@@ -349,21 +230,20 @@ * | ||
function areSetsEqual(a, b, isEqual, meta) { | ||
if (a.size !== b.size) { | ||
return false; | ||
var isValueEqual = a.size === b.size; | ||
if (isValueEqual && a.size) { | ||
a.forEach(function (aValue) { | ||
if (isValueEqual) { | ||
isValueEqual = false; | ||
b.forEach(function (bValue) { | ||
if (!isValueEqual) { | ||
isValueEqual = isEqual(aValue, bValue, meta); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
var valuesA = toValues(a); | ||
var valuesB = toValues(b); | ||
var length = valuesA.length; | ||
for (var index = 0; index < length; index++) { | ||
if (!hasValue(valuesB, valuesA[index], isEqual, meta) || | ||
!hasValue(valuesA, valuesB[index], isEqual, meta)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return isValueEqual; | ||
} | ||
var isArray = Array.isArray; | ||
var HAS_MAP_SUPPORT = typeof Map === 'function'; | ||
var HAS_SET_SUPPORT = typeof Set === 'function'; | ||
var OBJECT_TYPEOF = 'object'; | ||
function createComparator(createIsEqual) { | ||
@@ -377,5 +257,2 @@ var isEqual = | ||
/** | ||
* @function comparator | ||
* | ||
* @description | ||
* compare the value of the two objects and return true if they are equivalent in values | ||
@@ -389,23 +266,23 @@ * | ||
function comparator(a, b, meta) { | ||
if (sameValueZeroEqual(a, b)) { | ||
if (a === b) { | ||
return true; | ||
} | ||
if (a && b && typeof a === OBJECT_TYPEOF && typeof b === OBJECT_TYPEOF) { | ||
if (a && b && typeof a === 'object' && typeof b === 'object') { | ||
if (isPlainObject(a) && isPlainObject(b)) { | ||
return areObjectsEqual(a, b, isEqual, meta); | ||
} | ||
var arrayA = isArray(a); | ||
var arrayB = isArray(b); | ||
if (arrayA || arrayB) { | ||
return arrayA === arrayB && areArraysEqual(a, b, isEqual, meta); | ||
var aShape = Array.isArray(a); | ||
var bShape = Array.isArray(b); | ||
if (aShape || bShape) { | ||
return aShape === bShape && areArraysEqual(a, b, isEqual, meta); | ||
} | ||
var aDate = a instanceof Date; | ||
var bDate = b instanceof Date; | ||
if (aDate || bDate) { | ||
return aDate === bDate && sameValueZeroEqual(a.getTime(), b.getTime()); | ||
aShape = a instanceof Date; | ||
bShape = b instanceof Date; | ||
if (aShape || bShape) { | ||
return (aShape === bShape && sameValueZeroEqual(a.getTime(), b.getTime())); | ||
} | ||
var aRegExp = a instanceof RegExp; | ||
var bRegExp = b instanceof RegExp; | ||
if (aRegExp || bRegExp) { | ||
return aRegExp === bRegExp && areRegExpsEqual(a, b); | ||
aShape = a instanceof RegExp; | ||
bShape = b instanceof RegExp; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areRegExpsEqual(a, b); | ||
} | ||
@@ -416,13 +293,13 @@ if (isPromiseLike(a) || isPromiseLike(b)) { | ||
if (HAS_MAP_SUPPORT) { | ||
var aMap = a instanceof Map; | ||
var bMap = b instanceof Map; | ||
if (aMap || bMap) { | ||
return aMap === bMap && areMapsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Map; | ||
bShape = b instanceof Map; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areMapsEqual(a, b, isEqual, meta); | ||
} | ||
} | ||
if (HAS_SET_SUPPORT) { | ||
var aSet = a instanceof Set; | ||
var bSet = b instanceof Set; | ||
if (aSet || bSet) { | ||
return aSet === bSet && areSetsEqual(a, b, isEqual, meta); | ||
aShape = a instanceof Set; | ||
bShape = b instanceof Set; | ||
if (aShape || bShape) { | ||
return aShape === bShape && areSetsEqual(a, b, isEqual, meta); | ||
} | ||
@@ -432,3 +309,3 @@ } | ||
} | ||
return false; | ||
return a !== a && b !== b; | ||
} | ||
@@ -438,3 +315,2 @@ return comparator; | ||
// comparator | ||
var deepEqual = createComparator(); | ||
@@ -454,3 +330,3 @@ var shallowEqual = createComparator(function () { return sameValueZeroEqual; }); | ||
})); | ||
}))); | ||
//# sourceMappingURL=fast-equals.js.map |
@@ -1,1 +0,1 @@ | ||
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n=n||self)["fast-equals"]={})}(this,function(n){"use strict";var e="function"==typeof WeakSet,t=Object.keys;function r(n,e){n&&"object"==typeof n&&e.add(n)}function u(n,e,t,r){for(var u,i=n.length,o=0;o<i;o++)if(t((u=n[o])[0],e[0],r)&&t(u[1],e[1],r))return!0;return!1}function i(n,e,t,r){for(var u=n.length,i=0;i<u;i++)if(t(n[i],e,r))return!0;return!1}function o(n,e){return n===e||n!=n&&e!=e}function f(n){return n.constructor===Object||null==n.constructor}function a(n){return!!n&&"function"==typeof n.then}function c(n){return!(!n||!n.$$typeof)}function s(){return Object.create({_values:[],add:function(n){this._values.push(n)},has:function(n){return-1!==this._values.indexOf(n)}})}var l=e?function(){return new WeakSet}:s;function p(n){return function(e){var t=n||e;return function(n,e,u){void 0===u&&(u=l());var i=u.has(n),o=u.has(e);return i||o?i&&o:(r(n,u),r(e,u),t(n,e,u))}}}function v(n){var e=new Array(n.size),t=0;return n.forEach(function(n,r){e[t++]=[r,n]}),e}function y(n){var e=new Array(n.size),t=0;return n.forEach(function(n){e[t++]=n}),e}var d="_owner",h=Function.prototype.bind.call(Function.prototype.call,Object.prototype.hasOwnProperty);function g(n,e,r,u){var i,o=t(n),f=o.length;if(t(e).length!==f)return!1;for(var a=0;a<f;a++){if(i=o[a],!h(e,i))return!1;if(i===d&&c(n)){if(!c(e))return!1}else if(!r(n[i],e[i],u))return!1}return!0}var b=Array.isArray,E="function"==typeof Map,j="function"==typeof Set,m="object";function x(n){var e="function"==typeof n?n(t):t;function t(n,t,r){if(o(n,t))return!0;if(n&&t&&typeof n===m&&typeof t===m){if(f(n)&&f(t))return g(n,t,e,r);var c=b(n),s=b(t);if(c||s)return c===s&&function(n,e,t,r){var u=n.length;if(e.length!==u)return!1;for(var i=0;i<u;i++)if(!t(n[i],e[i],r))return!1;return!0}(n,t,e,r);var l=n instanceof Date,p=t instanceof Date;if(l||p)return l===p&&o(n.getTime(),t.getTime());var d=n instanceof RegExp,h=t instanceof RegExp;if(d||h)return d===h&&function(n,e){return n.source===e.source&&n.global===e.global&&n.ignoreCase===e.ignoreCase&&n.multiline===e.multiline&&n.unicode===e.unicode&&n.sticky===e.sticky&&n.lastIndex===e.lastIndex}(n,t);if(a(n)||a(t))return n===t;if(E){var x=n instanceof Map,q=t instanceof Map;if(x||q)return x===q&&function(n,e,t,r){if(n.size!==e.size)return!1;for(var i=v(n),o=v(e),f=i.length,a=0;a<f;a++)if(!u(o,i[a],t,r)||!u(i,o[a],t,r))return!1;return!0}(n,t,e,r)}if(j){var w=n instanceof Set,O=t instanceof Set;if(w||O)return w===O&&function(n,e,t,r){if(n.size!==e.size)return!1;for(var u=y(n),o=y(e),f=u.length,a=0;a<f;a++)if(!i(o,u[a],t,r)||!i(u,o[a],t,r))return!1;return!0}(n,t,e,r)}return g(n,t,e,r)}return!1}return t}var q=x(),w=x(function(){return o}),O=x(p()),z=x(p(o));n.circularDeepEqual=O,n.circularShallowEqual=z,n.createCustomEqual=x,n.deepEqual=q,n.sameValueZeroEqual=o,n.shallowEqual=w,Object.defineProperty(n,"__esModule",{value:!0})}); | ||
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self)["fast-equals"]={})}(this,(function(n){"use strict";var e="function"==typeof WeakSet,t=Object.keys;function r(n,e){return n===e||n!=n&&e!=e}function o(n){return n.constructor===Object||null==n.constructor}function i(n){return!!n&&"function"==typeof n.then}function u(n){return!(!n||!n.$$typeof)}function f(){var n=[];return{add:function(e){n.push(e)},has:function(e){return-1!==n.indexOf(e)}}}var a=e?function(){return new WeakSet}:f;function c(n){return function(e){var t=n||e;return function(n,e,r){void 0===r&&(r=a());var o=!!n&&"object"==typeof n,i=!!e&&"object"==typeof e;if(o||i){var u=o&&r.has(n),f=i&&r.has(e);if(u||f)return u&&f;o&&r.add(n),o&&r.add(e)}return t(n,e,r)}}}var s=Function.prototype.bind.call(Function.prototype.call,Object.prototype.hasOwnProperty);function l(n,e,r,o){var i=t(n),f=i.length;if(t(e).length!==f)return!1;if(f)for(var a=void 0;f-- >0;){if("_owner"===(a=i[f])){var c=u(n),l=u(e);if((c||l)&&c!==l)return!1}if(!s(e,a)||!r(n[a],e[a],o))return!1}return!0}var p="function"==typeof Map,d="function"==typeof Set;function y(n){var e="function"==typeof n?n(t):t;function t(n,t,u){if(n===t)return!0;if(n&&t&&"object"==typeof n&&"object"==typeof t){if(o(n)&&o(t))return l(n,t,e,u);var f=Array.isArray(n),a=Array.isArray(t);return f||a?f===a&&function(n,e,t,r){var o=n.length;if(e.length!==o)return!1;for(;o-- >0;)if(!t(n[o],e[o],r))return!1;return!0}(n,t,e,u):(f=n instanceof Date,a=t instanceof Date,f||a?f===a&&r(n.getTime(),t.getTime()):(f=n instanceof RegExp,a=t instanceof RegExp,f||a?f===a&&function(n,e){return n.source===e.source&&n.global===e.global&&n.ignoreCase===e.ignoreCase&&n.multiline===e.multiline&&n.unicode===e.unicode&&n.sticky===e.sticky&&n.lastIndex===e.lastIndex}(n,t):i(n)||i(t)?n===t:p&&(f=n instanceof Map,a=t instanceof Map,f||a)?f===a&&function(n,e,t,r){var o=n.size===e.size;return o&&n.size&&n.forEach((function(n,i){o&&(o=!1,e.forEach((function(e,u){!o&&t(i,u,r)&&(o=t(n,e,r))})))})),o}(n,t,e,u):d&&(f=n instanceof Set,a=t instanceof Set,f||a)?f===a&&function(n,e,t,r){var o=n.size===e.size;return o&&n.size&&n.forEach((function(n){o&&(o=!1,e.forEach((function(e){o||(o=t(n,e,r))})))})),o}(n,t,e,u):l(n,t,e,u)))}return n!=n&&t!=t}return t}var v=y(),h=y((function(){return r})),b=y(c()),g=y(c(r));n.circularDeepEqual=b,n.circularShallowEqual=g,n.createCustomEqual=y,n.deepEqual=v,n.sameValueZeroEqual=r,n.shallowEqual=h,Object.defineProperty(n,"__esModule",{value:!0})})); |
@@ -9,9 +9,10 @@ { | ||
"devDependencies": { | ||
"@types/jest": "^24.0.12", | ||
"@rollup/plugin-node-resolve": "^11.2.1", | ||
"@types/jest": "^26.0.23", | ||
"@types/lodash": "^4.14.121", | ||
"@types/node": "^12.6.9", | ||
"@types/ramda": "^0.26.8", | ||
"@types/react": "^16.8.3", | ||
"@typescript-eslint/eslint-plugin": "^1.7.0", | ||
"@typescript-eslint/parser": "^1.7.0", | ||
"@types/node": "^15.0.1", | ||
"@types/ramda": "^0.27.40", | ||
"@types/react": "^17.0.4", | ||
"@typescript-eslint/eslint-plugin": "^4.22.0", | ||
"@typescript-eslint/parser": "^4.22.0", | ||
"benchee": "^1.1.0", | ||
@@ -21,33 +22,29 @@ "cli-table2": "^0.2.0", | ||
"deep-eql": "^4.0.0", | ||
"deep-equal": "^1.0.1", | ||
"eslint": "^6.1.0", | ||
"eslint-config-airbnb": "^17.1.0", | ||
"eslint-loader": "^2.1.2", | ||
"deep-equal": "^2.0.5", | ||
"eslint": "^7.25.0", | ||
"eslint-config-airbnb": "^18.2.1", | ||
"eslint-plugin-import": "^2.17.2", | ||
"eslint-plugin-jsx-a11y": "^6.2.1", | ||
"eslint-plugin-react": "^7.12.4", | ||
"fast-deep-equal": "^2.0.1", | ||
"fs-extra": "^8.1.0", | ||
"html-webpack-plugin": "^3.2.0", | ||
"eslint-plugin-react": "^7.23.2", | ||
"eslint-webpack-plugin": "^2.5.4", | ||
"fast-deep-equal": "^3.1.3", | ||
"fs-extra": "^9.1.0", | ||
"html-webpack-plugin": "^5.3.1", | ||
"in-publish": "^2.0.0", | ||
"jest": "^24.7.1", | ||
"lodash": "^4.17.11", | ||
"jest": "^26.6.3", | ||
"lodash": "^4.17.21", | ||
"nano-equal": "^2.0.2", | ||
"nyc": "^14.1.0", | ||
"optimize-js-plugin": "^0.0.4", | ||
"react": "^16.8.6", | ||
"react-dom": "^16.7.0", | ||
"react-fast-compare": "^2.0.4", | ||
"rollup": "^1.1.2", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"rollup-plugin-terser": "^5.1.1", | ||
"rollup-plugin-typescript2": "^0.22.1", | ||
"react": "^17.0.2", | ||
"react-dom": "^17.0.2", | ||
"react-fast-compare": "^3.2.0", | ||
"rollup": "^2.46.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"rollup-plugin-typescript2": "^0.30.0", | ||
"shallow-equal-fuzzy": "^0.0.2", | ||
"sinon": "^7.4.0", | ||
"ts-jest": "^24.0.2", | ||
"ts-loader": "^6.0.4", | ||
"typescript": "^3.4.5", | ||
"underscore": "^1.9.1", | ||
"webpack": "^4.29.0", | ||
"webpack-cli": "^3.2.1", | ||
"ts-jest": "^26.5.5", | ||
"ts-loader": "^9.1.1", | ||
"typescript": "^4.2.4", | ||
"underscore": "^1.13.1", | ||
"webpack": "^5.36.2", | ||
"webpack-cli": "^4.6.0", | ||
"webpack-dev-server": "^3.1.14" | ||
@@ -74,3 +71,3 @@ }, | ||
"build": "NODE_ENV=production rollup -c", | ||
"dev": "NODE_ENV=development webpack-dev-server --progress --colors --config=webpack/webpack.config.js", | ||
"dev": "NODE_ENV=development webpack serve --progress --config=webpack/webpack.config.js", | ||
"dist": "rimraf dist && npm run build", | ||
@@ -81,3 +78,3 @@ "lint": "eslint src/*.ts", | ||
"prepublish": "if in-publish; then npm run prepublish:compile; fi", | ||
"prepublish:compile": "npm run lint && npm run test:coverage && npm run dist", | ||
"prepublish:compile": "npm run lint && npm run test && npm run dist", | ||
"release": "release-it", | ||
@@ -91,3 +88,3 @@ "release:beta": "release-it --config=.release-it.beta.json", | ||
"types": "index.d.ts", | ||
"version": "2.0.1" | ||
"version": "2.0.2" | ||
} |
@@ -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 ~1.3kB when minified and gzipped. | ||
Perform [blazing fast](#benchmarks) equality comparisons (either deep or shallow) on two objects passed. It has no dependencies, and is ~1kB when minified and gzipped. | ||
@@ -23,13 +23,15 @@ Unlike most equality validation libraries, the following types are handled out-of-the-box: | ||
- [Usage](#usage) | ||
- [Specific builds](#specific-builds) | ||
- [Available methods](#available-methods) | ||
- [deepEqual](#deepequal) | ||
- [shallowEqual](#shallowequal) | ||
- [sameValueZeroEqual](#samevaluezeroequal) | ||
- [circularDeepEqual](#circulardeepequal) | ||
- [circularShallowEqual](#circularshallowequal) | ||
- [createCustomEqual](#createcustomequal) | ||
- [Benchmarks](#benchmarks) | ||
- [Development](#development) | ||
- [fast-equals](#fast-equals) | ||
- [Table of contents](#table-of-contents) | ||
- [Usage](#usage) | ||
- [Specific builds](#specific-builds) | ||
- [Available methods](#available-methods) | ||
- [deepEqual](#deepequal) | ||
- [shallowEqual](#shallowequal) | ||
- [sameValueZeroEqual](#samevaluezeroequal) | ||
- [circularDeepEqual](#circulardeepequal) | ||
- [circularShallowEqual](#circularshallowequal) | ||
- [createCustomEqual](#createcustomequal) | ||
- [Benchmarks](#benchmarks) | ||
- [Development](#development) | ||
@@ -177,7 +179,6 @@ ## Usage | ||
const isDeepEqualOrFooMatchesMeta = createCustomEqual( | ||
(deepEqual) => (objectA, objectB, meta) => ( | ||
(deepEqual) => (objectA, objectB, meta) => | ||
objectA.foo === meta || | ||
objectB.foo === meta || | ||
deepEqual(objectA, objectB, meta) | ||
) | ||
deepEqual(objectA, objectB, meta), | ||
); | ||
@@ -194,3 +195,3 @@ | ||
All benchmarks were performed on an i7 8-core Arch Linux laptop with 16GB of memory using NodeJS version `10.15.3`, and are based on averages of running comparisons based deep equality on the following object types: | ||
All benchmarks were performed on an i7-8650U Ubuntu Linux laptop with 24GB of memory using NodeJS version `12.19.1`, and are based on averages of running comparisons based deep equality on the following object types: | ||
@@ -208,16 +209,17 @@ - Primitives (`String`, `Number`, `null`, `undefined`) | ||
| -------------------------- | ------------------- | | ||
| **fast-equals** | **142,730** | | ||
| nano-equal | 115,530 | | ||
| shallow-equal-fuzzy | 102,633 | | ||
| fast-deep-equal | 102,335 | | ||
| react-fast-compare | 100,036 | | ||
| **fast-equals (circular)** | **79,589** | | ||
| underscore.isEqual | 63,390 | | ||
| deep-equal | 48,783 | | ||
| lodash.isEqual | 24,456 | | ||
| deep-eql | 24,196 | | ||
| assert.deepStrictEqual | 1,382 | | ||
| **fast-equals** | **153,880** | | ||
| fast-deep-equal | 144,035 | | ||
| react-fast-compare | 130,324 | | ||
| nano-equal | 104,624 | | ||
| **fast-equals (circular)** | **97,610** | | ||
| shallow-equal-fuzzy | 83,946 | | ||
| underscore.isEqual | 47,370 | | ||
| lodash.isEqual | 25,053 | | ||
| deep-eql | 22,146 | | ||
| assert.deepStrictEqual | 532 | | ||
| deep-equal | 209 | | ||
Caveats that impact the benchmark (and accuracy of comparison): | ||
- `Map`s, `Promise`s, and `Set`s were excluded from the benchmark entirely because no library other than `deep-eql` fully supported their comparison | ||
- `assert.deepStrictEqual` does not support `NaN` or `SameValueZero` equality for dates | ||
@@ -232,3 +234,3 @@ - `deep-eql` does not support `SameValueZero` equality for zero equality (positive and negative zero are not equal) | ||
All of these have the potential of inflating the respective library's numbers in comparison to `fast-equals`, but it was the closest apples-to-apples comparison I could create of a reasonable sample size. `Map`s, `Promise`s, and `Set`s were excluded from the benchmark entirely because no library other than `deep-eql` fully supported their comparison. The same logic applies to `react` elements (which can be circular objects), but simple elements are non-circular objects so I kept the `react` comparison very basic to allow it to be included. | ||
All of these have the potential of inflating the respective library's numbers in comparison to `fast-equals`, but it was the closest apples-to-apples comparison I could create of a reasonable sample size. It should be noted that `react` elements can be circular objects, however simple elements are not; I kept the `react` comparison very basic to allow it to be included. | ||
@@ -235,0 +237,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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40
247
127588
1234