fast-equals 5.3.3 → 5.4.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 +1 -1
- package/README.md +128 -77
- package/dist/cjs/comparator.d.cts +60 -0
- package/dist/cjs/{types/equals.d.cts → equals.d.cts} +8 -0
- package/dist/cjs/index.cjs +171 -162
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/{types/index.d.cts → index.d.cts} +21 -2
- package/{src/internalTypes.ts → dist/cjs/internalTypes.d.cts} +18 -50
- package/dist/cjs/{types/utils.d.cts → utils.d.cts} +7 -2
- package/dist/es/comparator.d.mts +60 -0
- package/dist/{esm/types → es}/equals.d.mts +8 -0
- package/dist/{esm/types → es}/index.d.mts +21 -2
- package/dist/{esm → es}/index.mjs +171 -162
- package/dist/es/index.mjs.map +1 -0
- package/dist/es/internalTypes.d.mts +178 -0
- package/dist/{esm/types → es}/utils.d.mts +7 -2
- package/dist/{min/types → umd}/comparator.d.ts +2 -2
- package/dist/{min/types → umd}/equals.d.ts +8 -0
- package/dist/umd/index.js +171 -162
- package/dist/umd/index.js.map +1 -1
- package/dist/{min/types → umd}/internalTypes.d.ts +10 -8
- package/index.d.ts +73 -75
- package/package.json +45 -48
- package/CHANGELOG.md +0 -364
- package/dist/cjs/types/comparator.d.cts +0 -26
- package/dist/cjs/types/internalTypes.d.cts +0 -157
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/types/comparator.d.mts +0 -26
- package/dist/esm/types/internalTypes.d.mts +0 -157
- package/dist/min/index.js +0 -1
- package/dist/umd/types/comparator.d.ts +0 -26
- package/dist/umd/types/equals.d.ts +0 -54
- package/dist/umd/types/index.d.ts +0 -47
- package/dist/umd/types/internalTypes.d.ts +0 -157
- package/dist/umd/types/utils.d.ts +0 -28
- package/src/comparator.ts +0 -376
- package/src/equals.ts +0 -355
- package/src/index.ts +0 -112
- package/src/utils.ts +0 -96
- /package/dist/{min/types → umd}/index.d.ts +0 -0
- /package/dist/{min/types → umd}/utils.d.ts +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
3
|
+
const { hasOwnProperty } = Object.prototype;
|
|
3
4
|
/**
|
|
4
5
|
* Combine two comparators into a single comparators.
|
|
5
6
|
*/
|
|
@@ -18,15 +19,15 @@ function createIsCircular(areItemsEqual) {
|
|
|
18
19
|
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
|
19
20
|
return areItemsEqual(a, b, state);
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
const { cache } = state;
|
|
23
|
+
const cachedA = cache.get(a);
|
|
24
|
+
const cachedB = cache.get(b);
|
|
24
25
|
if (cachedA && cachedB) {
|
|
25
26
|
return cachedA === b && cachedB === a;
|
|
26
27
|
}
|
|
27
28
|
cache.set(a, b);
|
|
28
29
|
cache.set(b, a);
|
|
29
|
-
|
|
30
|
+
const result = areItemsEqual(a, b, state);
|
|
30
31
|
cache.delete(a);
|
|
31
32
|
cache.delete(b);
|
|
32
33
|
return result;
|
|
@@ -48,12 +49,9 @@ function getStrictProperties(object) {
|
|
|
48
49
|
/**
|
|
49
50
|
* Whether the object contains the property passed as an own property.
|
|
50
51
|
*/
|
|
51
|
-
|
|
52
|
+
const hasOwn =
|
|
52
53
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
53
|
-
Object.hasOwn ||
|
|
54
|
-
(function (object, property) {
|
|
55
|
-
return hasOwnProperty.call(object, property);
|
|
56
|
-
});
|
|
54
|
+
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
|
|
57
55
|
/**
|
|
58
56
|
* Whether the values passed are strictly equal or both NaN.
|
|
59
57
|
*/
|
|
@@ -61,15 +59,21 @@ function sameValueZeroEqual(a, b) {
|
|
|
61
59
|
return a === b || (!a && !b && a !== a && b !== b);
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
const PREACT_VNODE = '__v';
|
|
63
|
+
const PREACT_OWNER = '__o';
|
|
64
|
+
const REACT_OWNER = '_owner';
|
|
65
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
66
|
+
/**
|
|
67
|
+
* Whether the array buffers are equal in value.
|
|
68
|
+
*/
|
|
69
|
+
function areArrayBuffersEqual(a, b) {
|
|
70
|
+
return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));
|
|
71
|
+
}
|
|
68
72
|
/**
|
|
69
73
|
* Whether the arrays are equal in value.
|
|
70
74
|
*/
|
|
71
75
|
function areArraysEqual(a, b, state) {
|
|
72
|
-
|
|
76
|
+
let index = a.length;
|
|
73
77
|
if (b.length !== index) {
|
|
74
78
|
return false;
|
|
75
79
|
}
|
|
@@ -80,6 +84,13 @@ function areArraysEqual(a, b, state) {
|
|
|
80
84
|
}
|
|
81
85
|
return true;
|
|
82
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Whether the dataviews are equal in value.
|
|
89
|
+
*/
|
|
90
|
+
function areDataViewsEqual(a, b) {
|
|
91
|
+
return (a.byteLength === b.byteLength
|
|
92
|
+
&& areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength)));
|
|
93
|
+
}
|
|
83
94
|
/**
|
|
84
95
|
* Whether the dates passed are equal in value.
|
|
85
96
|
*/
|
|
@@ -90,10 +101,7 @@ function areDatesEqual(a, b) {
|
|
|
90
101
|
* Whether the errors passed are equal in value.
|
|
91
102
|
*/
|
|
92
103
|
function areErrorsEqual(a, b) {
|
|
93
|
-
return
|
|
94
|
-
a.message === b.message &&
|
|
95
|
-
a.cause === b.cause &&
|
|
96
|
-
a.stack === b.stack);
|
|
104
|
+
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
97
105
|
}
|
|
98
106
|
/**
|
|
99
107
|
* Whether the functions passed are equal in value.
|
|
@@ -105,26 +113,26 @@ function areFunctionsEqual(a, b) {
|
|
|
105
113
|
* Whether the `Map`s are equal in value.
|
|
106
114
|
*/
|
|
107
115
|
function areMapsEqual(a, b, state) {
|
|
108
|
-
|
|
116
|
+
const size = a.size;
|
|
109
117
|
if (size !== b.size) {
|
|
110
118
|
return false;
|
|
111
119
|
}
|
|
112
120
|
if (!size) {
|
|
113
121
|
return true;
|
|
114
122
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
const matchedIndices = new Array(size);
|
|
124
|
+
const aIterable = a.entries();
|
|
125
|
+
let aResult;
|
|
126
|
+
let bResult;
|
|
127
|
+
let index = 0;
|
|
120
128
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
121
129
|
while ((aResult = aIterable.next())) {
|
|
122
130
|
if (aResult.done) {
|
|
123
131
|
break;
|
|
124
132
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
const bIterable = b.entries();
|
|
134
|
+
let hasMatch = false;
|
|
135
|
+
let matchIndex = 0;
|
|
128
136
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
129
137
|
while ((bResult = bIterable.next())) {
|
|
130
138
|
if (bResult.done) {
|
|
@@ -134,10 +142,10 @@ function areMapsEqual(a, b, state) {
|
|
|
134
142
|
matchIndex++;
|
|
135
143
|
continue;
|
|
136
144
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state)
|
|
140
|
-
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
|
145
|
+
const aEntry = aResult.value;
|
|
146
|
+
const bEntry = bResult.value;
|
|
147
|
+
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state)
|
|
148
|
+
&& state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
|
141
149
|
hasMatch = matchedIndices[matchIndex] = true;
|
|
142
150
|
break;
|
|
143
151
|
}
|
|
@@ -153,13 +161,13 @@ function areMapsEqual(a, b, state) {
|
|
|
153
161
|
/**
|
|
154
162
|
* Whether the numbers are equal in value.
|
|
155
163
|
*/
|
|
156
|
-
|
|
164
|
+
const areNumbersEqual = sameValueZeroEqual;
|
|
157
165
|
/**
|
|
158
166
|
* Whether the objects are equal in value.
|
|
159
167
|
*/
|
|
160
168
|
function areObjectsEqual(a, b, state) {
|
|
161
|
-
|
|
162
|
-
|
|
169
|
+
const properties = keys(a);
|
|
170
|
+
let index = properties.length;
|
|
163
171
|
if (keys(b).length !== index) {
|
|
164
172
|
return false;
|
|
165
173
|
}
|
|
@@ -178,14 +186,14 @@ function areObjectsEqual(a, b, state) {
|
|
|
178
186
|
* Whether the objects are equal in value with strict property checking.
|
|
179
187
|
*/
|
|
180
188
|
function areObjectsEqualStrict(a, b, state) {
|
|
181
|
-
|
|
182
|
-
|
|
189
|
+
const properties = getStrictProperties(a);
|
|
190
|
+
let index = properties.length;
|
|
183
191
|
if (getStrictProperties(b).length !== index) {
|
|
184
192
|
return false;
|
|
185
193
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
let property;
|
|
195
|
+
let descriptorA;
|
|
196
|
+
let descriptorB;
|
|
189
197
|
// Decrementing `while` showed faster results than either incrementing or
|
|
190
198
|
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
191
199
|
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
@@ -197,12 +205,12 @@ function areObjectsEqualStrict(a, b, state) {
|
|
|
197
205
|
}
|
|
198
206
|
descriptorA = getOwnPropertyDescriptor(a, property);
|
|
199
207
|
descriptorB = getOwnPropertyDescriptor(b, property);
|
|
200
|
-
if ((descriptorA || descriptorB)
|
|
201
|
-
(!descriptorA
|
|
202
|
-
!descriptorB
|
|
203
|
-
descriptorA.configurable !== descriptorB.configurable
|
|
204
|
-
descriptorA.enumerable !== descriptorB.enumerable
|
|
205
|
-
descriptorA.writable !== descriptorB.writable)) {
|
|
208
|
+
if ((descriptorA || descriptorB)
|
|
209
|
+
&& (!descriptorA
|
|
210
|
+
|| !descriptorB
|
|
211
|
+
|| descriptorA.configurable !== descriptorB.configurable
|
|
212
|
+
|| descriptorA.enumerable !== descriptorB.enumerable
|
|
213
|
+
|| descriptorA.writable !== descriptorB.writable)) {
|
|
206
214
|
return false;
|
|
207
215
|
}
|
|
208
216
|
}
|
|
@@ -224,32 +232,32 @@ function areRegExpsEqual(a, b) {
|
|
|
224
232
|
* Whether the `Set`s are equal in value.
|
|
225
233
|
*/
|
|
226
234
|
function areSetsEqual(a, b, state) {
|
|
227
|
-
|
|
235
|
+
const size = a.size;
|
|
228
236
|
if (size !== b.size) {
|
|
229
237
|
return false;
|
|
230
238
|
}
|
|
231
239
|
if (!size) {
|
|
232
240
|
return true;
|
|
233
241
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
242
|
+
const matchedIndices = new Array(size);
|
|
243
|
+
const aIterable = a.values();
|
|
244
|
+
let aResult;
|
|
245
|
+
let bResult;
|
|
238
246
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
239
247
|
while ((aResult = aIterable.next())) {
|
|
240
248
|
if (aResult.done) {
|
|
241
249
|
break;
|
|
242
250
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
251
|
+
const bIterable = b.values();
|
|
252
|
+
let hasMatch = false;
|
|
253
|
+
let matchIndex = 0;
|
|
246
254
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
247
255
|
while ((bResult = bIterable.next())) {
|
|
248
256
|
if (bResult.done) {
|
|
249
257
|
break;
|
|
250
258
|
}
|
|
251
|
-
if (!matchedIndices[matchIndex]
|
|
252
|
-
state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
|
259
|
+
if (!matchedIndices[matchIndex]
|
|
260
|
+
&& state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
|
253
261
|
hasMatch = matchedIndices[matchIndex] = true;
|
|
254
262
|
break;
|
|
255
263
|
}
|
|
@@ -265,8 +273,8 @@ function areSetsEqual(a, b, state) {
|
|
|
265
273
|
* Whether the TypedArray instances are equal in value.
|
|
266
274
|
*/
|
|
267
275
|
function areTypedArraysEqual(a, b) {
|
|
268
|
-
|
|
269
|
-
if (b.
|
|
276
|
+
let index = a.byteLength;
|
|
277
|
+
if (b.byteLength !== index || a.byteOffset !== b.byteOffset) {
|
|
270
278
|
return false;
|
|
271
279
|
}
|
|
272
280
|
while (index-- > 0) {
|
|
@@ -280,47 +288,55 @@ function areTypedArraysEqual(a, b) {
|
|
|
280
288
|
* Whether the URL instances are equal in value.
|
|
281
289
|
*/
|
|
282
290
|
function areUrlsEqual(a, b) {
|
|
283
|
-
return (a.hostname === b.hostname
|
|
284
|
-
a.pathname === b.pathname
|
|
285
|
-
a.protocol === b.protocol
|
|
286
|
-
a.port === b.port
|
|
287
|
-
a.hash === b.hash
|
|
288
|
-
a.username === b.username
|
|
289
|
-
a.password === b.password);
|
|
291
|
+
return (a.hostname === b.hostname
|
|
292
|
+
&& a.pathname === b.pathname
|
|
293
|
+
&& a.protocol === b.protocol
|
|
294
|
+
&& a.port === b.port
|
|
295
|
+
&& a.hash === b.hash
|
|
296
|
+
&& a.username === b.username
|
|
297
|
+
&& a.password === b.password);
|
|
290
298
|
}
|
|
291
299
|
function isPropertyEqual(a, b, state, property) {
|
|
292
|
-
if ((property === REACT_OWNER ||
|
|
293
|
-
|
|
294
|
-
property === PREACT_VNODE) &&
|
|
295
|
-
(a.$$typeof || b.$$typeof)) {
|
|
300
|
+
if ((property === REACT_OWNER || property === PREACT_OWNER || property === PREACT_VNODE)
|
|
301
|
+
&& (a.$$typeof || b.$$typeof)) {
|
|
296
302
|
return true;
|
|
297
303
|
}
|
|
298
|
-
return
|
|
299
|
-
state.equals(a[property], b[property], property, property, a, b, state));
|
|
304
|
+
return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);
|
|
300
305
|
}
|
|
301
306
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
:
|
|
317
|
-
|
|
318
|
-
|
|
307
|
+
const ARRAY_BUFFER_TAG = '[object ArrayBuffer]';
|
|
308
|
+
const ARGUMENTS_TAG = '[object Arguments]';
|
|
309
|
+
const BOOLEAN_TAG = '[object Boolean]';
|
|
310
|
+
const DATA_VIEW_TAG = '[object DataView]';
|
|
311
|
+
const DATE_TAG = '[object Date]';
|
|
312
|
+
const ERROR_TAG = '[object Error]';
|
|
313
|
+
const MAP_TAG = '[object Map]';
|
|
314
|
+
const NUMBER_TAG = '[object Number]';
|
|
315
|
+
const OBJECT_TAG = '[object Object]';
|
|
316
|
+
const REG_EXP_TAG = '[object RegExp]';
|
|
317
|
+
const SET_TAG = '[object Set]';
|
|
318
|
+
const STRING_TAG = '[object String]';
|
|
319
|
+
const TYPED_ARRAY_TAGS = {
|
|
320
|
+
'[object Int8Array]': true,
|
|
321
|
+
'[object Uint8Array]': true,
|
|
322
|
+
'[object Uint8ClampedArray]': true,
|
|
323
|
+
'[object Int16Array]': true,
|
|
324
|
+
'[object Uint16Array]': true,
|
|
325
|
+
'[object Int32Array]': true,
|
|
326
|
+
'[object Uint32Array]': true,
|
|
327
|
+
'[object Float16Array]': true,
|
|
328
|
+
'[object Float32Array]': true,
|
|
329
|
+
'[object Float64Array]': true,
|
|
330
|
+
'[object BigInt64Array]': true,
|
|
331
|
+
'[object BigUint64Array]': true,
|
|
332
|
+
};
|
|
333
|
+
const URL_TAG = '[object URL]';
|
|
334
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
335
|
+
const toString = Object.prototype.toString;
|
|
319
336
|
/**
|
|
320
337
|
* Create a comparator method based on the type-specific equality comparators passed.
|
|
321
338
|
*/
|
|
322
|
-
function createEqualityComparator(
|
|
323
|
-
var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areErrorsEqual = _a.areErrorsEqual, areFunctionsEqual = _a.areFunctionsEqual, areMapsEqual = _a.areMapsEqual, areNumbersEqual = _a.areNumbersEqual, areObjectsEqual = _a.areObjectsEqual, arePrimitiveWrappersEqual = _a.arePrimitiveWrappersEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, areTypedArraysEqual = _a.areTypedArraysEqual, areUrlsEqual = _a.areUrlsEqual, unknownTagComparators = _a.unknownTagComparators;
|
|
339
|
+
function createEqualityComparator({ areArrayBuffersEqual, areArraysEqual, areDataViewsEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators, }) {
|
|
324
340
|
/**
|
|
325
341
|
* compare the value of the two objects and return true if they are equivalent in values
|
|
326
342
|
*/
|
|
@@ -334,7 +350,7 @@ function createEqualityComparator(_a) {
|
|
|
334
350
|
if (a == null || b == null) {
|
|
335
351
|
return false;
|
|
336
352
|
}
|
|
337
|
-
|
|
353
|
+
const type = typeof a;
|
|
338
354
|
if (type !== typeof b) {
|
|
339
355
|
return false;
|
|
340
356
|
}
|
|
@@ -348,7 +364,7 @@ function createEqualityComparator(_a) {
|
|
|
348
364
|
// If a primitive value that is not strictly equal, it must be unequal.
|
|
349
365
|
return false;
|
|
350
366
|
}
|
|
351
|
-
|
|
367
|
+
const constructor = a.constructor;
|
|
352
368
|
// Checks are listed in order of commonality of use-case:
|
|
353
369
|
// 1. Common complex object types (plain object, array)
|
|
354
370
|
// 2. Common data values (date, regexp)
|
|
@@ -370,14 +386,9 @@ function createEqualityComparator(_a) {
|
|
|
370
386
|
}
|
|
371
387
|
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
|
372
388
|
// the string tag or doing an `instanceof` check.
|
|
373
|
-
if (isArray(a)) {
|
|
389
|
+
if (Array.isArray(a)) {
|
|
374
390
|
return areArraysEqual(a, b, state);
|
|
375
391
|
}
|
|
376
|
-
// `isTypedArray()` works on all possible TypedArray classes, so we can avoid
|
|
377
|
-
// capturing the string tag or comparing against all possible constructors.
|
|
378
|
-
if (isTypedArray != null && isTypedArray(a)) {
|
|
379
|
-
return areTypedArraysEqual(a, b, state);
|
|
380
|
-
}
|
|
381
392
|
// Try to fast-path equality checks for other complex object types in the
|
|
382
393
|
// same realm to avoid capturing the string tag. Strict equality is used
|
|
383
394
|
// instead of `instanceof` because it is more performant for the common
|
|
@@ -397,7 +408,7 @@ function createEqualityComparator(_a) {
|
|
|
397
408
|
}
|
|
398
409
|
// Since this is a custom object, capture the string tag to determing its type.
|
|
399
410
|
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
|
400
|
-
|
|
411
|
+
const tag = toString.call(a);
|
|
401
412
|
if (tag === DATE_TAG) {
|
|
402
413
|
return areDatesEqual(a, b, state);
|
|
403
414
|
}
|
|
@@ -416,9 +427,7 @@ function createEqualityComparator(_a) {
|
|
|
416
427
|
// The exception for value comparison is custom `Promise`-like class instances. These should
|
|
417
428
|
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
|
418
429
|
// it reaches this point then that strict equality comparison has already failed.
|
|
419
|
-
return
|
|
420
|
-
typeof b.then !== 'function' &&
|
|
421
|
-
areObjectsEqual(a, b, state));
|
|
430
|
+
return typeof a.then !== 'function' && typeof b.then !== 'function' && areObjectsEqual(a, b, state);
|
|
422
431
|
}
|
|
423
432
|
// If a URL tag, it should be tested explicitly. Like RegExp, the properties are not
|
|
424
433
|
// enumerable, and therefore will give false positives if tested like a standard object.
|
|
@@ -434,6 +443,15 @@ function createEqualityComparator(_a) {
|
|
|
434
443
|
if (tag === ARGUMENTS_TAG) {
|
|
435
444
|
return areObjectsEqual(a, b, state);
|
|
436
445
|
}
|
|
446
|
+
if (TYPED_ARRAY_TAGS[tag]) {
|
|
447
|
+
return areTypedArraysEqual(a, b, state);
|
|
448
|
+
}
|
|
449
|
+
if (tag === ARRAY_BUFFER_TAG) {
|
|
450
|
+
return areArrayBuffersEqual(a, b, state);
|
|
451
|
+
}
|
|
452
|
+
if (tag === DATA_VIEW_TAG) {
|
|
453
|
+
return areDataViewsEqual(a, b, state);
|
|
454
|
+
}
|
|
437
455
|
// As the penultimate fallback, check if the values passed are primitive wrappers. This
|
|
438
456
|
// is very rare in modern JS, which is why it is deprioritized compared to all other object
|
|
439
457
|
// types.
|
|
@@ -441,9 +459,9 @@ function createEqualityComparator(_a) {
|
|
|
441
459
|
return arePrimitiveWrappersEqual(a, b, state);
|
|
442
460
|
}
|
|
443
461
|
if (unknownTagComparators) {
|
|
444
|
-
|
|
462
|
+
let unknownTagComparator = unknownTagComparators[tag];
|
|
445
463
|
if (!unknownTagComparator) {
|
|
446
|
-
|
|
464
|
+
const shortTag = getShortTag(a);
|
|
447
465
|
if (shortTag) {
|
|
448
466
|
unknownTagComparator = unknownTagComparators[shortTag];
|
|
449
467
|
}
|
|
@@ -471,46 +489,39 @@ function createEqualityComparator(_a) {
|
|
|
471
489
|
/**
|
|
472
490
|
* Create the configuration object used for building comparators.
|
|
473
491
|
*/
|
|
474
|
-
function createEqualityComparatorConfig(
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
areArraysEqual: strict
|
|
478
|
-
|
|
479
|
-
: areArraysEqual,
|
|
492
|
+
function createEqualityComparatorConfig({ circular, createCustomConfig, strict, }) {
|
|
493
|
+
let config = {
|
|
494
|
+
areArrayBuffersEqual,
|
|
495
|
+
areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
|
|
496
|
+
areDataViewsEqual,
|
|
480
497
|
areDatesEqual: areDatesEqual,
|
|
481
498
|
areErrorsEqual: areErrorsEqual,
|
|
482
499
|
areFunctionsEqual: areFunctionsEqual,
|
|
483
|
-
areMapsEqual: strict
|
|
484
|
-
? combineComparators(areMapsEqual, areObjectsEqualStrict)
|
|
485
|
-
: areMapsEqual,
|
|
500
|
+
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
486
501
|
areNumbersEqual: areNumbersEqual,
|
|
487
|
-
areObjectsEqual: strict
|
|
488
|
-
? areObjectsEqualStrict
|
|
489
|
-
: areObjectsEqual,
|
|
502
|
+
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
490
503
|
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
|
491
504
|
areRegExpsEqual: areRegExpsEqual,
|
|
492
|
-
areSetsEqual: strict
|
|
493
|
-
? combineComparators(areSetsEqual, areObjectsEqualStrict)
|
|
494
|
-
: areSetsEqual,
|
|
505
|
+
areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
|
|
495
506
|
areTypedArraysEqual: strict
|
|
496
|
-
? areObjectsEqualStrict
|
|
507
|
+
? combineComparators(areTypedArraysEqual, areObjectsEqualStrict)
|
|
497
508
|
: areTypedArraysEqual,
|
|
498
509
|
areUrlsEqual: areUrlsEqual,
|
|
499
510
|
unknownTagComparators: undefined,
|
|
500
511
|
};
|
|
501
512
|
if (createCustomConfig) {
|
|
502
|
-
config = assign({}, config, createCustomConfig(config));
|
|
513
|
+
config = Object.assign({}, config, createCustomConfig(config));
|
|
503
514
|
}
|
|
504
515
|
if (circular) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
config = assign({}, config, {
|
|
510
|
-
areArraysEqual
|
|
511
|
-
areMapsEqual
|
|
512
|
-
areObjectsEqual
|
|
513
|
-
areSetsEqual
|
|
516
|
+
const areArraysEqual = createIsCircular(config.areArraysEqual);
|
|
517
|
+
const areMapsEqual = createIsCircular(config.areMapsEqual);
|
|
518
|
+
const areObjectsEqual = createIsCircular(config.areObjectsEqual);
|
|
519
|
+
const areSetsEqual = createIsCircular(config.areSetsEqual);
|
|
520
|
+
config = Object.assign({}, config, {
|
|
521
|
+
areArraysEqual,
|
|
522
|
+
areMapsEqual,
|
|
523
|
+
areObjectsEqual,
|
|
524
|
+
areSetsEqual,
|
|
514
525
|
});
|
|
515
526
|
}
|
|
516
527
|
return config;
|
|
@@ -527,16 +538,15 @@ function createInternalEqualityComparator(compare) {
|
|
|
527
538
|
/**
|
|
528
539
|
* Create the `isEqual` function used by the consuming application.
|
|
529
540
|
*/
|
|
530
|
-
function createIsEqual(
|
|
531
|
-
var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;
|
|
541
|
+
function createIsEqual({ circular, comparator, createState, equals, strict }) {
|
|
532
542
|
if (createState) {
|
|
533
543
|
return function isEqual(a, b) {
|
|
534
|
-
|
|
544
|
+
const { cache = circular ? new WeakMap() : undefined, meta } = createState();
|
|
535
545
|
return comparator(a, b, {
|
|
536
|
-
cache
|
|
537
|
-
equals
|
|
538
|
-
meta
|
|
539
|
-
strict
|
|
546
|
+
cache,
|
|
547
|
+
equals,
|
|
548
|
+
meta,
|
|
549
|
+
strict,
|
|
540
550
|
});
|
|
541
551
|
};
|
|
542
552
|
}
|
|
@@ -544,17 +554,17 @@ function createIsEqual(_a) {
|
|
|
544
554
|
return function isEqual(a, b) {
|
|
545
555
|
return comparator(a, b, {
|
|
546
556
|
cache: new WeakMap(),
|
|
547
|
-
equals
|
|
557
|
+
equals,
|
|
548
558
|
meta: undefined,
|
|
549
|
-
strict
|
|
559
|
+
strict,
|
|
550
560
|
});
|
|
551
561
|
};
|
|
552
562
|
}
|
|
553
|
-
|
|
563
|
+
const state = {
|
|
554
564
|
cache: undefined,
|
|
555
|
-
equals
|
|
565
|
+
equals,
|
|
556
566
|
meta: undefined,
|
|
557
|
-
strict
|
|
567
|
+
strict,
|
|
558
568
|
};
|
|
559
569
|
return function isEqual(a, b) {
|
|
560
570
|
return comparator(a, b, state);
|
|
@@ -564,50 +574,50 @@ function createIsEqual(_a) {
|
|
|
564
574
|
/**
|
|
565
575
|
* Whether the items passed are deeply-equal in value.
|
|
566
576
|
*/
|
|
567
|
-
|
|
577
|
+
const deepEqual = createCustomEqual();
|
|
568
578
|
/**
|
|
569
579
|
* Whether the items passed are deeply-equal in value based on strict comparison.
|
|
570
580
|
*/
|
|
571
|
-
|
|
581
|
+
const strictDeepEqual = createCustomEqual({ strict: true });
|
|
572
582
|
/**
|
|
573
583
|
* Whether the items passed are deeply-equal in value, including circular references.
|
|
574
584
|
*/
|
|
575
|
-
|
|
585
|
+
const circularDeepEqual = createCustomEqual({ circular: true });
|
|
576
586
|
/**
|
|
577
587
|
* Whether the items passed are deeply-equal in value, including circular references,
|
|
578
588
|
* based on strict comparison.
|
|
579
589
|
*/
|
|
580
|
-
|
|
590
|
+
const strictCircularDeepEqual = createCustomEqual({
|
|
581
591
|
circular: true,
|
|
582
592
|
strict: true,
|
|
583
593
|
});
|
|
584
594
|
/**
|
|
585
595
|
* Whether the items passed are shallowly-equal in value.
|
|
586
596
|
*/
|
|
587
|
-
|
|
588
|
-
createInternalComparator:
|
|
597
|
+
const shallowEqual = createCustomEqual({
|
|
598
|
+
createInternalComparator: () => sameValueZeroEqual,
|
|
589
599
|
});
|
|
590
600
|
/**
|
|
591
601
|
* Whether the items passed are shallowly-equal in value based on strict comparison
|
|
592
602
|
*/
|
|
593
|
-
|
|
603
|
+
const strictShallowEqual = createCustomEqual({
|
|
594
604
|
strict: true,
|
|
595
|
-
createInternalComparator:
|
|
605
|
+
createInternalComparator: () => sameValueZeroEqual,
|
|
596
606
|
});
|
|
597
607
|
/**
|
|
598
608
|
* Whether the items passed are shallowly-equal in value, including circular references.
|
|
599
609
|
*/
|
|
600
|
-
|
|
610
|
+
const circularShallowEqual = createCustomEqual({
|
|
601
611
|
circular: true,
|
|
602
|
-
createInternalComparator:
|
|
612
|
+
createInternalComparator: () => sameValueZeroEqual,
|
|
603
613
|
});
|
|
604
614
|
/**
|
|
605
615
|
* Whether the items passed are shallowly-equal in value, including circular references,
|
|
606
616
|
* based on strict comparison.
|
|
607
617
|
*/
|
|
608
|
-
|
|
618
|
+
const strictCircularShallowEqual = createCustomEqual({
|
|
609
619
|
circular: true,
|
|
610
|
-
createInternalComparator:
|
|
620
|
+
createInternalComparator: () => sameValueZeroEqual,
|
|
611
621
|
strict: true,
|
|
612
622
|
});
|
|
613
623
|
/**
|
|
@@ -618,15 +628,14 @@ var strictCircularShallowEqual = createCustomEqual({
|
|
|
618
628
|
* support for legacy environments that do not support expected features like
|
|
619
629
|
* `RegExp.prototype.flags` out of the box.
|
|
620
630
|
*/
|
|
621
|
-
function createCustomEqual(options) {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
var equals = createCustomInternalComparator
|
|
631
|
+
function createCustomEqual(options = {}) {
|
|
632
|
+
const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false, } = options;
|
|
633
|
+
const config = createEqualityComparatorConfig(options);
|
|
634
|
+
const comparator = createEqualityComparator(config);
|
|
635
|
+
const equals = createCustomInternalComparator
|
|
627
636
|
? createCustomInternalComparator(comparator)
|
|
628
637
|
: createInternalEqualityComparator(comparator);
|
|
629
|
-
return createIsEqual({ circular
|
|
638
|
+
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
630
639
|
}
|
|
631
640
|
|
|
632
641
|
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|