simple-comparator
Version:
A production-ready deep equality comparison library for JavaScript and TypeScript, supporting complex objects, arrays, and primitive types with circular reference detection. Works seamlessly across Node.js, Deno, and browser environments.
2 lines • 3.02 kB
JavaScript
const WRAPPER_TYPES=new Set(["String","Number","Boolean","BigInt"]),SIMPLE_TYPES=new Set(["string","boolean","undefined"]);export const typeChecker={bothAreSameType:(e,r)=>typeof e==typeof r&&Array.isArray(e)===Array.isArray(r),isSimpleType:e=>SIMPLE_TYPES.has(typeof e),bothAreNulls:(e,r)=>null===e&&null===r,isNumber:e=>["number"].includes(typeof e),isNotNullObject:e=>"object"==typeof e&&null!==e,bothAreNumbers:(e,r)=>typeChecker.isNumber(e)&&typeChecker.isNumber(r),bothAreNumbersAndNaNs:(e,r)=>typeChecker.bothAreNumbers(e,r)&&Number.isNaN(e)&&Number.isNaN(r),bothAreNumbersAndOnlyOneIsNaN:(e,r)=>typeChecker.bothAreNumbers(e,r)&&(!Number.isNaN(e)&&Number.isNaN(r)||Number.isNaN(e)&&!Number.isNaN(r)),bothAreWrapperTypes:(e,r)=>typeChecker.isNotNullObject(e)&&typeChecker.isNotNullObject(r)&&!!(null==e?void 0:e.constructor.name)&&!!(null==r?void 0:r.constructor.name)&&WRAPPER_TYPES.has(null==e?void 0:e.constructor.name)&&WRAPPER_TYPES.has(null==r?void 0:r.constructor.name),isComparableObject:e=>typeChecker.isNotNullObject(e)&&"equals"in e&&"function"==typeof e.equals,bothAreComparableObjects:(e,r)=>typeChecker.isComparableObject(e)&&typeChecker.isComparableObject(r)};function compareArrs(e,r,t,n,o,s,i,a){if(e.length!==r.length)return!1;for(let l=0;l<e.length;l+=1)if(!internalCompare(e[l],r[l],t,n,o,s,i,a))return!1;return!0}function compareObjects(e,r,t,n,o,s,i,a){var l,u;let c,p;const b=Array.isArray(t)?e=>t.includes(e):e=>null==t?void 0:t.has(e),y=Array.isArray(t)?t.length:null!==(l=null==t?void 0:t.size)&&void 0!==l?l:0,N=Array.isArray(n)?e=>n.includes(e):e=>null==n?void 0:n.has(e),h=Array.isArray(n)?n.length:null!==(u=null==n?void 0:n.size)&&void 0!==u?u:0;if(n&&0===h)return!0;if(y||h?(c=Object.keys(e||{}).sort().filter((e=>h?N(e):!b(e))),p=Object.keys(r||{}).sort().filter((e=>h?N(e):!b(e)))):(c=Object.keys(e||{}).sort(),p=Object.keys(r||{}).sort()),!compareArrs(c,p,t,n,o,s,i,a))return!1;for(let t=0;t<c.length;t+=1)if(!internalCompare(e[c[t]],r[c[t]],void 0,void 0,o,s,!1,a))return!1;return!0}function internalCompare(e,r,t,n,o,s=!1,i=!0,a=new WeakSet){if(!typeChecker.bothAreSameType(e,r))return!1;if(typeChecker.isSimpleType(e)||typeChecker.bothAreNulls(e,r))return e===r;if(typeChecker.bothAreNumbersAndNaNs(e,r))return!0;if(typeChecker.bothAreNumbersAndOnlyOneIsNaN(e,r))return!1;if(typeChecker.bothAreNumbers(e,r))return e===r;if(typeChecker.bothAreWrapperTypes(e,r))return internalCompare(e.valueOf(),r.valueOf(),t,n,o,s,!1,a);if(typeChecker.bothAreComparableObjects(e,r))return e.equals(r);if(typeChecker.isNotNullObject(e)){if(s){if(a.has(e)&&a.has(r))return!0;a.add(e),a.add(r)}if(!i&&o)return e===r}return Array.isArray(e)?compareArrs(e,r,t,n,o,s,!1,a):compareObjects(e,r,t,n,o,s,!1,a)}export function compare(e,r,t={}){const{topLevelIgnore:n,topLevelInclude:o,shallow:s,detectCircular:i=!1}=t;return internalCompare(e,r,n,o,s,i)}export function same(e,r,t={}){return compare(e,r,t)}export function different(e,r,t={}){return!compare(e,r,t)}
//# sourceMappingURL=comparator.js.map