@adaptabletools/adaptable-cjs
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
128 lines (127 loc) • 3.39 kB
JavaScript
"use strict";
/**
* Performs a deep comparison between two values to determine if they are equivalent.
* Drop-in replacement for lodash/isEqual.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = isEqual;
function baseIsEqual(a, b, seen) {
// Identical references or primitives
if (a === b) {
return true;
}
// NaN check
if (a !== a && b !== b) {
return true;
}
// Null/undefined/primitive mismatch
if (a == null || b == null) {
return false;
}
const typeA = typeof a;
const typeB = typeof b;
if (typeA !== typeB) {
return false;
}
if (typeA !== 'object') {
return false;
}
// Date
if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime();
}
// RegExp
if (a instanceof RegExp && b instanceof RegExp) {
return a.source === b.source && a.flags === b.flags;
}
// One is Date/RegExp but the other is not
if (a instanceof Date !== b instanceof Date) {
return false;
}
if (a instanceof RegExp !== b instanceof RegExp) {
return false;
}
// Circular reference detection
if (seen.has(a)) {
return seen.get(a) === b;
}
seen.set(a, b);
// Arrays
if (Array.isArray(a)) {
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (!baseIsEqual(a[i], b[i], seen)) {
return false;
}
}
return true;
}
if (Array.isArray(b)) {
return false;
}
// Map
if (a instanceof Map && b instanceof Map) {
if (a.size !== b.size) {
return false;
}
for (const [key, val] of a) {
if (!b.has(key) || !baseIsEqual(val, b.get(key), seen)) {
return false;
}
}
return true;
}
// Set (unordered deep comparison, matching lodash behavior)
if (a instanceof Set && b instanceof Set) {
if (a.size !== b.size) {
return false;
}
for (const valA of a) {
let found = false;
for (const valB of b) {
if (baseIsEqual(valA, valB, new Map(seen))) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
// ArrayBuffer / TypedArray
if (ArrayBuffer.isView(a) && ArrayBuffer.isView(b)) {
const viewA = a;
const viewB = b;
if (viewA.length !== viewB.length) {
return false;
}
for (let i = 0; i < viewA.length; i++) {
if (viewA[i] !== viewB[i]) {
return false;
}
}
return true;
}
// Plain objects
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) {
return false;
}
for (const key of keysA) {
if (!Object.prototype.hasOwnProperty.call(b, key)) {
return false;
}
if (!baseIsEqual(a[key], b[key], seen)) {
return false;
}
}
return true;
}
function isEqual(value, other) {
return baseIsEqual(value, other, new Map());
}