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
package/src/equals.ts
DELETED
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
Dictionary,
|
|
3
|
-
PrimitiveWrapper,
|
|
4
|
-
State,
|
|
5
|
-
TypedArray,
|
|
6
|
-
} from './internalTypes.js';
|
|
7
|
-
import { getStrictProperties, hasOwn, sameValueZeroEqual } from './utils.js';
|
|
8
|
-
|
|
9
|
-
const PREACT_VNODE = '__v';
|
|
10
|
-
const PREACT_OWNER = '__o';
|
|
11
|
-
const REACT_OWNER = '_owner';
|
|
12
|
-
|
|
13
|
-
const { getOwnPropertyDescriptor, keys } = Object;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Whether the arrays are equal in value.
|
|
17
|
-
*/
|
|
18
|
-
export function areArraysEqual(a: any[], b: any[], state: State<any>) {
|
|
19
|
-
let index = a.length;
|
|
20
|
-
|
|
21
|
-
if (b.length !== index) {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
while (index-- > 0) {
|
|
26
|
-
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Whether the dates passed are equal in value.
|
|
36
|
-
*/
|
|
37
|
-
export function areDatesEqual(a: Date, b: Date): boolean {
|
|
38
|
-
return sameValueZeroEqual(a.getTime(), b.getTime());
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Whether the errors passed are equal in value.
|
|
43
|
-
*/
|
|
44
|
-
export function areErrorsEqual(a: Error, b: Error): boolean {
|
|
45
|
-
return (
|
|
46
|
-
a.name === b.name &&
|
|
47
|
-
a.message === b.message &&
|
|
48
|
-
a.cause === b.cause &&
|
|
49
|
-
a.stack === b.stack
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Whether the functions passed are equal in value.
|
|
55
|
-
*/
|
|
56
|
-
export function areFunctionsEqual(
|
|
57
|
-
a: (...args: any[]) => any,
|
|
58
|
-
b: (...args: any[]) => any,
|
|
59
|
-
): boolean {
|
|
60
|
-
return a === b;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Whether the `Map`s are equal in value.
|
|
65
|
-
*/
|
|
66
|
-
export function areMapsEqual(
|
|
67
|
-
a: Map<any, any>,
|
|
68
|
-
b: Map<any, any>,
|
|
69
|
-
state: State<any>,
|
|
70
|
-
): boolean {
|
|
71
|
-
const size = a.size;
|
|
72
|
-
|
|
73
|
-
if (size !== b.size) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!size) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const matchedIndices = new Array<true | undefined>(size);
|
|
82
|
-
const aIterable = a.entries();
|
|
83
|
-
|
|
84
|
-
let aResult: IteratorResult<[any, any]>;
|
|
85
|
-
let bResult: IteratorResult<[any, any]>;
|
|
86
|
-
let index = 0;
|
|
87
|
-
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
89
|
-
while ((aResult = aIterable.next())) {
|
|
90
|
-
if (aResult.done) {
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const bIterable = b.entries();
|
|
95
|
-
|
|
96
|
-
let hasMatch = false;
|
|
97
|
-
let matchIndex = 0;
|
|
98
|
-
|
|
99
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
100
|
-
while ((bResult = bIterable.next())) {
|
|
101
|
-
if (bResult.done) {
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (matchedIndices[matchIndex]) {
|
|
106
|
-
matchIndex++;
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
const aEntry = aResult.value;
|
|
111
|
-
const bEntry = bResult.value;
|
|
112
|
-
|
|
113
|
-
if (
|
|
114
|
-
state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) &&
|
|
115
|
-
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)
|
|
116
|
-
) {
|
|
117
|
-
hasMatch = matchedIndices[matchIndex] = true;
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
matchIndex++;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (!hasMatch) {
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
index++;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Whether the numbers are equal in value.
|
|
136
|
-
*/
|
|
137
|
-
export const areNumbersEqual = sameValueZeroEqual;
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Whether the objects are equal in value.
|
|
141
|
-
*/
|
|
142
|
-
export function areObjectsEqual(
|
|
143
|
-
a: Dictionary,
|
|
144
|
-
b: Dictionary,
|
|
145
|
-
state: State<any>,
|
|
146
|
-
): boolean {
|
|
147
|
-
const properties = keys(a);
|
|
148
|
-
|
|
149
|
-
let index = properties.length;
|
|
150
|
-
|
|
151
|
-
if (keys(b).length !== index) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Decrementing `while` showed faster results than either incrementing or
|
|
156
|
-
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
157
|
-
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
158
|
-
// cost of anonymous callbacks.
|
|
159
|
-
while (index-- > 0) {
|
|
160
|
-
if (!isPropertyEqual(a, b, state, properties[index]!)) {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Whether the objects are equal in value with strict property checking.
|
|
170
|
-
*/
|
|
171
|
-
export function areObjectsEqualStrict(
|
|
172
|
-
a: Dictionary,
|
|
173
|
-
b: Dictionary,
|
|
174
|
-
state: State<any>,
|
|
175
|
-
): boolean {
|
|
176
|
-
const properties = getStrictProperties(a);
|
|
177
|
-
|
|
178
|
-
let index = properties.length;
|
|
179
|
-
|
|
180
|
-
if (getStrictProperties(b).length !== index) {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
let property: string | symbol;
|
|
185
|
-
let descriptorA: ReturnType<typeof getOwnPropertyDescriptor>;
|
|
186
|
-
let descriptorB: ReturnType<typeof getOwnPropertyDescriptor>;
|
|
187
|
-
|
|
188
|
-
// Decrementing `while` showed faster results than either incrementing or
|
|
189
|
-
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
190
|
-
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
191
|
-
// cost of anonymous callbacks.
|
|
192
|
-
while (index-- > 0) {
|
|
193
|
-
property = properties[index]!;
|
|
194
|
-
|
|
195
|
-
if (!isPropertyEqual(a, b, state, property)) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
descriptorA = getOwnPropertyDescriptor(a, property);
|
|
200
|
-
descriptorB = getOwnPropertyDescriptor(b, property);
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
(descriptorA || descriptorB) &&
|
|
204
|
-
(!descriptorA ||
|
|
205
|
-
!descriptorB ||
|
|
206
|
-
descriptorA.configurable !== descriptorB.configurable ||
|
|
207
|
-
descriptorA.enumerable !== descriptorB.enumerable ||
|
|
208
|
-
descriptorA.writable !== descriptorB.writable)
|
|
209
|
-
) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Whether the primitive wrappers passed are equal in value.
|
|
219
|
-
*/
|
|
220
|
-
export function arePrimitiveWrappersEqual(
|
|
221
|
-
a: PrimitiveWrapper,
|
|
222
|
-
b: PrimitiveWrapper,
|
|
223
|
-
): boolean {
|
|
224
|
-
return sameValueZeroEqual(a.valueOf(), b.valueOf());
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Whether the regexps passed are equal in value.
|
|
229
|
-
*/
|
|
230
|
-
export function areRegExpsEqual(a: RegExp, b: RegExp): boolean {
|
|
231
|
-
return a.source === b.source && a.flags === b.flags;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Whether the `Set`s are equal in value.
|
|
236
|
-
*/
|
|
237
|
-
export function areSetsEqual(
|
|
238
|
-
a: Set<any>,
|
|
239
|
-
b: Set<any>,
|
|
240
|
-
state: State<any>,
|
|
241
|
-
): boolean {
|
|
242
|
-
const size = a.size;
|
|
243
|
-
|
|
244
|
-
if (size !== b.size) {
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (!size) {
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const matchedIndices = new Array<true | undefined>(size);
|
|
253
|
-
const aIterable = a.values();
|
|
254
|
-
|
|
255
|
-
let aResult: IteratorResult<any>;
|
|
256
|
-
let bResult: IteratorResult<any>;
|
|
257
|
-
|
|
258
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
259
|
-
while ((aResult = aIterable.next())) {
|
|
260
|
-
if (aResult.done) {
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const bIterable = b.values();
|
|
265
|
-
|
|
266
|
-
let hasMatch = false;
|
|
267
|
-
let matchIndex = 0;
|
|
268
|
-
|
|
269
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
270
|
-
while ((bResult = bIterable.next())) {
|
|
271
|
-
if (bResult.done) {
|
|
272
|
-
break;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (
|
|
276
|
-
!matchedIndices[matchIndex] &&
|
|
277
|
-
state.equals(
|
|
278
|
-
aResult.value,
|
|
279
|
-
bResult.value,
|
|
280
|
-
aResult.value,
|
|
281
|
-
bResult.value,
|
|
282
|
-
a,
|
|
283
|
-
b,
|
|
284
|
-
state,
|
|
285
|
-
)
|
|
286
|
-
) {
|
|
287
|
-
hasMatch = matchedIndices[matchIndex] = true;
|
|
288
|
-
break;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
matchIndex++;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (!hasMatch) {
|
|
295
|
-
return false;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Whether the TypedArray instances are equal in value.
|
|
304
|
-
*/
|
|
305
|
-
export function areTypedArraysEqual(a: TypedArray, b: TypedArray) {
|
|
306
|
-
let index = a.length;
|
|
307
|
-
|
|
308
|
-
if (b.length !== index) {
|
|
309
|
-
return false;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
while (index-- > 0) {
|
|
313
|
-
if (a[index] !== b[index]) {
|
|
314
|
-
return false;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Whether the URL instances are equal in value.
|
|
323
|
-
*/
|
|
324
|
-
export function areUrlsEqual(a: URL, b: URL): boolean {
|
|
325
|
-
return (
|
|
326
|
-
a.hostname === b.hostname &&
|
|
327
|
-
a.pathname === b.pathname &&
|
|
328
|
-
a.protocol === b.protocol &&
|
|
329
|
-
a.port === b.port &&
|
|
330
|
-
a.hash === b.hash &&
|
|
331
|
-
a.username === b.username &&
|
|
332
|
-
a.password === b.password
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function isPropertyEqual(
|
|
337
|
-
a: Dictionary,
|
|
338
|
-
b: Dictionary,
|
|
339
|
-
state: State<any>,
|
|
340
|
-
property: string | symbol,
|
|
341
|
-
) {
|
|
342
|
-
if (
|
|
343
|
-
(property === REACT_OWNER ||
|
|
344
|
-
property === PREACT_OWNER ||
|
|
345
|
-
property === PREACT_VNODE) &&
|
|
346
|
-
(a.$$typeof || b.$$typeof)
|
|
347
|
-
) {
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
return (
|
|
352
|
-
hasOwn(b, property) &&
|
|
353
|
-
state.equals(a[property], b[property], property, property, a, b, state)
|
|
354
|
-
);
|
|
355
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createEqualityComparatorConfig,
|
|
3
|
-
createEqualityComparator,
|
|
4
|
-
createInternalEqualityComparator,
|
|
5
|
-
createIsEqual,
|
|
6
|
-
} from './comparator.js';
|
|
7
|
-
import type { CustomEqualCreatorOptions } from './internalTypes.js';
|
|
8
|
-
import { sameValueZeroEqual } from './utils.js';
|
|
9
|
-
|
|
10
|
-
export { sameValueZeroEqual };
|
|
11
|
-
export type {
|
|
12
|
-
AnyEqualityComparator,
|
|
13
|
-
Cache,
|
|
14
|
-
CircularState,
|
|
15
|
-
ComparatorConfig,
|
|
16
|
-
CreateCustomComparatorConfig,
|
|
17
|
-
CreateState,
|
|
18
|
-
CustomEqualCreatorOptions,
|
|
19
|
-
DefaultState,
|
|
20
|
-
Dictionary,
|
|
21
|
-
EqualityComparator,
|
|
22
|
-
EqualityComparatorCreator,
|
|
23
|
-
InternalEqualityComparator,
|
|
24
|
-
PrimitiveWrapper,
|
|
25
|
-
State,
|
|
26
|
-
TypeEqualityComparator,
|
|
27
|
-
TypedArray,
|
|
28
|
-
} from './internalTypes.js';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Whether the items passed are deeply-equal in value.
|
|
32
|
-
*/
|
|
33
|
-
export const deepEqual = createCustomEqual();
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Whether the items passed are deeply-equal in value based on strict comparison.
|
|
37
|
-
*/
|
|
38
|
-
export const strictDeepEqual = createCustomEqual({ strict: true });
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Whether the items passed are deeply-equal in value, including circular references.
|
|
42
|
-
*/
|
|
43
|
-
export const circularDeepEqual = createCustomEqual({ circular: true });
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Whether the items passed are deeply-equal in value, including circular references,
|
|
47
|
-
* based on strict comparison.
|
|
48
|
-
*/
|
|
49
|
-
export const strictCircularDeepEqual = createCustomEqual({
|
|
50
|
-
circular: true,
|
|
51
|
-
strict: true,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Whether the items passed are shallowly-equal in value.
|
|
56
|
-
*/
|
|
57
|
-
export const shallowEqual = createCustomEqual({
|
|
58
|
-
createInternalComparator: () => sameValueZeroEqual,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Whether the items passed are shallowly-equal in value based on strict comparison
|
|
63
|
-
*/
|
|
64
|
-
export const strictShallowEqual = createCustomEqual({
|
|
65
|
-
strict: true,
|
|
66
|
-
createInternalComparator: () => sameValueZeroEqual,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Whether the items passed are shallowly-equal in value, including circular references.
|
|
71
|
-
*/
|
|
72
|
-
export const circularShallowEqual = createCustomEqual({
|
|
73
|
-
circular: true,
|
|
74
|
-
createInternalComparator: () => sameValueZeroEqual,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Whether the items passed are shallowly-equal in value, including circular references,
|
|
79
|
-
* based on strict comparison.
|
|
80
|
-
*/
|
|
81
|
-
export const strictCircularShallowEqual = createCustomEqual({
|
|
82
|
-
circular: true,
|
|
83
|
-
createInternalComparator: () => sameValueZeroEqual,
|
|
84
|
-
strict: true,
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Create a custom equality comparison method.
|
|
89
|
-
*
|
|
90
|
-
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
|
91
|
-
* where the standard methods are not performant enough, but can also be used to provide
|
|
92
|
-
* support for legacy environments that do not support expected features like
|
|
93
|
-
* `RegExp.prototype.flags` out of the box.
|
|
94
|
-
*/
|
|
95
|
-
export function createCustomEqual<Meta = undefined>(
|
|
96
|
-
options: CustomEqualCreatorOptions<Meta> = {},
|
|
97
|
-
) {
|
|
98
|
-
const {
|
|
99
|
-
circular = false,
|
|
100
|
-
createInternalComparator: createCustomInternalComparator,
|
|
101
|
-
createState,
|
|
102
|
-
strict = false,
|
|
103
|
-
} = options;
|
|
104
|
-
|
|
105
|
-
const config = createEqualityComparatorConfig<Meta>(options);
|
|
106
|
-
const comparator = createEqualityComparator(config);
|
|
107
|
-
const equals = createCustomInternalComparator
|
|
108
|
-
? createCustomInternalComparator(comparator)
|
|
109
|
-
: createInternalEqualityComparator(comparator);
|
|
110
|
-
|
|
111
|
-
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
112
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
AnyEqualityComparator,
|
|
3
|
-
Cache,
|
|
4
|
-
CircularState,
|
|
5
|
-
Dictionary,
|
|
6
|
-
State,
|
|
7
|
-
TypeEqualityComparator,
|
|
8
|
-
} from './internalTypes.js';
|
|
9
|
-
|
|
10
|
-
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
11
|
-
const { hasOwnProperty } = Object.prototype;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Combine two comparators into a single comparators.
|
|
15
|
-
*/
|
|
16
|
-
export function combineComparators<Meta>(
|
|
17
|
-
comparatorA: AnyEqualityComparator<Meta>,
|
|
18
|
-
comparatorB: AnyEqualityComparator<Meta>,
|
|
19
|
-
) {
|
|
20
|
-
return function isEqual<A, B>(a: A, b: B, state: State<Meta>) {
|
|
21
|
-
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
|
27
|
-
* for circular references to be safely included in the comparison without creating
|
|
28
|
-
* stack overflows.
|
|
29
|
-
*/
|
|
30
|
-
export function createIsCircular<
|
|
31
|
-
AreItemsEqual extends TypeEqualityComparator<any, any>,
|
|
32
|
-
>(areItemsEqual: AreItemsEqual): AreItemsEqual {
|
|
33
|
-
return function isCircular(
|
|
34
|
-
a: any,
|
|
35
|
-
b: any,
|
|
36
|
-
state: CircularState<Cache<any, any>>,
|
|
37
|
-
) {
|
|
38
|
-
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
|
39
|
-
return areItemsEqual(a, b, state);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const { cache } = state;
|
|
43
|
-
|
|
44
|
-
const cachedA = cache.get(a);
|
|
45
|
-
const cachedB = cache.get(b);
|
|
46
|
-
|
|
47
|
-
if (cachedA && cachedB) {
|
|
48
|
-
return cachedA === b && cachedB === a;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
cache.set(a, b);
|
|
52
|
-
cache.set(b, a);
|
|
53
|
-
|
|
54
|
-
const result = areItemsEqual(a, b, state);
|
|
55
|
-
|
|
56
|
-
cache.delete(a);
|
|
57
|
-
cache.delete(b);
|
|
58
|
-
|
|
59
|
-
return result;
|
|
60
|
-
} as AreItemsEqual;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Get the `@@toStringTag` of the value, if it exists.
|
|
65
|
-
*/
|
|
66
|
-
export function getShortTag(value: any): string | undefined {
|
|
67
|
-
return value != null ? value[Symbol.toStringTag] : undefined;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Get the properties to strictly examine, which include both own properties that are
|
|
72
|
-
* not enumerable and symbol properties.
|
|
73
|
-
*/
|
|
74
|
-
export function getStrictProperties(
|
|
75
|
-
object: Dictionary,
|
|
76
|
-
): Array<string | symbol> {
|
|
77
|
-
return (getOwnPropertyNames(object) as Array<string | symbol>).concat(
|
|
78
|
-
getOwnPropertySymbols(object),
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Whether the object contains the property passed as an own property.
|
|
84
|
-
*/
|
|
85
|
-
export const hasOwn =
|
|
86
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
87
|
-
Object.hasOwn ||
|
|
88
|
-
((object: Dictionary, property: number | string | symbol) =>
|
|
89
|
-
hasOwnProperty.call(object, property));
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Whether the values passed are strictly equal or both NaN.
|
|
93
|
-
*/
|
|
94
|
-
export function sameValueZeroEqual(a: any, b: any): boolean {
|
|
95
|
-
return a === b || (!a && !b && a !== a && b !== b);
|
|
96
|
-
}
|
|
File without changes
|
|
File without changes
|