fast-is-equal 1.0.4 → 1.1.0
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/LICENSE +20 -0
- package/README.md +39 -143
- package/dist/__tests__/fastIsEqual.test.js +1 -154
- package/dist/index.js +3 -21
- package/package.json +34 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jairaj Jangle
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
in the Software without restriction, including without limitation the rights
|
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# fast-is-equal
|
|
2
2
|
|
|
3
|
-
Blazing-fast equality checks, minus the baggage. A lean, standalone alternative to Lodash
|
|
3
|
+
⚡️Blazing-fast equality checks, minus the baggage. A lean, standalone alternative to Lodash's `isEqual` - because speed matters.
|
|
4
4
|
|
|
5
|
-
[](https://badge.fury.io/js/fast-is-equal)
|
|
5
|
+
[](https://badge.fury.io/js/fast-is-equal) [](https://github.com/JairajJangle/fast-is-equal/blob/main/LICENSE) 
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -19,6 +19,7 @@ npm install fast-is-equal
|
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
22
|
+
|
|
22
23
|
```typescript
|
|
23
24
|
import { fastIsEqual } from 'fast-is-equal';
|
|
24
25
|
|
|
@@ -28,152 +29,47 @@ console.log(fastIsEqual([1, 2], [1, 3])); // false
|
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
## Features
|
|
32
|
+
|
|
31
33
|
- Lightweight and dependency-free.
|
|
32
34
|
- Handles primitives, objects, arrays, Maps, Sets, circular references, and more.
|
|
33
35
|
- Optimized for performance (see benchmarks).
|
|
34
36
|
|
|
35
37
|
## Benchmarks
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
fastIsEqual: 0.000097 ms
|
|
67
|
-
Lodash isEqual: 0.000271 ms
|
|
68
|
-
Difference (fastIsEqual - Lodash): -0.000174 ms
|
|
69
|
-
fastIsEqual is 2.80x faster than Lodash
|
|
70
|
-
----------------------------------------
|
|
71
|
-
Test Case 6: Simple Object (unequal)
|
|
72
|
-
fastIsEqual: 0.000105 ms
|
|
73
|
-
Lodash isEqual: 0.000271 ms
|
|
74
|
-
Difference (fastIsEqual - Lodash): -0.000165 ms
|
|
75
|
-
fastIsEqual is 2.57x faster than Lodash
|
|
76
|
-
----------------------------------------
|
|
77
|
-
Test Case 7: Nested Object (equal)
|
|
78
|
-
fastIsEqual: 0.000184 ms
|
|
79
|
-
Lodash isEqual: 0.000835 ms
|
|
80
|
-
Difference (fastIsEqual - Lodash): -0.000651 ms
|
|
81
|
-
fastIsEqual is 4.53x faster than Lodash
|
|
82
|
-
----------------------------------------
|
|
83
|
-
Test Case 8: Nested Object (unequal)
|
|
84
|
-
fastIsEqual: 0.000197 ms
|
|
85
|
-
Lodash isEqual: 0.000850 ms
|
|
86
|
-
Difference (fastIsEqual - Lodash): -0.000653 ms
|
|
87
|
-
fastIsEqual is 4.31x faster than Lodash
|
|
88
|
-
----------------------------------------
|
|
89
|
-
Test Case 9: Array of Primitives (equal)
|
|
90
|
-
fastIsEqual: 0.000017 ms
|
|
91
|
-
Lodash isEqual: 0.000102 ms
|
|
92
|
-
Difference (fastIsEqual - Lodash): -0.000085 ms
|
|
93
|
-
fastIsEqual is 5.95x faster than Lodash
|
|
94
|
-
----------------------------------------
|
|
95
|
-
Test Case 10: Array of Primitives (unequal)
|
|
96
|
-
fastIsEqual: 0.000015 ms
|
|
97
|
-
Lodash isEqual: 0.000103 ms
|
|
98
|
-
Difference (fastIsEqual - Lodash): -0.000088 ms
|
|
99
|
-
fastIsEqual is 6.79x faster than Lodash
|
|
100
|
-
----------------------------------------
|
|
101
|
-
Test Case 11: Array of Objects (equal)
|
|
102
|
-
fastIsEqual: 0.000078 ms
|
|
103
|
-
Lodash isEqual: 0.000638 ms
|
|
104
|
-
Difference (fastIsEqual - Lodash): -0.000560 ms
|
|
105
|
-
fastIsEqual is 8.15x faster than Lodash
|
|
106
|
-
----------------------------------------
|
|
107
|
-
Test Case 12: Circular Reference
|
|
108
|
-
fastIsEqual: 0.000095 ms
|
|
109
|
-
Lodash isEqual: 0.000493 ms
|
|
110
|
-
Difference (fastIsEqual - Lodash): -0.000399 ms
|
|
111
|
-
fastIsEqual is 5.22x faster than Lodash
|
|
112
|
-
----------------------------------------
|
|
113
|
-
Test Case 13: Map (equal)
|
|
114
|
-
fastIsEqual: 0.000074 ms
|
|
115
|
-
Lodash isEqual: 0.001383 ms
|
|
116
|
-
Difference (fastIsEqual - Lodash): -0.001309 ms
|
|
117
|
-
fastIsEqual is 18.67x faster than Lodash
|
|
118
|
-
----------------------------------------
|
|
119
|
-
Test Case 14: Map (unequal)
|
|
120
|
-
fastIsEqual: 0.000076 ms
|
|
121
|
-
Lodash isEqual: 0.001330 ms
|
|
122
|
-
Difference (fastIsEqual - Lodash): -0.001255 ms
|
|
123
|
-
fastIsEqual is 17.59x faster than Lodash
|
|
124
|
-
----------------------------------------
|
|
125
|
-
Test Case 15: Set (equal)
|
|
126
|
-
fastIsEqual: 0.000073 ms
|
|
127
|
-
Lodash isEqual: 0.000949 ms
|
|
128
|
-
Difference (fastIsEqual - Lodash): -0.000876 ms
|
|
129
|
-
fastIsEqual is 13.07x faster than Lodash
|
|
130
|
-
----------------------------------------
|
|
131
|
-
Test Case 16: Set (unequal)
|
|
132
|
-
fastIsEqual: 0.000070 ms
|
|
133
|
-
Lodash isEqual: 0.000930 ms
|
|
134
|
-
Difference (fastIsEqual - Lodash): -0.000860 ms
|
|
135
|
-
fastIsEqual is 13.22x faster than Lodash
|
|
136
|
-
----------------------------------------
|
|
137
|
-
Test Case 17: Empty Object vs Array
|
|
138
|
-
fastIsEqual: 0.000009 ms
|
|
139
|
-
Lodash isEqual: 0.000043 ms
|
|
140
|
-
Difference (fastIsEqual - Lodash): -0.000034 ms
|
|
141
|
-
fastIsEqual is 4.74x faster than Lodash
|
|
142
|
-
----------------------------------------
|
|
143
|
-
Test Case 18: Map vs Set
|
|
144
|
-
fastIsEqual: 0.000018 ms
|
|
145
|
-
Lodash isEqual: 0.000469 ms
|
|
146
|
-
Difference (fastIsEqual - Lodash): -0.000452 ms
|
|
147
|
-
fastIsEqual is 26.55x faster than Lodash
|
|
148
|
-
----------------------------------------
|
|
149
|
-
Average Performance:
|
|
150
|
-
fastIsEqual: 0.000063 ms
|
|
151
|
-
Lodash isEqual: 0.000483 ms
|
|
152
|
-
fastIsEqual is on average 7.71x faster than Lodash
|
|
153
|
-
```
|
|
38
|
+
|
|
39
|
+
`fast-is-equal` outperforms Lodash's `isEqual` in most cases. Run `npm run benchmark` locally to compare:
|
|
40
|
+
|
|
41
|
+
| Test Case | fastIsEqual (ms) | Lodash isEqual (ms) | Performance Gain |
|
|
42
|
+
|-----------|------------------|---------------------|------------------|
|
|
43
|
+
| Numbers | 0.000003 | 0.000007 | **2.56x faster** |
|
|
44
|
+
| Strings | 0.000008 | 0.000007 | 0.92x slower |
|
|
45
|
+
| Booleans | 0.000007 | 0.000007 | **0.95x faster** |
|
|
46
|
+
| NaN | 0.000008 | 0.000017 | **2.05x faster** |
|
|
47
|
+
| Simple Object (equal) | 0.000137 | 0.000531 | **3.87x faster** |
|
|
48
|
+
| Simple Object (unequal) | 0.000137 | 0.000560 | **4.09x faster** |
|
|
49
|
+
| Nested Object (equal) | 0.000240 | 0.001426 | **5.95x faster** |
|
|
50
|
+
| Nested Object (unequal) | 0.000242 | 0.001437 | **5.93x faster** |
|
|
51
|
+
| Array of Primitives (equal) | 0.000025 | 0.000163 | **6.44x faster** |
|
|
52
|
+
| Array of Primitives (unequal) | 0.000025 | 0.000170 | **6.82x faster** |
|
|
53
|
+
| Array of Objects (equal) | 0.000119 | 0.001237 | **10.39x faster** |
|
|
54
|
+
| Circular Reference | 0.000136 | 0.000928 | **6.83x faster** |
|
|
55
|
+
| Map (equal) | 0.000101 | 0.001765 | **17.55x faster** |
|
|
56
|
+
| Map (unequal) | 0.000098 | 0.001688 | **17.22x faster** |
|
|
57
|
+
| Set (equal) | 0.000098 | 0.001474 | **15.04x faster** |
|
|
58
|
+
| Set (unequal) | 0.000101 | 0.001765 | **17.55x faster** |
|
|
59
|
+
| Empty Object vs Array | 0.000015 | 0.000051 | **3.51x faster** |
|
|
60
|
+
| Map vs Set | 0.000026 | 0.000811 | **30.69x faster** |
|
|
61
|
+
|
|
62
|
+
[Benchmark logs](benchmarks/results.txt)
|
|
63
|
+
|
|
64
|
+
### Summary
|
|
65
|
+
- **Average Performance**: `fastIsEqual` is **10.58x faster** than Lodash's `isEqual`
|
|
66
|
+
- **Best Performance**: Map vs Set comparison shows **30.69x faster** execution
|
|
67
|
+
- **Iterations**: 1,000,000 per test case for accurate measurements
|
|
154
68
|
|
|
155
69
|
## License
|
|
70
|
+
|
|
156
71
|
MIT
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
163
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
164
|
-
in the Software without restriction, including without limitation the rights
|
|
165
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
166
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
167
|
-
furnished to do so, subject to the following conditions:
|
|
168
|
-
|
|
169
|
-
The above copyright notice and this permission notice shall be included in all
|
|
170
|
-
copies or substantial portions of the Software.
|
|
171
|
-
|
|
172
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
173
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
174
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
175
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
176
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
177
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
178
|
-
SOFTWARE.
|
|
179
|
-
```
|
|
72
|
+
|
|
73
|
+
## 🙏 Support the project
|
|
74
|
+
|
|
75
|
+
<p align="center" valign="center"> <a href="https://liberapay.com/FutureJJ/donate"> <img src="https://liberapay.com/assets/widgets/donate.svg" alt="LiberPay_Donation_Button" height="50" > </a> <a href=".github/assets/Jairaj_Jangle_Google_Pay_UPI_QR_Code.jpg"> <img src=".github/assets/upi.png" alt="Paypal_Donation_Button" height="50" > </a> <a href="https://www.paypal.com/paypalme/jairajjangle001/usd"> <img src=".github/assets/paypal_donate.png" alt="Paypal_Donation_Button" height="50" > </a> </p>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const index_1 = require("../index");
|
|
4
|
-
describe('
|
|
4
|
+
describe('isEqual', () => {
|
|
5
5
|
// **Primitives**
|
|
6
6
|
it('should return true for identical primitives', () => {
|
|
7
7
|
expect((0, index_1.fastIsEqual)(1, 1)).toBe(true);
|
|
@@ -37,21 +37,6 @@ describe('fastIsEqual', () => {
|
|
|
37
37
|
const obj2 = { a: 1, b: { c: 2 } };
|
|
38
38
|
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
39
39
|
});
|
|
40
|
-
it('should return true for deeply unequal objects', () => {
|
|
41
|
-
const obj1 = { a: 1, b: { c: 2 } };
|
|
42
|
-
const obj2 = { a: 1, b: { c: 3 } };
|
|
43
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
it('should return true for deeply equal objects with array', () => {
|
|
46
|
-
const obj1 = { a: 1, b: { c: [1, 2, 3] } };
|
|
47
|
-
const obj2 = { a: 1, b: { c: [1, 2, 3] } };
|
|
48
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
49
|
-
});
|
|
50
|
-
it('should return true for deeply unequal objects with array', () => {
|
|
51
|
-
const obj1 = { a: 1, b: { c: [1, 2, 3] } };
|
|
52
|
-
const obj2 = { a: 1, b: { c: [1, 2, 3, 4] } };
|
|
53
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(false);
|
|
54
|
-
});
|
|
55
40
|
it('should return false for objects with different keys', () => {
|
|
56
41
|
const obj1 = { a: 1 };
|
|
57
42
|
const obj2 = { b: 1 };
|
|
@@ -82,11 +67,6 @@ describe('fastIsEqual', () => {
|
|
|
82
67
|
const arr2 = [1, 3];
|
|
83
68
|
expect((0, index_1.fastIsEqual)(arr1, arr2)).toBe(false);
|
|
84
69
|
});
|
|
85
|
-
it('should return true for arrays with different order', () => {
|
|
86
|
-
const arr1 = [1, 2, 3, 4];
|
|
87
|
-
const arr2 = [1, 2, 4, 3];
|
|
88
|
-
expect((0, index_1.fastIsEqual)(arr1, arr2)).toBe(false);
|
|
89
|
-
});
|
|
90
70
|
// **Dates**
|
|
91
71
|
it('should return true for identical dates', () => {
|
|
92
72
|
const date = new Date();
|
|
@@ -197,137 +177,4 @@ describe('fastIsEqual', () => {
|
|
|
197
177
|
expect((0, index_1.fastIsEqual)({}, [])).toBe(false);
|
|
198
178
|
expect((0, index_1.fastIsEqual)(new Map(), new Set())).toBe(false);
|
|
199
179
|
});
|
|
200
|
-
// **Symbol Tests**
|
|
201
|
-
it('should return true for identical symbols', () => {
|
|
202
|
-
const sym = Symbol('test');
|
|
203
|
-
expect((0, index_1.fastIsEqual)(sym, sym)).toBe(true);
|
|
204
|
-
});
|
|
205
|
-
it('should return false for different symbols with same description', () => {
|
|
206
|
-
expect((0, index_1.fastIsEqual)(Symbol('test'), Symbol('test'))).toBe(false);
|
|
207
|
-
});
|
|
208
|
-
// **BigInt Tests**
|
|
209
|
-
it('should return true for identical BigInts', () => {
|
|
210
|
-
expect((0, index_1.fastIsEqual)(BigInt(123), BigInt(123))).toBe(true);
|
|
211
|
-
});
|
|
212
|
-
it('should return false for different BigInts', () => {
|
|
213
|
-
expect((0, index_1.fastIsEqual)(BigInt(123), BigInt(456))).toBe(false);
|
|
214
|
-
});
|
|
215
|
-
// **Nested Complex Structures**
|
|
216
|
-
it('should handle deeply nested objects with arrays, maps and sets', () => {
|
|
217
|
-
const obj1 = {
|
|
218
|
-
a: [1, 2, { b: new Map([['key', new Set([1, 2, { c: 3 }])]]) }],
|
|
219
|
-
d: new Set([new Map([['e', { f: 7 }]])])
|
|
220
|
-
};
|
|
221
|
-
const obj2 = {
|
|
222
|
-
a: [1, 2, { b: new Map([['key', new Set([1, 2, { c: 3 }])]]) }],
|
|
223
|
-
d: new Set([new Map([['e', { f: 7 }]])])
|
|
224
|
-
};
|
|
225
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
226
|
-
});
|
|
227
|
-
it('should detect differences in deeply nested structures', () => {
|
|
228
|
-
const obj1 = {
|
|
229
|
-
a: [1, 2, { b: new Map([['key', new Set([1, 2, { c: 3 }])]]) }]
|
|
230
|
-
};
|
|
231
|
-
const obj2 = {
|
|
232
|
-
a: [1, 2, { b: new Map([['key', new Set([1, 2, { c: 4 }])]]) }]
|
|
233
|
-
};
|
|
234
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(false);
|
|
235
|
-
});
|
|
236
|
-
// **Typed Arrays**
|
|
237
|
-
it('should compare typed arrays correctly', () => {
|
|
238
|
-
expect((0, index_1.fastIsEqual)(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]))).toBe(true);
|
|
239
|
-
expect((0, index_1.fastIsEqual)(new Int32Array([1, 2, 3]), new Int32Array([1, 2, 3]))).toBe(true);
|
|
240
|
-
expect((0, index_1.fastIsEqual)(new Float64Array([1.1, 2.2]), new Float64Array([1.1, 2.2]))).toBe(true);
|
|
241
|
-
expect((0, index_1.fastIsEqual)(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4]))).toBe(false);
|
|
242
|
-
expect((0, index_1.fastIsEqual)(new Uint8Array([1, 2]), new Int8Array([1, 2]))).toBe(false);
|
|
243
|
-
});
|
|
244
|
-
// **Partial Object Comparison with Extra Keys**
|
|
245
|
-
it('should detect when objects have extra keys', () => {
|
|
246
|
-
const obj1 = { a: 1, b: 2 };
|
|
247
|
-
const obj2 = { a: 1, b: 2, c: 3 };
|
|
248
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(false);
|
|
249
|
-
});
|
|
250
|
-
// **Object with Different Property Orders**
|
|
251
|
-
it('should return true for objects with same properties in different order', () => {
|
|
252
|
-
const obj1 = { a: 1, b: 2, c: 3 };
|
|
253
|
-
const obj2 = { c: 3, a: 1, b: 2 };
|
|
254
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
255
|
-
});
|
|
256
|
-
// **Map/Set with Object Keys/Values**
|
|
257
|
-
it('should handle Maps with object keys correctly', () => {
|
|
258
|
-
const key1 = { id: 1 };
|
|
259
|
-
const key2 = { id: 1 };
|
|
260
|
-
const map1 = new Map([[key1, 'value']]);
|
|
261
|
-
const map2 = new Map([[key2, 'value']]);
|
|
262
|
-
// Objects as keys are compared by reference
|
|
263
|
-
expect((0, index_1.fastIsEqual)(map1, map2)).toBe(false);
|
|
264
|
-
// Same reference should work
|
|
265
|
-
const map3 = new Map([[key1, 'value']]);
|
|
266
|
-
expect((0, index_1.fastIsEqual)(map1, map3)).toBe(true);
|
|
267
|
-
});
|
|
268
|
-
// **WeakMap and WeakSet** (if supported by fastIsEqual)
|
|
269
|
-
it('should return true for identical WeakMap/WeakSet references', () => {
|
|
270
|
-
const weakMap = new WeakMap();
|
|
271
|
-
const weakSet = new WeakSet();
|
|
272
|
-
expect((0, index_1.fastIsEqual)(weakMap, weakMap)).toBe(true);
|
|
273
|
-
expect((0, index_1.fastIsEqual)(weakSet, weakSet)).toBe(true);
|
|
274
|
-
});
|
|
275
|
-
it('should return false for different WeakMap/WeakSet instances', () => {
|
|
276
|
-
expect((0, index_1.fastIsEqual)(new WeakMap(), new WeakMap())).toBe(false);
|
|
277
|
-
expect((0, index_1.fastIsEqual)(new WeakSet(), new WeakSet())).toBe(false);
|
|
278
|
-
});
|
|
279
|
-
// **Cross-circular References**
|
|
280
|
-
it('should handle cross-circular references', () => {
|
|
281
|
-
const obj1 = { name: 'object1' };
|
|
282
|
-
const obj2 = { name: 'object2' };
|
|
283
|
-
obj1.ref = obj2;
|
|
284
|
-
obj2.ref = obj1;
|
|
285
|
-
const obj3 = { name: 'object1' };
|
|
286
|
-
const obj4 = { name: 'object2' };
|
|
287
|
-
obj3.ref = obj4;
|
|
288
|
-
obj4.ref = obj3;
|
|
289
|
-
expect((0, index_1.fastIsEqual)(obj1, obj3)).toBe(true);
|
|
290
|
-
});
|
|
291
|
-
it('should detect differences in cross-circular references', () => {
|
|
292
|
-
const obj1 = { name: 'object1' };
|
|
293
|
-
const obj2 = { name: 'object2' };
|
|
294
|
-
obj1.ref = obj2;
|
|
295
|
-
obj2.ref = obj1;
|
|
296
|
-
const obj3 = { name: 'object1' };
|
|
297
|
-
const obj4 = { name: 'differentName' };
|
|
298
|
-
obj3.ref = obj4;
|
|
299
|
-
obj4.ref = obj3;
|
|
300
|
-
expect((0, index_1.fastIsEqual)(obj1, obj3)).toBe(false);
|
|
301
|
-
});
|
|
302
|
-
// **Edge Cases**
|
|
303
|
-
it('should handle -0 and +0 comparison', () => {
|
|
304
|
-
expect((0, index_1.fastIsEqual)(0, -0)).toBe(true); // Depending on implementation
|
|
305
|
-
});
|
|
306
|
-
it('should handle Object.create(null)', () => {
|
|
307
|
-
const obj1 = Object.create(null);
|
|
308
|
-
obj1.a = 1;
|
|
309
|
-
const obj2 = Object.create(null);
|
|
310
|
-
obj2.a = 1;
|
|
311
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
312
|
-
});
|
|
313
|
-
// **Performance Stress Test**
|
|
314
|
-
it('should handle large objects without stack overflow', () => {
|
|
315
|
-
// Create a very deep object
|
|
316
|
-
let obj1 = {};
|
|
317
|
-
let obj2 = {};
|
|
318
|
-
let temp1 = obj1;
|
|
319
|
-
let temp2 = obj2;
|
|
320
|
-
for (let i = 0; i < 1000; i++) {
|
|
321
|
-
temp1.next = {};
|
|
322
|
-
temp2.next = {};
|
|
323
|
-
temp1 = temp1.next;
|
|
324
|
-
temp2 = temp2.next;
|
|
325
|
-
temp1.value = i;
|
|
326
|
-
temp2.value = i;
|
|
327
|
-
}
|
|
328
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(true);
|
|
329
|
-
// Change a value deep in the structure
|
|
330
|
-
temp2.value = 'different';
|
|
331
|
-
expect((0, index_1.fastIsEqual)(obj1, obj2)).toBe(false);
|
|
332
|
-
});
|
|
333
180
|
});
|
package/dist/index.js
CHANGED
|
@@ -52,13 +52,6 @@ function deepEqual(valA, valB, visited) {
|
|
|
52
52
|
return valA === valB;
|
|
53
53
|
if (typeof valA !== typeof valB)
|
|
54
54
|
return false;
|
|
55
|
-
// Handle WeakMap and WeakSet (reference equality)
|
|
56
|
-
if (valA instanceof WeakMap && valB instanceof WeakMap) {
|
|
57
|
-
return valA === valB;
|
|
58
|
-
}
|
|
59
|
-
if (valA instanceof WeakSet && valB instanceof WeakSet) {
|
|
60
|
-
return valA === valB;
|
|
61
|
-
}
|
|
62
55
|
// Handle Dates
|
|
63
56
|
if (valA instanceof Date && valB instanceof Date) {
|
|
64
57
|
return valA.getTime() === valB.getTime();
|
|
@@ -103,23 +96,12 @@ function deepEqual(valA, valB, visited) {
|
|
|
103
96
|
}
|
|
104
97
|
return true;
|
|
105
98
|
}
|
|
106
|
-
// Handle Sets
|
|
99
|
+
// Handle Sets
|
|
107
100
|
if (valA instanceof Set && valB instanceof Set) {
|
|
108
101
|
if (valA.size !== valB.size)
|
|
109
102
|
return false;
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
const matched = new Set();
|
|
113
|
-
for (const elemA of arrA) {
|
|
114
|
-
let found = false;
|
|
115
|
-
for (const elemB of arrB) {
|
|
116
|
-
if (!matched.has(elemB) && deepEqual(elemA, elemB, visited)) {
|
|
117
|
-
matched.add(elemB);
|
|
118
|
-
found = true;
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (!found)
|
|
103
|
+
for (const value of valA) {
|
|
104
|
+
if (!valB.has(value))
|
|
123
105
|
return false;
|
|
124
106
|
}
|
|
125
107
|
return true;
|
package/package.json
CHANGED
|
@@ -1,13 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fast-is-equal",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Blazing-fast equality checks, minus the baggage. A lean, standalone alternative to Lodash's isEqual—because speed matters.",
|
|
5
5
|
"keywords": [
|
|
6
|
+
"deep-equal",
|
|
7
|
+
"equality",
|
|
8
|
+
"compare",
|
|
6
9
|
"lodash",
|
|
7
10
|
"isEqual",
|
|
11
|
+
"fast",
|
|
12
|
+
"performance",
|
|
8
13
|
"typescript",
|
|
14
|
+
"javascript",
|
|
9
15
|
"react",
|
|
10
|
-
"react-native"
|
|
16
|
+
"react-native",
|
|
17
|
+
"vue",
|
|
18
|
+
"angular",
|
|
19
|
+
"object-comparison",
|
|
20
|
+
"array-comparison",
|
|
21
|
+
"deep-comparison",
|
|
22
|
+
"utility",
|
|
23
|
+
"lightweight",
|
|
24
|
+
"zero-dependencies",
|
|
25
|
+
"circular-references",
|
|
26
|
+
"map",
|
|
27
|
+
"set",
|
|
28
|
+
"immutable",
|
|
29
|
+
"benchmark",
|
|
30
|
+
"speed",
|
|
31
|
+
"efficient",
|
|
32
|
+
"alternative",
|
|
33
|
+
"replacement"
|
|
11
34
|
],
|
|
12
35
|
"homepage": "https://github.com/JairajJangle/fast-is-equal#readme",
|
|
13
36
|
"bugs": {
|
|
@@ -19,6 +42,10 @@
|
|
|
19
42
|
},
|
|
20
43
|
"license": "MIT",
|
|
21
44
|
"author": "Jairaj Jangle <reachout.jairaj.jangle@gmail.com> (https://github.com/JairajJangle)",
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"registry": "https://registry.npmjs.org/",
|
|
47
|
+
"provenance": true
|
|
48
|
+
},
|
|
22
49
|
"main": "dist/index.js",
|
|
23
50
|
"types": "dist/index.d.ts",
|
|
24
51
|
"scripts": {
|
|
@@ -31,11 +58,16 @@
|
|
|
31
58
|
"dist"
|
|
32
59
|
],
|
|
33
60
|
"devDependencies": {
|
|
61
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
62
|
+
"@semantic-release/git": "^10.0.1",
|
|
63
|
+
"@semantic-release/github": "^10.1.7",
|
|
64
|
+
"@semantic-release/npm": "^12.0.1",
|
|
34
65
|
"@types/jest": "^29.5.3",
|
|
35
66
|
"@types/lodash": "^4.17.16",
|
|
36
67
|
"jest": "^29.7.0",
|
|
37
68
|
"lodash": "^4.17.21",
|
|
38
69
|
"rimraf": "^6.0.1",
|
|
70
|
+
"semantic-release": "^24.1.0",
|
|
39
71
|
"ts-jest": "^29.1.1",
|
|
40
72
|
"ts-node": "^10.9.2",
|
|
41
73
|
"tslib": "^2.8.1",
|