@guanghechen/equal 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +12 -0
- package/lib/cjs/index.cjs +59 -2
- package/lib/esm/index.mjs +59 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,41 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 2.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix deep equality for Map, Set, typed arrays, DataView/ArrayBuffer, and null-prototype objects.
|
|
8
|
+
|
|
9
|
+
## 2.0.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- chore: vitest config auto-load aliases and coverage thresholds; style/doc formatting updates
|
|
14
|
+
|
|
3
15
|
All notable changes to this project will be documented in this file. See
|
|
4
16
|
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
17
|
|
|
18
|
+
## 2.0.1 (2025-02-07)
|
|
19
|
+
|
|
20
|
+
### Improvements
|
|
21
|
+
|
|
22
|
+
- Clean up build configs and standardize package exports
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
|
|
26
|
+
- Update README.md
|
|
27
|
+
|
|
28
|
+
### Miscellaneous
|
|
29
|
+
|
|
30
|
+
- Add LICENSE file
|
|
31
|
+
- Migrate from lerna to changesets
|
|
32
|
+
|
|
33
|
+
## 2.0.0 (2025-01-15)
|
|
34
|
+
|
|
35
|
+
### Improvements
|
|
36
|
+
|
|
37
|
+
- Switch to recommended ESLint stack
|
|
38
|
+
|
|
6
39
|
## 1.0.0-alpha.7 (2024-09-18)
|
|
7
40
|
|
|
8
41
|
- :wrench: chore: upgrade devDependencies and fix configs
|
package/README.md
CHANGED
|
@@ -114,6 +114,18 @@ isEqual(/abc/g, /abc/i) // false
|
|
|
114
114
|
// Date
|
|
115
115
|
isEqual(new Date('2024-01-01'), new Date('2024-01-01')) // true
|
|
116
116
|
|
|
117
|
+
// Map (keys matched by identity, values compared deeply)
|
|
118
|
+
isEqual(new Map([['a', 1]]), new Map([['a', 1]])) // true
|
|
119
|
+
isEqual(new Map([['a', 1]]), new Map([['a', 2]])) // false
|
|
120
|
+
|
|
121
|
+
// Set (elements matched by identity)
|
|
122
|
+
isEqual(new Set([1, 2, 3]), new Set([3, 2, 1])) // true
|
|
123
|
+
isEqual(new Set([1, 2]), new Set([1, 2, 3])) // false
|
|
124
|
+
|
|
125
|
+
// Typed arrays (element-wise)
|
|
126
|
+
isEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3])) // true
|
|
127
|
+
isEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4])) // false
|
|
128
|
+
|
|
117
129
|
// Custom valueOf/toString
|
|
118
130
|
class Point {
|
|
119
131
|
constructor(public x: number, public y: number) {}
|
package/lib/cjs/index.cjs
CHANGED
|
@@ -23,12 +23,69 @@ function isEqual(x, y) {
|
|
|
23
23
|
}
|
|
24
24
|
return true;
|
|
25
25
|
}
|
|
26
|
+
if (x instanceof Map) {
|
|
27
|
+
if (x.size !== y.size)
|
|
28
|
+
return false;
|
|
29
|
+
for (const [key, value] of x) {
|
|
30
|
+
if (!y.has(key) || !isEqual(value, y.get(key)))
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
if (x instanceof Set) {
|
|
36
|
+
if (x.size !== y.size)
|
|
37
|
+
return false;
|
|
38
|
+
for (const value of x) {
|
|
39
|
+
if (!y.has(value))
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
if (ArrayBuffer.isView(x)) {
|
|
45
|
+
if (x instanceof DataView) {
|
|
46
|
+
if (x.byteLength !== y.byteLength)
|
|
47
|
+
return false;
|
|
48
|
+
for (let i = 0; i < x.byteLength; ++i) {
|
|
49
|
+
if (x.getUint8(i) !== y.getUint8(i))
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
const lhs = x;
|
|
55
|
+
const rhs = y;
|
|
56
|
+
if (lhs.length !== rhs.length)
|
|
57
|
+
return false;
|
|
58
|
+
for (let i = 0; i < lhs.length; ++i) {
|
|
59
|
+
if (!Object.is(lhs[i], rhs[i]))
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (x instanceof ArrayBuffer) {
|
|
65
|
+
if (x.byteLength !== y.byteLength)
|
|
66
|
+
return false;
|
|
67
|
+
if (x.byteLength === 0)
|
|
68
|
+
return true;
|
|
69
|
+
const lhs = new Uint8Array(x);
|
|
70
|
+
const rhs = new Uint8Array(y);
|
|
71
|
+
for (let i = 0; i < lhs.length; ++i) {
|
|
72
|
+
if (lhs[i] !== rhs[i])
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
26
77
|
if (x.constructor === RegExp)
|
|
27
78
|
return x.source === y.source && x.flags === y.flags;
|
|
28
|
-
if (x.valueOf !== Object.prototype.valueOf)
|
|
79
|
+
if (typeof x.valueOf === 'function' && x.valueOf !== Object.prototype.valueOf) {
|
|
80
|
+
if (typeof y.valueOf !== 'function')
|
|
81
|
+
return false;
|
|
29
82
|
return x.valueOf() === y.valueOf();
|
|
30
|
-
|
|
83
|
+
}
|
|
84
|
+
if (typeof x.toString === 'function' && x.toString !== Object.prototype.toString) {
|
|
85
|
+
if (typeof y.toString !== 'function')
|
|
86
|
+
return false;
|
|
31
87
|
return x.toString() === y.toString();
|
|
88
|
+
}
|
|
32
89
|
const keys = Object.keys(x);
|
|
33
90
|
if (keys.length !== Object.keys(y).length)
|
|
34
91
|
return false;
|
package/lib/esm/index.mjs
CHANGED
|
@@ -19,12 +19,69 @@ function isEqual(x, y) {
|
|
|
19
19
|
}
|
|
20
20
|
return true;
|
|
21
21
|
}
|
|
22
|
+
if (x instanceof Map) {
|
|
23
|
+
if (x.size !== y.size)
|
|
24
|
+
return false;
|
|
25
|
+
for (const [key, value] of x) {
|
|
26
|
+
if (!y.has(key) || !isEqual(value, y.get(key)))
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
if (x instanceof Set) {
|
|
32
|
+
if (x.size !== y.size)
|
|
33
|
+
return false;
|
|
34
|
+
for (const value of x) {
|
|
35
|
+
if (!y.has(value))
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
if (ArrayBuffer.isView(x)) {
|
|
41
|
+
if (x instanceof DataView) {
|
|
42
|
+
if (x.byteLength !== y.byteLength)
|
|
43
|
+
return false;
|
|
44
|
+
for (let i = 0; i < x.byteLength; ++i) {
|
|
45
|
+
if (x.getUint8(i) !== y.getUint8(i))
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
const lhs = x;
|
|
51
|
+
const rhs = y;
|
|
52
|
+
if (lhs.length !== rhs.length)
|
|
53
|
+
return false;
|
|
54
|
+
for (let i = 0; i < lhs.length; ++i) {
|
|
55
|
+
if (!Object.is(lhs[i], rhs[i]))
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
if (x instanceof ArrayBuffer) {
|
|
61
|
+
if (x.byteLength !== y.byteLength)
|
|
62
|
+
return false;
|
|
63
|
+
if (x.byteLength === 0)
|
|
64
|
+
return true;
|
|
65
|
+
const lhs = new Uint8Array(x);
|
|
66
|
+
const rhs = new Uint8Array(y);
|
|
67
|
+
for (let i = 0; i < lhs.length; ++i) {
|
|
68
|
+
if (lhs[i] !== rhs[i])
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
22
73
|
if (x.constructor === RegExp)
|
|
23
74
|
return x.source === y.source && x.flags === y.flags;
|
|
24
|
-
if (x.valueOf !== Object.prototype.valueOf)
|
|
75
|
+
if (typeof x.valueOf === 'function' && x.valueOf !== Object.prototype.valueOf) {
|
|
76
|
+
if (typeof y.valueOf !== 'function')
|
|
77
|
+
return false;
|
|
25
78
|
return x.valueOf() === y.valueOf();
|
|
26
|
-
|
|
79
|
+
}
|
|
80
|
+
if (typeof x.toString === 'function' && x.toString !== Object.prototype.toString) {
|
|
81
|
+
if (typeof y.toString !== 'function')
|
|
82
|
+
return false;
|
|
27
83
|
return x.toString() === y.toString();
|
|
84
|
+
}
|
|
28
85
|
const keys = Object.keys(x);
|
|
29
86
|
if (keys.length !== Object.keys(y).length)
|
|
30
87
|
return false;
|