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.31 kB
JavaScript
;Object.defineProperty(exports,"__esModule",{value:!0}),exports.typeChecker=void 0,exports.compare=compare,exports.same=same,exports.different=different;const WRAPPER_TYPES=new Set(["String","Number","Boolean","BigInt"]),SIMPLE_TYPES=new Set(["string","boolean","undefined"]);function compareArrs(e,r,t,o,s,n,i,a){if(e.length!==r.length)return!1;for(let p=0;p<e.length;p+=1)if(!internalCompare(e[p],r[p],t,o,s,n,i,a))return!1;return!0}function compareObjects(e,r,t,o,s,n,i,a){var p,u;let l,c;const b=Array.isArray(t)?e=>t.includes(e):e=>null==t?void 0:t.has(e),y=Array.isArray(t)?t.length:null!==(p=null==t?void 0:t.size)&&void 0!==p?p:0,h=Array.isArray(o)?e=>o.includes(e):e=>null==o?void 0:o.has(e),m=Array.isArray(o)?o.length:null!==(u=null==o?void 0:o.size)&&void 0!==u?u:0;if(o&&0===m)return!0;if(y||m?(l=Object.keys(e||{}).sort().filter((e=>m?h(e):!b(e))),c=Object.keys(r||{}).sort().filter((e=>m?h(e):!b(e)))):(l=Object.keys(e||{}).sort(),c=Object.keys(r||{}).sort()),!compareArrs(l,c,t,o,s,n,i,a))return!1;for(let t=0;t<l.length;t+=1)if(!internalCompare(e[l[t]],r[l[t]],void 0,void 0,s,n,!1,a))return!1;return!0}function internalCompare(e,r,t,o,s,n=!1,i=!0,a=new WeakSet){if(!exports.typeChecker.bothAreSameType(e,r))return!1;if(exports.typeChecker.isSimpleType(e)||exports.typeChecker.bothAreNulls(e,r))return e===r;if(exports.typeChecker.bothAreNumbersAndNaNs(e,r))return!0;if(exports.typeChecker.bothAreNumbersAndOnlyOneIsNaN(e,r))return!1;if(exports.typeChecker.bothAreNumbers(e,r))return e===r;if(exports.typeChecker.bothAreWrapperTypes(e,r))return internalCompare(e.valueOf(),r.valueOf(),t,o,s,n,!1,a);if(exports.typeChecker.bothAreComparableObjects(e,r))return e.equals(r);if(exports.typeChecker.isNotNullObject(e)){if(n){if(a.has(e)&&a.has(r))return!0;a.add(e),a.add(r)}if(!i&&s)return e===r}return Array.isArray(e)?compareArrs(e,r,t,o,s,n,!1,a):compareObjects(e,r,t,o,s,n,!1,a)}function compare(e,r,t={}){const{topLevelIgnore:o,topLevelInclude:s,shallow:n,detectCircular:i=!1}=t;return internalCompare(e,r,o,s,n,i)}function same(e,r,t={}){return compare(e,r,t)}function different(e,r,t={}){return!compare(e,r,t)}exports.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)=>exports.typeChecker.isNumber(e)&&exports.typeChecker.isNumber(r),bothAreNumbersAndNaNs:(e,r)=>exports.typeChecker.bothAreNumbers(e,r)&&Number.isNaN(e)&&Number.isNaN(r),bothAreNumbersAndOnlyOneIsNaN:(e,r)=>exports.typeChecker.bothAreNumbers(e,r)&&(!Number.isNaN(e)&&Number.isNaN(r)||Number.isNaN(e)&&!Number.isNaN(r)),bothAreWrapperTypes:(e,r)=>exports.typeChecker.isNotNullObject(e)&&exports.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=>exports.typeChecker.isNotNullObject(e)&&"equals"in e&&"function"==typeof e.equals,bothAreComparableObjects:(e,r)=>exports.typeChecker.isComparableObject(e)&&exports.typeChecker.isComparableObject(r)};
//# sourceMappingURL=comparator.cjs.map