Skip to content

Commit 00d2de8

Browse files
committed
perf(shared): optimize deepEqual
1 parent 692df58 commit 00d2de8

1 file changed

Lines changed: 37 additions & 1 deletion

File tree

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,37 @@
1-
export { dequal as default } from 'dequal/lite';
1+
/**
2+
* Deep equality for JSON-compatible values (objects, arrays, primitives).
3+
* Used to determine whether read/write pruned variants actually differ.
4+
*/
5+
const deepEqual = (a: unknown, b: unknown): boolean => {
6+
if (a === b) return true;
7+
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') return false;
8+
9+
const ctor = (a as object).constructor;
10+
if (ctor !== (b as object).constructor) return false;
11+
12+
// Arrays
13+
if (Array.isArray(a)) {
14+
const arrA = a as unknown[];
15+
const arrB = b as unknown[];
16+
let len = arrA.length;
17+
if (len !== arrB.length) return false;
18+
while (len--) {
19+
if (!deepEqual(arrA[len], arrB[len])) return false;
20+
}
21+
return true;
22+
}
23+
24+
// Plain objects
25+
const objA = a as Record<string, unknown>;
26+
const objB = b as Record<string, unknown>;
27+
let len = 0;
28+
for (const key in objA) {
29+
if (Object.hasOwn(objA, key)) {
30+
if (++len && !Object.hasOwn(objB, key)) return false;
31+
if (!deepEqual(objA[key], objB[key])) return false;
32+
}
33+
}
34+
return Object.keys(objB).length === len;
35+
};
36+
37+
export default deepEqual;

0 commit comments

Comments
 (0)