npm package: @orin00/deep-equal-util
Description: A recursive deep equality comparison utility for Node.js and Browser environments.
Author: orin00
Latest version: 1.0.0

# deep-equal-strict

A **strict deep equality comparison utility** for JavaScript.  
Designed for correctness over performance, with explicit handling of edge cases such as `NaN`, `-0`, circular references, `Map`, `Set`, `Symbol`, and prototype checks.

This library intentionally avoids heuristic shortcuts and follows a **well-defined comparison policy**.

---

## Features

- ✅ **Strict numeric comparison**
  - Uses `Object.is` only
  - `NaN` equals `NaN`
  - `0` and `-0` are treated as **different**
- 🔁 **Circular reference safe**
  - Uses symmetric pair caching with nested `WeakMap`
- 🧠 **Deep comparison**
  - Recursively compares:
    - Objects
    - Arrays
    - `Map` (including deep comparison of keys)
    - `Set` (order-independent, 1:1 matching)
- 🧬 **Prototype-aware**
  - Objects with different prototypes are **not equal**
- 🧿 **Symbol & non-enumerable properties**
  - Compared via `Reflect.ownKeys`
- 🌐 **UMD compatible**
  - Works in Node.js and browsers

---

## Installation

### npm
npm install deep-equal-strict

### yarn
yarn add deep-equal-strict

---

Usage

### CommonJS (Node.js)
"""
const deepEqual = require('deep-equal-strict');

deepEqual({ a: 1 }, { a: 1 }); // true
"""

### Browser (Global)
"""
<script src="deep-equal-strict.js"></script>
<script>
  deepEqual({ x: 1 }, { x: 1 }); // true
</script>
"""

---
Examples
### Basic Objects
"""
deepEqual(
  { a: 1, b: { c: 2 } },
  { a: 1, b: { c: 2 } }
); // true
"""

### Strict Numeric Comparison
"""
deepEqual(NaN, NaN); // true
deepEqual(0, -0);   // false
"""

### Circular References
"""
const a = {};
a.self = a;

const b = {};
b.self = b;

deepEqual(a, b); // true
"""

### Map (Deep Key Comparison)
"""
const mapA = new Map([[{ id: 1 }, 'value']]);
const mapB = new Map([[{ id: 1 }, 'value']]);

deepEqual(mapA, mapB); // true
"""

### Set (Order Independent)
"""
const setA = new Set([{ x: 1 }, { y: 2 }]);
const setB = new Set([{ y: 2 }, { x: 1 }]);

deepEqual(setA, setB); // true
"""

### Symbols & Non-enumerable Properties
"""
const sym = Symbol('key');

const a = {};
Object.defineProperty(a, sym, { value: 42 });

const b = {};
Object.defineProperty(b, sym, { value: 42 });

deepEqual(a, b); // true
"""

### Prototype Mismatch
"""
const a = { x: 1 };
const b = Object.create(null);
b.x = 1;

deepEqual(a, b); // false
"""

### Functions
"""
const fn = () => 1;

deepEqual(fn, fn);       // true
deepEqual(() => 1, () => 1); // false
"""

### Error Objects
"""
deepEqual(
  new Error('fail'),
  new Error('fail')
); // usually false (stack differs)
"""

---
Design Notes (Strict Mode)

Correctness first, performance second

Map and Set comparisons are O(n²) by design

Functions are compared by reference only

Error objects are compared structurally and may differ by environment

Property descriptors (writable, getter, etc.) are not compared

This library is not intended to be a drop-in replacement for lodash.isEqual.
It is designed for users who want predictable and explicit equality semantics.
---
When to Use

You need deterministic deep equality

You care about NaN, -0, and prototype correctness

You work with complex structures (Map, Set, circular graphs)

When NOT to Use

Performance-critical hot paths

JSON-only shallow comparisons

Heuristic or fuzzy equality needs
---
License : MIT