fast-equals 6.0.0-rc.0 → 6.0.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/README.md +107 -85
- package/dist/cjs/index.cjs +40 -25
- package/dist/cjs/index.d.cts +46 -40
- package/dist/es/index.d.mts +46 -40
- package/dist/es/index.mjs +39 -26
- package/index.d.ts +46 -40
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
> fast-equals
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
<img src="https://img.shields.io/badge/license-MIT-blue.svg"/>
|
|
6
|
-
|
|
7
|
-
Perform [blazing fast](#benchmarks) equality comparisons (either deep or shallow) on two objects passed, while also
|
|
8
|
-
maintaining a high degree of flexibility for various implementation use-cases. It has no dependencies, and is ~2kB when
|
|
9
|
-
minified and gzipped.
|
|
3
|
+
Perform [blazing fast](#benchmarks) equality comparisons between two objects, while also allowing for flexibility for
|
|
4
|
+
various use-cases. It has no dependencies, and is ~2kB when minified and gzipped.
|
|
10
5
|
|
|
11
6
|
The following types are handled out-of-the-box:
|
|
12
7
|
|
|
@@ -16,36 +11,43 @@ The following types are handled out-of-the-box:
|
|
|
16
11
|
- `Date` objects
|
|
17
12
|
- `RegExp` objects
|
|
18
13
|
- `Map` / `Set` iterables
|
|
19
|
-
- `Promise` objects
|
|
14
|
+
- `Promise` objects and then-ables
|
|
20
15
|
- Primitive wrappers (`new Boolean()` / `new Number()` / `new String()`)
|
|
21
16
|
- Custom class instances, including subclasses of native classes
|
|
22
17
|
|
|
23
|
-
Methods are available for deep, shallow,
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
- [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- [
|
|
48
|
-
- [
|
|
18
|
+
Methods are available for deep, shallow, [`SameValue`](http://ecma-international.org/ecma-262/7.0/#sec-samevalue),
|
|
19
|
+
[`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero), or
|
|
20
|
+
[strict equality](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) comparison. In addition, you
|
|
21
|
+
can opt into support for circular objects, or performing a "strict" comparison with unconventional property definition,
|
|
22
|
+
or both. You can also customize any specific type comparison based on your application's use-cases.
|
|
23
|
+
|
|
24
|
+
By default, npm should resolve the correct build of the package based on your consumption (ESM vs CommonJS). However, if
|
|
25
|
+
you want to force use of a specific build, they can be located here:
|
|
26
|
+
|
|
27
|
+
- ESM => `fast-equals/dist/es/index.mjs`
|
|
28
|
+
- CommonJS => `fast-equals/dist/cjs/index.cjs`
|
|
29
|
+
|
|
30
|
+
If you are having any problems, want to request a new feature, or have any questions,
|
|
31
|
+
[please file an issue](https://github.com/planttheidea/fast-equals/issues).
|
|
32
|
+
|
|
33
|
+
- [Usage](#usage)
|
|
34
|
+
- [Available methods](#available-methods)
|
|
35
|
+
- [deepEqual](#deepequal)
|
|
36
|
+
- [Comparing `Map`s](#comparing-maps)
|
|
37
|
+
- [shallowEqual](#shallowequal)
|
|
38
|
+
- [sameValueEqual](#samevalueequal)
|
|
39
|
+
- [sameValueZeroEqual](#samevaluezeroequal)
|
|
40
|
+
- [strictEqual](#strictequal)
|
|
41
|
+
- [circularDeepEqual](#circulardeepequal)
|
|
42
|
+
- [circularShallowEqual](#circularshallowequal)
|
|
43
|
+
- [strictDeepEqual](#strictdeepequal)
|
|
44
|
+
- [strictShallowEqual](#strictshallowequal)
|
|
45
|
+
- [strictCircularDeepEqual](#strictcirculardeepequal)
|
|
46
|
+
- [strictCircularShallowEqual](#strictcircularshallowequal)
|
|
47
|
+
- [createCustomEqual](#createcustomequal)
|
|
48
|
+
- [getUnsupportedCustomComparator](#getunsupportedcustomcomparator)
|
|
49
|
+
- [Recipes](#recipes)
|
|
50
|
+
- [Benchmarks](#benchmarks)
|
|
49
51
|
|
|
50
52
|
## Usage
|
|
51
53
|
|
|
@@ -55,19 +57,6 @@ import { deepEqual } from 'fast-equals';
|
|
|
55
57
|
console.log(deepEqual({ foo: 'bar' }, { foo: 'bar' })); // true
|
|
56
58
|
```
|
|
57
59
|
|
|
58
|
-
### Specific builds
|
|
59
|
-
|
|
60
|
-
By default, npm should resolve the correct build of the package based on your consumption (ESM vs CommonJS). However, if
|
|
61
|
-
you want to force use of a specific build, they can be located here:
|
|
62
|
-
|
|
63
|
-
- ESM => `fast-equals/dist/esm/index.mjs`
|
|
64
|
-
- CommonJS => `fast-equals/dist/cjs/index.cjs`
|
|
65
|
-
- UMD => `fast-equals/dist/umd/index.js`
|
|
66
|
-
- Minified UMD => `fast-equals/dist/min/index.js`
|
|
67
|
-
|
|
68
|
-
If you are having issues loading a specific build type,
|
|
69
|
-
[please file an issue](https://github.com/planttheidea/fast-equals/issues).
|
|
70
|
-
|
|
71
60
|
## Available methods
|
|
72
61
|
|
|
73
62
|
### deepEqual
|
|
@@ -99,7 +88,7 @@ deepEqual(mapA, mapB);
|
|
|
99
88
|
```
|
|
100
89
|
|
|
101
90
|
To support true deep equality of all contents, `fast-equals` will perform a deep equality comparison for key and value
|
|
102
|
-
|
|
91
|
+
pairs. Therefore, the above would be `true`.
|
|
103
92
|
|
|
104
93
|
### shallowEqual
|
|
105
94
|
|
|
@@ -143,9 +132,59 @@ console.log(sameValueEqual(mainObject.foo, objectB)); // true
|
|
|
143
132
|
console.log(sameValueEqual(mainObject, objectC)); // false
|
|
144
133
|
```
|
|
145
134
|
|
|
146
|
-
**NOTE**: In environments that support
|
|
147
|
-
[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is),
|
|
148
|
-
a re-export of that method.
|
|
135
|
+
_**NOTE**: In environments that support
|
|
136
|
+
[`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is),
|
|
137
|
+
`sameValueEqual` is just a re-export of that method._
|
|
138
|
+
|
|
139
|
+
### sameValueZeroEqual
|
|
140
|
+
|
|
141
|
+
Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) comparison on the two
|
|
142
|
+
objects passed and returns a boolean representing the value equivalency of the objects. In simple terms, this means:
|
|
143
|
+
|
|
144
|
+
- `+0` and `-0` are equal
|
|
145
|
+
- `NaN` is equal to `NaN`
|
|
146
|
+
- All other items are based on referential equality (`a === b`)
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { sameValueEqual } from 'fast-equals';
|
|
150
|
+
|
|
151
|
+
const mainObject = { foo: NaN, bar: 'baz' };
|
|
152
|
+
|
|
153
|
+
const objectA = 'baz';
|
|
154
|
+
const objectB = NaN;
|
|
155
|
+
const objectC = { foo: NaN, bar: 'baz' };
|
|
156
|
+
|
|
157
|
+
console.log(sameValueEqual(mainObject.bar, objectA)); // true
|
|
158
|
+
console.log(sameValueEqual(mainObject.foo, objectB)); // true
|
|
159
|
+
console.log(sameValueEqual(mainObject, objectC)); // false
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### strictEqual
|
|
163
|
+
|
|
164
|
+
Performs a [Strict Equality](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) comparison on the
|
|
165
|
+
two objects passed and returns a boolean representing the referential equality of the objects. In simple terms, this
|
|
166
|
+
means:
|
|
167
|
+
|
|
168
|
+
- `+0` and `-0` are equal
|
|
169
|
+
- `NaN` is not equal to `NaN`
|
|
170
|
+
- All other items are based on referential equality (`a === b`)
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { strictEqual } from 'fast-equals';
|
|
174
|
+
|
|
175
|
+
const mainObject = { foo: NaN, bar: 'baz' };
|
|
176
|
+
|
|
177
|
+
const objectA = 'baz';
|
|
178
|
+
const objectB = NaN;
|
|
179
|
+
const objectC = { foo: NaN, bar: 'baz' };
|
|
180
|
+
|
|
181
|
+
console.log(sameValueEqual(mainObject.bar, objectA)); // true
|
|
182
|
+
console.log(sameValueEqual(mainObject.foo, objectB)); // false
|
|
183
|
+
console.log(sameValueEqual(mainObject, objectC)); // false
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
_**NOTE**: This is mainly a convenience function, such as needing a default functional equality comparator. Naturally,
|
|
187
|
+
it is faster to simply compare `a === b`. :)_
|
|
149
188
|
|
|
150
189
|
### circularDeepEqual
|
|
151
190
|
|
|
@@ -305,21 +344,21 @@ interface Cache<Key extends object, Value> {
|
|
|
305
344
|
}
|
|
306
345
|
|
|
307
346
|
interface ComparatorConfig<Meta> {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
areDataViewsEqual:
|
|
311
|
-
areDatesEqual:
|
|
312
|
-
areErrorsEqual:
|
|
313
|
-
areFunctionsEqual:
|
|
314
|
-
areMapsEqual:
|
|
315
|
-
areNumbersEqual:
|
|
316
|
-
areObjectsEqual:
|
|
317
|
-
arePrimitiveWrappersEqual:
|
|
318
|
-
areRegExpsEqual:
|
|
319
|
-
areSetsEqual:
|
|
320
|
-
areTypedArraysEqual:
|
|
321
|
-
areUrlsEqual:
|
|
322
|
-
getUnsupportedCustomComparator: <Type>(a: Type, b: Type, tag: string) =>
|
|
347
|
+
areArrayBuffersEqual: EqualityComparator<Meta>;
|
|
348
|
+
areArraysEqual: EqualityComparator<Meta>;
|
|
349
|
+
areDataViewsEqual: EqualityComparator<Meta>;
|
|
350
|
+
areDatesEqual: EqualityComparator<Meta>;
|
|
351
|
+
areErrorsEqual: EqualityComparator<Meta>;
|
|
352
|
+
areFunctionsEqual: EqualityComparator<Meta>;
|
|
353
|
+
areMapsEqual: EqualityComparator<Meta>;
|
|
354
|
+
areNumbersEqual: EqualityComparator<Meta>;
|
|
355
|
+
areObjectsEqual: EqualityComparator<Meta>;
|
|
356
|
+
arePrimitiveWrappersEqual: EqualityComparator<Meta>;
|
|
357
|
+
areRegExpsEqual: EqualityComparator<Meta>;
|
|
358
|
+
areSetsEqual: EqualityComparator<Meta>;
|
|
359
|
+
areTypedArraysEqual: EqualityComparator<Meta>;
|
|
360
|
+
areUrlsEqual: EqualityComparator<Meta>;
|
|
361
|
+
getUnsupportedCustomComparator: <Type>(a: Type, b: Type, state: State<Meta>, tag: string) => EqualityComparator<Meta>;
|
|
323
362
|
}
|
|
324
363
|
|
|
325
364
|
function createCustomEqual<Meta>(options: {
|
|
@@ -358,7 +397,7 @@ to the problem you are solving, they can offer guidance of how to structure your
|
|
|
358
397
|
- [Using `meta` in comparison](./recipes//using-meta-in-comparison.md)
|
|
359
398
|
- [Comparing non-standard properties](./recipes/non-standard-properties.md)
|
|
360
399
|
- [Strict property descriptor comparison](./recipes/strict-property-descriptor-check.md)
|
|
361
|
-
- [Legacy environment support for
|
|
400
|
+
- [Legacy environment support for circular equal comparators](./recipes/legacy-circular-equal-support.md)
|
|
362
401
|
- [Custom comparator support](./recipes/special-objects.md)
|
|
363
402
|
|
|
364
403
|
## Benchmarks
|
|
@@ -468,20 +507,3 @@ All of these have the potential of inflating the respective library's numbers in
|
|
|
468
507
|
the closest apples-to-apples comparison I could create of a reasonable sample size. It should be noted that `react`
|
|
469
508
|
elements can be circular objects, however simple elements are not; I kept the `react` comparison very basic to allow it
|
|
470
509
|
to be included.
|
|
471
|
-
|
|
472
|
-
## Development
|
|
473
|
-
|
|
474
|
-
Standard practice, clone the repo and `npm i` to get the dependencies. The following npm scripts are available:
|
|
475
|
-
|
|
476
|
-
- benchmark => run benchmark tests against other equality libraries
|
|
477
|
-
- build => build `main`, `module`, and `browser` distributables with `rollup`
|
|
478
|
-
- clean => run `rimraf` on the `dist` folder
|
|
479
|
-
- dev => start `vite` playground App
|
|
480
|
-
- dist => run `build`
|
|
481
|
-
- lint => run ESLint on all files in `src` folder (also runs on `dev` script)
|
|
482
|
-
- lint:fix => run `lint` script, but with auto-fixer
|
|
483
|
-
- prepublish:compile => run `lint`, `test:coverage`, `transpile:lib`, `transpile:es`, and `dist` scripts
|
|
484
|
-
- start => run `dev`
|
|
485
|
-
- test => run AVA with NODE_ENV=test on all files in `test` folder
|
|
486
|
-
- test:coverage => run same script as `test` with code coverage calculation via `nyc`
|
|
487
|
-
- test:watch => run same script as `test` but keep persistent watcher
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -48,8 +48,18 @@ function getStrictProperties(object) {
|
|
|
48
48
|
const hasOwn =
|
|
49
49
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
50
50
|
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
|
|
51
|
+
|
|
52
|
+
const PREACT_VNODE = '__v';
|
|
53
|
+
const PREACT_OWNER = '__o';
|
|
54
|
+
const REACT_OWNER = '_owner';
|
|
55
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
51
56
|
/**
|
|
52
|
-
* Whether the values passed are
|
|
57
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
58
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
59
|
+
*
|
|
60
|
+
* @note
|
|
61
|
+
* When available in the environment, this is just a re-export of the global
|
|
62
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
53
63
|
*/
|
|
54
64
|
const sameValueEqual =
|
|
55
65
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -57,11 +67,26 @@ Object.is
|
|
|
57
67
|
|| function sameValueEqual(a, b) {
|
|
58
68
|
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
|
59
69
|
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.
|
|
72
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both
|
|
73
|
+
* are either positive or negative zero.
|
|
74
|
+
*/
|
|
75
|
+
function sameValueZeroEqual(a, b) {
|
|
76
|
+
return a === b || (a !== a && b !== b);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether the values passed are equal based on a
|
|
80
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
81
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
82
|
+
*
|
|
83
|
+
* @note
|
|
84
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
85
|
+
* two objects is used.
|
|
86
|
+
*/
|
|
87
|
+
function strictEqual(a, b) {
|
|
88
|
+
return a === b;
|
|
89
|
+
}
|
|
65
90
|
/**
|
|
66
91
|
* Whether the array buffers are equal in value.
|
|
67
92
|
*/
|
|
@@ -102,12 +127,6 @@ function areDatesEqual(a, b) {
|
|
|
102
127
|
function areErrorsEqual(a, b) {
|
|
103
128
|
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
104
129
|
}
|
|
105
|
-
/**
|
|
106
|
-
* Whether the functions passed are equal in value.
|
|
107
|
-
*/
|
|
108
|
-
function areFunctionsEqual(a, b) {
|
|
109
|
-
return a === b;
|
|
110
|
-
}
|
|
111
130
|
/**
|
|
112
131
|
* Whether the `Map`s are equal in value.
|
|
113
132
|
*/
|
|
@@ -157,10 +176,6 @@ function areMapsEqual(a, b, state) {
|
|
|
157
176
|
}
|
|
158
177
|
return true;
|
|
159
178
|
}
|
|
160
|
-
/**
|
|
161
|
-
* Whether the numbers are equal in value.
|
|
162
|
-
*/
|
|
163
|
-
const areNumbersEqual = sameValueEqual;
|
|
164
179
|
/**
|
|
165
180
|
* Whether the objects are equal in value.
|
|
166
181
|
*/
|
|
@@ -355,8 +370,8 @@ function createEqualityComparator(config) {
|
|
|
355
370
|
// Try to fast-path equality checks for other complex object types in the
|
|
356
371
|
// same realm to avoid capturing the string tag. Strict equality is used
|
|
357
372
|
// instead of `instanceof` because it is more performant for the common
|
|
358
|
-
// use-case. If someone is
|
|
359
|
-
// with the string tag comparison.
|
|
373
|
+
// use-case. If someone is creating a subclass from a native class, it will be
|
|
374
|
+
// handled with the string tag comparison.
|
|
360
375
|
if (constructor === Object) {
|
|
361
376
|
return areObjectsEqual(a, b, state);
|
|
362
377
|
}
|
|
@@ -385,14 +400,14 @@ function createEqualityComparator(config) {
|
|
|
385
400
|
if (Array.isArray(a)) {
|
|
386
401
|
return areArraysEqual(a, b, state);
|
|
387
402
|
}
|
|
388
|
-
// Since this is a custom object, capture the string tag to
|
|
403
|
+
// Since this is a custom object, capture the string tag to determining its type.
|
|
389
404
|
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
|
390
405
|
const tag = toString.call(a);
|
|
391
406
|
const supportedComparator = supportedComparatorMap[tag];
|
|
392
407
|
if (supportedComparator) {
|
|
393
408
|
return supportedComparator(a, b, state);
|
|
394
409
|
}
|
|
395
|
-
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, tag);
|
|
410
|
+
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);
|
|
396
411
|
if (unsupportedCustomComparator) {
|
|
397
412
|
return unsupportedCustomComparator(a, b, state);
|
|
398
413
|
}
|
|
@@ -400,9 +415,6 @@ function createEqualityComparator(config) {
|
|
|
400
415
|
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
|
401
416
|
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
|
402
417
|
// comparison that can be made.
|
|
403
|
-
// - For types that can be introspected, but rarely have requirements to be compared
|
|
404
|
-
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
|
405
|
-
// use-cases (may be included in a future release, if requested enough).
|
|
406
418
|
// - For types that can be introspected but do not have an objective definition of what
|
|
407
419
|
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
|
408
420
|
// In all cases, these decisions should be reevaluated based on changes to the language and
|
|
@@ -420,9 +432,9 @@ function createEqualityComparatorConfig({ circular, createCustomConfig, strict,
|
|
|
420
432
|
areDataViewsEqual,
|
|
421
433
|
areDatesEqual: areDatesEqual,
|
|
422
434
|
areErrorsEqual: areErrorsEqual,
|
|
423
|
-
areFunctionsEqual:
|
|
435
|
+
areFunctionsEqual: strictEqual,
|
|
424
436
|
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
425
|
-
areNumbersEqual:
|
|
437
|
+
areNumbersEqual: sameValueEqual,
|
|
426
438
|
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
427
439
|
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
|
428
440
|
areRegExpsEqual: areRegExpsEqual,
|
|
@@ -502,6 +514,7 @@ function createSupportedComparatorMap({ areArrayBuffersEqual, areArraysEqual, ar
|
|
|
502
514
|
'[object Arguments]': areObjectsEqual,
|
|
503
515
|
'[object Array]': areArraysEqual,
|
|
504
516
|
'[object ArrayBuffer]': areArrayBuffersEqual,
|
|
517
|
+
'[object AsyncGeneratorFunction]': areFunctionsEqual,
|
|
505
518
|
'[object BigInt]': areNumbersEqual,
|
|
506
519
|
'[object BigInt64Array]': areTypedArraysEqual,
|
|
507
520
|
'[object BigUint64Array]': areTypedArraysEqual,
|
|
@@ -611,8 +624,10 @@ exports.circularShallowEqual = circularShallowEqual;
|
|
|
611
624
|
exports.createCustomEqual = createCustomEqual;
|
|
612
625
|
exports.deepEqual = deepEqual;
|
|
613
626
|
exports.sameValueEqual = sameValueEqual;
|
|
627
|
+
exports.sameValueZeroEqual = sameValueZeroEqual;
|
|
614
628
|
exports.shallowEqual = shallowEqual;
|
|
615
629
|
exports.strictCircularDeepEqual = strictCircularDeepEqual;
|
|
616
630
|
exports.strictCircularShallowEqual = strictCircularShallowEqual;
|
|
617
631
|
exports.strictDeepEqual = strictDeepEqual;
|
|
632
|
+
exports.strictEqual = strictEqual;
|
|
618
633
|
exports.strictShallowEqual = strictShallowEqual;
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -27,92 +27,75 @@ interface State<Meta> {
|
|
|
27
27
|
*/
|
|
28
28
|
readonly strict: boolean;
|
|
29
29
|
}
|
|
30
|
-
interface CircularState<Meta> extends State<Meta> {
|
|
31
|
-
readonly cache: Cache<any, any>;
|
|
32
|
-
}
|
|
33
|
-
interface DefaultState<Meta> extends State<Meta> {
|
|
34
|
-
readonly cache: undefined;
|
|
35
|
-
}
|
|
36
|
-
interface Dictionary<Value = any> {
|
|
37
|
-
[key: string | symbol]: Value;
|
|
38
|
-
$$typeof?: any;
|
|
39
|
-
}
|
|
40
30
|
interface ComparatorConfig<Meta> {
|
|
41
31
|
/**
|
|
42
32
|
* Whether the array buffers passed are equal in value. In strict mode, this includes
|
|
43
33
|
* additional properties added to the array.
|
|
44
34
|
*/
|
|
45
|
-
areArrayBuffersEqual:
|
|
35
|
+
areArrayBuffersEqual: EqualityComparator<Meta>;
|
|
46
36
|
/**
|
|
47
37
|
* Whether the arrays passed are equal in value. In strict mode, this includes
|
|
48
38
|
* additional properties added to the array.
|
|
49
39
|
*/
|
|
50
|
-
areArraysEqual:
|
|
40
|
+
areArraysEqual: EqualityComparator<Meta>;
|
|
51
41
|
/**
|
|
52
42
|
* Whether the data views passed are equal in value.
|
|
53
43
|
*/
|
|
54
|
-
areDataViewsEqual:
|
|
44
|
+
areDataViewsEqual: EqualityComparator<Meta>;
|
|
55
45
|
/**
|
|
56
46
|
* Whether the dates passed are equal in value.
|
|
57
47
|
*/
|
|
58
|
-
areDatesEqual:
|
|
48
|
+
areDatesEqual: EqualityComparator<Meta>;
|
|
59
49
|
/**
|
|
60
50
|
* Whether the errors passed are equal in value.
|
|
61
51
|
*/
|
|
62
|
-
areErrorsEqual:
|
|
52
|
+
areErrorsEqual: EqualityComparator<Meta>;
|
|
63
53
|
/**
|
|
64
54
|
* Whether the functions passed are equal in value.
|
|
65
55
|
*/
|
|
66
|
-
areFunctionsEqual:
|
|
56
|
+
areFunctionsEqual: EqualityComparator<Meta>;
|
|
67
57
|
/**
|
|
68
58
|
* Whether the maps passed are equal in value. In strict mode, this includes
|
|
69
59
|
* additional properties added to the map.
|
|
70
60
|
*/
|
|
71
|
-
areMapsEqual:
|
|
61
|
+
areMapsEqual: EqualityComparator<Meta>;
|
|
72
62
|
/**
|
|
73
63
|
* Whether the numbers passed are equal in value.
|
|
74
64
|
*/
|
|
75
|
-
areNumbersEqual:
|
|
65
|
+
areNumbersEqual: EqualityComparator<Meta>;
|
|
76
66
|
/**
|
|
77
67
|
* Whether the objects passed are equal in value. In strict mode, this includes
|
|
78
68
|
* non-enumerable properties added to the map, as well as symbol properties.
|
|
79
69
|
*/
|
|
80
|
-
areObjectsEqual:
|
|
70
|
+
areObjectsEqual: EqualityComparator<Meta>;
|
|
81
71
|
/**
|
|
82
72
|
* Whether the primitive wrappers passed are equal in value.
|
|
83
73
|
*/
|
|
84
|
-
arePrimitiveWrappersEqual:
|
|
74
|
+
arePrimitiveWrappersEqual: EqualityComparator<Meta>;
|
|
85
75
|
/**
|
|
86
76
|
* Whether the regexps passed are equal in value.
|
|
87
77
|
*/
|
|
88
|
-
areRegExpsEqual:
|
|
78
|
+
areRegExpsEqual: EqualityComparator<Meta>;
|
|
89
79
|
/**
|
|
90
80
|
* Whether the sets passed are equal in value. In strict mode, this includes
|
|
91
81
|
* additional properties added to the set.
|
|
92
82
|
*/
|
|
93
|
-
areSetsEqual:
|
|
83
|
+
areSetsEqual: EqualityComparator<Meta>;
|
|
94
84
|
/**
|
|
95
85
|
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
|
96
86
|
* additional properties added to the typed array.
|
|
97
87
|
*/
|
|
98
|
-
areTypedArraysEqual:
|
|
88
|
+
areTypedArraysEqual: EqualityComparator<Meta>;
|
|
99
89
|
/**
|
|
100
90
|
* Whether the URLs passed are equal in value.
|
|
101
91
|
*/
|
|
102
|
-
areUrlsEqual:
|
|
92
|
+
areUrlsEqual: EqualityComparator<Meta>;
|
|
103
93
|
/**
|
|
104
94
|
* Get a custom comparator based on the objects passed.
|
|
105
95
|
*/
|
|
106
|
-
getUnsupportedCustomComparator: ((a: any, b: any, tag: string) =>
|
|
96
|
+
getUnsupportedCustomComparator: ((a: any, b: any, state: State<Meta>, tag: string) => EqualityComparator<Meta> | undefined) | undefined;
|
|
107
97
|
}
|
|
108
|
-
type
|
|
109
|
-
type CreateState<Meta> = () => {
|
|
110
|
-
cache?: Cache<any, any> | undefined;
|
|
111
|
-
meta?: Meta;
|
|
112
|
-
};
|
|
113
|
-
type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
|
114
|
-
type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
115
|
-
type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
|
98
|
+
type EqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
116
99
|
type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
|
117
100
|
type PrimitiveWrapper = Boolean | Number | String;
|
|
118
101
|
/**
|
|
@@ -120,7 +103,6 @@ type PrimitiveWrapper = Boolean | Number | String;
|
|
|
120
103
|
* classes.
|
|
121
104
|
*/
|
|
122
105
|
type TypedArray = BigInt64Array | BigUint64Array | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
|
123
|
-
type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
|
124
106
|
interface CustomEqualCreatorOptions<Meta> {
|
|
125
107
|
/**
|
|
126
108
|
* Whether circular references should be supported. It causes the
|
|
@@ -131,9 +113,9 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
131
113
|
/**
|
|
132
114
|
* Create a custom configuration of type-specific equality comparators.
|
|
133
115
|
* This receives the default configuration, which allows either replacement
|
|
134
|
-
* or
|
|
116
|
+
* or a superset of the default methods.
|
|
135
117
|
*/
|
|
136
|
-
createCustomConfig?:
|
|
118
|
+
createCustomConfig?: (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
|
137
119
|
/**
|
|
138
120
|
* Create a custom internal comparator, which is used as an override to the
|
|
139
121
|
* default entry point for nested value equality comparisons. This is often
|
|
@@ -146,7 +128,10 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
146
128
|
* Create a custom `state` object passed between the methods. This allows for
|
|
147
129
|
* custom `cache` and/or `meta` values to be used.
|
|
148
130
|
*/
|
|
149
|
-
createState?:
|
|
131
|
+
createState?: () => {
|
|
132
|
+
cache?: Cache<any, any> | undefined;
|
|
133
|
+
meta?: Meta;
|
|
134
|
+
};
|
|
150
135
|
/**
|
|
151
136
|
* Whether the equality comparison is strict, meaning it matches
|
|
152
137
|
* all properties (including symbols and non-enumerable properties)
|
|
@@ -156,9 +141,30 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
156
141
|
}
|
|
157
142
|
|
|
158
143
|
/**
|
|
159
|
-
* Whether the values passed are
|
|
144
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
145
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
146
|
+
*
|
|
147
|
+
* @note
|
|
148
|
+
* When available in the environment, this is just a re-export of the global
|
|
149
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
160
150
|
*/
|
|
161
151
|
declare const sameValueEqual: (value1: any, value2: any) => boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.
|
|
154
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both
|
|
155
|
+
* are either positive or negative zero.
|
|
156
|
+
*/
|
|
157
|
+
declare function sameValueZeroEqual(a: any, b: any): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the values passed are equal based on a
|
|
160
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
161
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
162
|
+
*
|
|
163
|
+
* @note
|
|
164
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
165
|
+
* two objects is used.
|
|
166
|
+
*/
|
|
167
|
+
declare function strictEqual(a: any, b: any): boolean;
|
|
162
168
|
|
|
163
169
|
/**
|
|
164
170
|
* Whether the items passed are deeply-equal in value.
|
|
@@ -204,5 +210,5 @@ declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
|
|
204
210
|
*/
|
|
205
211
|
declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
|
206
212
|
|
|
207
|
-
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|
|
208
|
-
export type {
|
|
213
|
+
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictEqual, strictShallowEqual };
|
|
214
|
+
export type { Cache, ComparatorConfig, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator, PrimitiveWrapper, State, TypedArray };
|
package/dist/es/index.d.mts
CHANGED
|
@@ -27,92 +27,75 @@ interface State<Meta> {
|
|
|
27
27
|
*/
|
|
28
28
|
readonly strict: boolean;
|
|
29
29
|
}
|
|
30
|
-
interface CircularState<Meta> extends State<Meta> {
|
|
31
|
-
readonly cache: Cache<any, any>;
|
|
32
|
-
}
|
|
33
|
-
interface DefaultState<Meta> extends State<Meta> {
|
|
34
|
-
readonly cache: undefined;
|
|
35
|
-
}
|
|
36
|
-
interface Dictionary<Value = any> {
|
|
37
|
-
[key: string | symbol]: Value;
|
|
38
|
-
$$typeof?: any;
|
|
39
|
-
}
|
|
40
30
|
interface ComparatorConfig<Meta> {
|
|
41
31
|
/**
|
|
42
32
|
* Whether the array buffers passed are equal in value. In strict mode, this includes
|
|
43
33
|
* additional properties added to the array.
|
|
44
34
|
*/
|
|
45
|
-
areArrayBuffersEqual:
|
|
35
|
+
areArrayBuffersEqual: EqualityComparator<Meta>;
|
|
46
36
|
/**
|
|
47
37
|
* Whether the arrays passed are equal in value. In strict mode, this includes
|
|
48
38
|
* additional properties added to the array.
|
|
49
39
|
*/
|
|
50
|
-
areArraysEqual:
|
|
40
|
+
areArraysEqual: EqualityComparator<Meta>;
|
|
51
41
|
/**
|
|
52
42
|
* Whether the data views passed are equal in value.
|
|
53
43
|
*/
|
|
54
|
-
areDataViewsEqual:
|
|
44
|
+
areDataViewsEqual: EqualityComparator<Meta>;
|
|
55
45
|
/**
|
|
56
46
|
* Whether the dates passed are equal in value.
|
|
57
47
|
*/
|
|
58
|
-
areDatesEqual:
|
|
48
|
+
areDatesEqual: EqualityComparator<Meta>;
|
|
59
49
|
/**
|
|
60
50
|
* Whether the errors passed are equal in value.
|
|
61
51
|
*/
|
|
62
|
-
areErrorsEqual:
|
|
52
|
+
areErrorsEqual: EqualityComparator<Meta>;
|
|
63
53
|
/**
|
|
64
54
|
* Whether the functions passed are equal in value.
|
|
65
55
|
*/
|
|
66
|
-
areFunctionsEqual:
|
|
56
|
+
areFunctionsEqual: EqualityComparator<Meta>;
|
|
67
57
|
/**
|
|
68
58
|
* Whether the maps passed are equal in value. In strict mode, this includes
|
|
69
59
|
* additional properties added to the map.
|
|
70
60
|
*/
|
|
71
|
-
areMapsEqual:
|
|
61
|
+
areMapsEqual: EqualityComparator<Meta>;
|
|
72
62
|
/**
|
|
73
63
|
* Whether the numbers passed are equal in value.
|
|
74
64
|
*/
|
|
75
|
-
areNumbersEqual:
|
|
65
|
+
areNumbersEqual: EqualityComparator<Meta>;
|
|
76
66
|
/**
|
|
77
67
|
* Whether the objects passed are equal in value. In strict mode, this includes
|
|
78
68
|
* non-enumerable properties added to the map, as well as symbol properties.
|
|
79
69
|
*/
|
|
80
|
-
areObjectsEqual:
|
|
70
|
+
areObjectsEqual: EqualityComparator<Meta>;
|
|
81
71
|
/**
|
|
82
72
|
* Whether the primitive wrappers passed are equal in value.
|
|
83
73
|
*/
|
|
84
|
-
arePrimitiveWrappersEqual:
|
|
74
|
+
arePrimitiveWrappersEqual: EqualityComparator<Meta>;
|
|
85
75
|
/**
|
|
86
76
|
* Whether the regexps passed are equal in value.
|
|
87
77
|
*/
|
|
88
|
-
areRegExpsEqual:
|
|
78
|
+
areRegExpsEqual: EqualityComparator<Meta>;
|
|
89
79
|
/**
|
|
90
80
|
* Whether the sets passed are equal in value. In strict mode, this includes
|
|
91
81
|
* additional properties added to the set.
|
|
92
82
|
*/
|
|
93
|
-
areSetsEqual:
|
|
83
|
+
areSetsEqual: EqualityComparator<Meta>;
|
|
94
84
|
/**
|
|
95
85
|
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
|
96
86
|
* additional properties added to the typed array.
|
|
97
87
|
*/
|
|
98
|
-
areTypedArraysEqual:
|
|
88
|
+
areTypedArraysEqual: EqualityComparator<Meta>;
|
|
99
89
|
/**
|
|
100
90
|
* Whether the URLs passed are equal in value.
|
|
101
91
|
*/
|
|
102
|
-
areUrlsEqual:
|
|
92
|
+
areUrlsEqual: EqualityComparator<Meta>;
|
|
103
93
|
/**
|
|
104
94
|
* Get a custom comparator based on the objects passed.
|
|
105
95
|
*/
|
|
106
|
-
getUnsupportedCustomComparator: ((a: any, b: any, tag: string) =>
|
|
96
|
+
getUnsupportedCustomComparator: ((a: any, b: any, state: State<Meta>, tag: string) => EqualityComparator<Meta> | undefined) | undefined;
|
|
107
97
|
}
|
|
108
|
-
type
|
|
109
|
-
type CreateState<Meta> = () => {
|
|
110
|
-
cache?: Cache<any, any> | undefined;
|
|
111
|
-
meta?: Meta;
|
|
112
|
-
};
|
|
113
|
-
type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
|
114
|
-
type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
115
|
-
type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
|
98
|
+
type EqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
116
99
|
type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
|
117
100
|
type PrimitiveWrapper = Boolean | Number | String;
|
|
118
101
|
/**
|
|
@@ -120,7 +103,6 @@ type PrimitiveWrapper = Boolean | Number | String;
|
|
|
120
103
|
* classes.
|
|
121
104
|
*/
|
|
122
105
|
type TypedArray = BigInt64Array | BigUint64Array | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
|
123
|
-
type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
|
124
106
|
interface CustomEqualCreatorOptions<Meta> {
|
|
125
107
|
/**
|
|
126
108
|
* Whether circular references should be supported. It causes the
|
|
@@ -131,9 +113,9 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
131
113
|
/**
|
|
132
114
|
* Create a custom configuration of type-specific equality comparators.
|
|
133
115
|
* This receives the default configuration, which allows either replacement
|
|
134
|
-
* or
|
|
116
|
+
* or a superset of the default methods.
|
|
135
117
|
*/
|
|
136
|
-
createCustomConfig?:
|
|
118
|
+
createCustomConfig?: (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
|
137
119
|
/**
|
|
138
120
|
* Create a custom internal comparator, which is used as an override to the
|
|
139
121
|
* default entry point for nested value equality comparisons. This is often
|
|
@@ -146,7 +128,10 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
146
128
|
* Create a custom `state` object passed between the methods. This allows for
|
|
147
129
|
* custom `cache` and/or `meta` values to be used.
|
|
148
130
|
*/
|
|
149
|
-
createState?:
|
|
131
|
+
createState?: () => {
|
|
132
|
+
cache?: Cache<any, any> | undefined;
|
|
133
|
+
meta?: Meta;
|
|
134
|
+
};
|
|
150
135
|
/**
|
|
151
136
|
* Whether the equality comparison is strict, meaning it matches
|
|
152
137
|
* all properties (including symbols and non-enumerable properties)
|
|
@@ -156,9 +141,30 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
156
141
|
}
|
|
157
142
|
|
|
158
143
|
/**
|
|
159
|
-
* Whether the values passed are
|
|
144
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
145
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
146
|
+
*
|
|
147
|
+
* @note
|
|
148
|
+
* When available in the environment, this is just a re-export of the global
|
|
149
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
160
150
|
*/
|
|
161
151
|
declare const sameValueEqual: (value1: any, value2: any) => boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.
|
|
154
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both
|
|
155
|
+
* are either positive or negative zero.
|
|
156
|
+
*/
|
|
157
|
+
declare function sameValueZeroEqual(a: any, b: any): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the values passed are equal based on a
|
|
160
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
161
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
162
|
+
*
|
|
163
|
+
* @note
|
|
164
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
165
|
+
* two objects is used.
|
|
166
|
+
*/
|
|
167
|
+
declare function strictEqual(a: any, b: any): boolean;
|
|
162
168
|
|
|
163
169
|
/**
|
|
164
170
|
* Whether the items passed are deeply-equal in value.
|
|
@@ -204,5 +210,5 @@ declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
|
|
204
210
|
*/
|
|
205
211
|
declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
|
206
212
|
|
|
207
|
-
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|
|
208
|
-
export type {
|
|
213
|
+
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictEqual, strictShallowEqual };
|
|
214
|
+
export type { Cache, ComparatorConfig, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator, PrimitiveWrapper, State, TypedArray };
|
package/dist/es/index.mjs
CHANGED
|
@@ -46,8 +46,18 @@ function getStrictProperties(object) {
|
|
|
46
46
|
const hasOwn =
|
|
47
47
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
48
48
|
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
|
|
49
|
+
|
|
50
|
+
const PREACT_VNODE = '__v';
|
|
51
|
+
const PREACT_OWNER = '__o';
|
|
52
|
+
const REACT_OWNER = '_owner';
|
|
53
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
49
54
|
/**
|
|
50
|
-
* Whether the values passed are
|
|
55
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
56
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
57
|
+
*
|
|
58
|
+
* @note
|
|
59
|
+
* When available in the environment, this is just a re-export of the global
|
|
60
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
51
61
|
*/
|
|
52
62
|
const sameValueEqual =
|
|
53
63
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -55,11 +65,26 @@ Object.is
|
|
|
55
65
|
|| function sameValueEqual(a, b) {
|
|
56
66
|
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
|
57
67
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.
|
|
70
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both
|
|
71
|
+
* are either positive or negative zero.
|
|
72
|
+
*/
|
|
73
|
+
function sameValueZeroEqual(a, b) {
|
|
74
|
+
return a === b || (a !== a && b !== b);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Whether the values passed are equal based on a
|
|
78
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
79
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
80
|
+
*
|
|
81
|
+
* @note
|
|
82
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
83
|
+
* two objects is used.
|
|
84
|
+
*/
|
|
85
|
+
function strictEqual(a, b) {
|
|
86
|
+
return a === b;
|
|
87
|
+
}
|
|
63
88
|
/**
|
|
64
89
|
* Whether the array buffers are equal in value.
|
|
65
90
|
*/
|
|
@@ -100,12 +125,6 @@ function areDatesEqual(a, b) {
|
|
|
100
125
|
function areErrorsEqual(a, b) {
|
|
101
126
|
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
102
127
|
}
|
|
103
|
-
/**
|
|
104
|
-
* Whether the functions passed are equal in value.
|
|
105
|
-
*/
|
|
106
|
-
function areFunctionsEqual(a, b) {
|
|
107
|
-
return a === b;
|
|
108
|
-
}
|
|
109
128
|
/**
|
|
110
129
|
* Whether the `Map`s are equal in value.
|
|
111
130
|
*/
|
|
@@ -155,10 +174,6 @@ function areMapsEqual(a, b, state) {
|
|
|
155
174
|
}
|
|
156
175
|
return true;
|
|
157
176
|
}
|
|
158
|
-
/**
|
|
159
|
-
* Whether the numbers are equal in value.
|
|
160
|
-
*/
|
|
161
|
-
const areNumbersEqual = sameValueEqual;
|
|
162
177
|
/**
|
|
163
178
|
* Whether the objects are equal in value.
|
|
164
179
|
*/
|
|
@@ -353,8 +368,8 @@ function createEqualityComparator(config) {
|
|
|
353
368
|
// Try to fast-path equality checks for other complex object types in the
|
|
354
369
|
// same realm to avoid capturing the string tag. Strict equality is used
|
|
355
370
|
// instead of `instanceof` because it is more performant for the common
|
|
356
|
-
// use-case. If someone is
|
|
357
|
-
// with the string tag comparison.
|
|
371
|
+
// use-case. If someone is creating a subclass from a native class, it will be
|
|
372
|
+
// handled with the string tag comparison.
|
|
358
373
|
if (constructor === Object) {
|
|
359
374
|
return areObjectsEqual(a, b, state);
|
|
360
375
|
}
|
|
@@ -383,14 +398,14 @@ function createEqualityComparator(config) {
|
|
|
383
398
|
if (Array.isArray(a)) {
|
|
384
399
|
return areArraysEqual(a, b, state);
|
|
385
400
|
}
|
|
386
|
-
// Since this is a custom object, capture the string tag to
|
|
401
|
+
// Since this is a custom object, capture the string tag to determining its type.
|
|
387
402
|
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
|
388
403
|
const tag = toString.call(a);
|
|
389
404
|
const supportedComparator = supportedComparatorMap[tag];
|
|
390
405
|
if (supportedComparator) {
|
|
391
406
|
return supportedComparator(a, b, state);
|
|
392
407
|
}
|
|
393
|
-
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, tag);
|
|
408
|
+
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);
|
|
394
409
|
if (unsupportedCustomComparator) {
|
|
395
410
|
return unsupportedCustomComparator(a, b, state);
|
|
396
411
|
}
|
|
@@ -398,9 +413,6 @@ function createEqualityComparator(config) {
|
|
|
398
413
|
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
|
399
414
|
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
|
400
415
|
// comparison that can be made.
|
|
401
|
-
// - For types that can be introspected, but rarely have requirements to be compared
|
|
402
|
-
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
|
403
|
-
// use-cases (may be included in a future release, if requested enough).
|
|
404
416
|
// - For types that can be introspected but do not have an objective definition of what
|
|
405
417
|
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
|
406
418
|
// In all cases, these decisions should be reevaluated based on changes to the language and
|
|
@@ -418,9 +430,9 @@ function createEqualityComparatorConfig({ circular, createCustomConfig, strict,
|
|
|
418
430
|
areDataViewsEqual,
|
|
419
431
|
areDatesEqual: areDatesEqual,
|
|
420
432
|
areErrorsEqual: areErrorsEqual,
|
|
421
|
-
areFunctionsEqual:
|
|
433
|
+
areFunctionsEqual: strictEqual,
|
|
422
434
|
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
423
|
-
areNumbersEqual:
|
|
435
|
+
areNumbersEqual: sameValueEqual,
|
|
424
436
|
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
425
437
|
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
|
426
438
|
areRegExpsEqual: areRegExpsEqual,
|
|
@@ -500,6 +512,7 @@ function createSupportedComparatorMap({ areArrayBuffersEqual, areArraysEqual, ar
|
|
|
500
512
|
'[object Arguments]': areObjectsEqual,
|
|
501
513
|
'[object Array]': areArraysEqual,
|
|
502
514
|
'[object ArrayBuffer]': areArrayBuffersEqual,
|
|
515
|
+
'[object AsyncGeneratorFunction]': areFunctionsEqual,
|
|
503
516
|
'[object BigInt]': areNumbersEqual,
|
|
504
517
|
'[object BigInt64Array]': areTypedArraysEqual,
|
|
505
518
|
'[object BigUint64Array]': areTypedArraysEqual,
|
|
@@ -604,4 +617,4 @@ function createCustomEqual(options = {}) {
|
|
|
604
617
|
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
605
618
|
}
|
|
606
619
|
|
|
607
|
-
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|
|
620
|
+
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictEqual, strictShallowEqual };
|
package/index.d.ts
CHANGED
|
@@ -27,92 +27,75 @@ interface State<Meta> {
|
|
|
27
27
|
*/
|
|
28
28
|
readonly strict: boolean;
|
|
29
29
|
}
|
|
30
|
-
interface CircularState<Meta> extends State<Meta> {
|
|
31
|
-
readonly cache: Cache<any, any>;
|
|
32
|
-
}
|
|
33
|
-
interface DefaultState<Meta> extends State<Meta> {
|
|
34
|
-
readonly cache: undefined;
|
|
35
|
-
}
|
|
36
|
-
interface Dictionary<Value = any> {
|
|
37
|
-
[key: string | symbol]: Value;
|
|
38
|
-
$$typeof?: any;
|
|
39
|
-
}
|
|
40
30
|
interface ComparatorConfig<Meta> {
|
|
41
31
|
/**
|
|
42
32
|
* Whether the array buffers passed are equal in value. In strict mode, this includes
|
|
43
33
|
* additional properties added to the array.
|
|
44
34
|
*/
|
|
45
|
-
areArrayBuffersEqual:
|
|
35
|
+
areArrayBuffersEqual: EqualityComparator<Meta>;
|
|
46
36
|
/**
|
|
47
37
|
* Whether the arrays passed are equal in value. In strict mode, this includes
|
|
48
38
|
* additional properties added to the array.
|
|
49
39
|
*/
|
|
50
|
-
areArraysEqual:
|
|
40
|
+
areArraysEqual: EqualityComparator<Meta>;
|
|
51
41
|
/**
|
|
52
42
|
* Whether the data views passed are equal in value.
|
|
53
43
|
*/
|
|
54
|
-
areDataViewsEqual:
|
|
44
|
+
areDataViewsEqual: EqualityComparator<Meta>;
|
|
55
45
|
/**
|
|
56
46
|
* Whether the dates passed are equal in value.
|
|
57
47
|
*/
|
|
58
|
-
areDatesEqual:
|
|
48
|
+
areDatesEqual: EqualityComparator<Meta>;
|
|
59
49
|
/**
|
|
60
50
|
* Whether the errors passed are equal in value.
|
|
61
51
|
*/
|
|
62
|
-
areErrorsEqual:
|
|
52
|
+
areErrorsEqual: EqualityComparator<Meta>;
|
|
63
53
|
/**
|
|
64
54
|
* Whether the functions passed are equal in value.
|
|
65
55
|
*/
|
|
66
|
-
areFunctionsEqual:
|
|
56
|
+
areFunctionsEqual: EqualityComparator<Meta>;
|
|
67
57
|
/**
|
|
68
58
|
* Whether the maps passed are equal in value. In strict mode, this includes
|
|
69
59
|
* additional properties added to the map.
|
|
70
60
|
*/
|
|
71
|
-
areMapsEqual:
|
|
61
|
+
areMapsEqual: EqualityComparator<Meta>;
|
|
72
62
|
/**
|
|
73
63
|
* Whether the numbers passed are equal in value.
|
|
74
64
|
*/
|
|
75
|
-
areNumbersEqual:
|
|
65
|
+
areNumbersEqual: EqualityComparator<Meta>;
|
|
76
66
|
/**
|
|
77
67
|
* Whether the objects passed are equal in value. In strict mode, this includes
|
|
78
68
|
* non-enumerable properties added to the map, as well as symbol properties.
|
|
79
69
|
*/
|
|
80
|
-
areObjectsEqual:
|
|
70
|
+
areObjectsEqual: EqualityComparator<Meta>;
|
|
81
71
|
/**
|
|
82
72
|
* Whether the primitive wrappers passed are equal in value.
|
|
83
73
|
*/
|
|
84
|
-
arePrimitiveWrappersEqual:
|
|
74
|
+
arePrimitiveWrappersEqual: EqualityComparator<Meta>;
|
|
85
75
|
/**
|
|
86
76
|
* Whether the regexps passed are equal in value.
|
|
87
77
|
*/
|
|
88
|
-
areRegExpsEqual:
|
|
78
|
+
areRegExpsEqual: EqualityComparator<Meta>;
|
|
89
79
|
/**
|
|
90
80
|
* Whether the sets passed are equal in value. In strict mode, this includes
|
|
91
81
|
* additional properties added to the set.
|
|
92
82
|
*/
|
|
93
|
-
areSetsEqual:
|
|
83
|
+
areSetsEqual: EqualityComparator<Meta>;
|
|
94
84
|
/**
|
|
95
85
|
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
|
96
86
|
* additional properties added to the typed array.
|
|
97
87
|
*/
|
|
98
|
-
areTypedArraysEqual:
|
|
88
|
+
areTypedArraysEqual: EqualityComparator<Meta>;
|
|
99
89
|
/**
|
|
100
90
|
* Whether the URLs passed are equal in value.
|
|
101
91
|
*/
|
|
102
|
-
areUrlsEqual:
|
|
92
|
+
areUrlsEqual: EqualityComparator<Meta>;
|
|
103
93
|
/**
|
|
104
94
|
* Get a custom comparator based on the objects passed.
|
|
105
95
|
*/
|
|
106
|
-
getUnsupportedCustomComparator: ((a: any, b: any, tag: string) =>
|
|
96
|
+
getUnsupportedCustomComparator: ((a: any, b: any, state: State<Meta>, tag: string) => EqualityComparator<Meta> | undefined) | undefined;
|
|
107
97
|
}
|
|
108
|
-
type
|
|
109
|
-
type CreateState<Meta> = () => {
|
|
110
|
-
cache?: Cache<any, any> | undefined;
|
|
111
|
-
meta?: Meta;
|
|
112
|
-
};
|
|
113
|
-
type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
|
114
|
-
type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
115
|
-
type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
|
98
|
+
type EqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
|
116
99
|
type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
|
117
100
|
type PrimitiveWrapper = Boolean | Number | String;
|
|
118
101
|
/**
|
|
@@ -120,7 +103,6 @@ type PrimitiveWrapper = Boolean | Number | String;
|
|
|
120
103
|
* classes.
|
|
121
104
|
*/
|
|
122
105
|
type TypedArray = BigInt64Array | BigUint64Array | Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
|
123
|
-
type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
|
124
106
|
interface CustomEqualCreatorOptions<Meta> {
|
|
125
107
|
/**
|
|
126
108
|
* Whether circular references should be supported. It causes the
|
|
@@ -131,9 +113,9 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
131
113
|
/**
|
|
132
114
|
* Create a custom configuration of type-specific equality comparators.
|
|
133
115
|
* This receives the default configuration, which allows either replacement
|
|
134
|
-
* or
|
|
116
|
+
* or a superset of the default methods.
|
|
135
117
|
*/
|
|
136
|
-
createCustomConfig?:
|
|
118
|
+
createCustomConfig?: (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
|
137
119
|
/**
|
|
138
120
|
* Create a custom internal comparator, which is used as an override to the
|
|
139
121
|
* default entry point for nested value equality comparisons. This is often
|
|
@@ -146,7 +128,10 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
146
128
|
* Create a custom `state` object passed between the methods. This allows for
|
|
147
129
|
* custom `cache` and/or `meta` values to be used.
|
|
148
130
|
*/
|
|
149
|
-
createState?:
|
|
131
|
+
createState?: () => {
|
|
132
|
+
cache?: Cache<any, any> | undefined;
|
|
133
|
+
meta?: Meta;
|
|
134
|
+
};
|
|
150
135
|
/**
|
|
151
136
|
* Whether the equality comparison is strict, meaning it matches
|
|
152
137
|
* all properties (including symbols and non-enumerable properties)
|
|
@@ -156,9 +141,30 @@ interface CustomEqualCreatorOptions<Meta> {
|
|
|
156
141
|
}
|
|
157
142
|
|
|
158
143
|
/**
|
|
159
|
-
* Whether the values passed are
|
|
144
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
145
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
146
|
+
*
|
|
147
|
+
* @note
|
|
148
|
+
* When available in the environment, this is just a re-export of the global
|
|
149
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
160
150
|
*/
|
|
161
151
|
declare const sameValueEqual: (value1: any, value2: any) => boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevaluezero) basis.
|
|
154
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`), both are `NaN`, or both
|
|
155
|
+
* are either positive or negative zero.
|
|
156
|
+
*/
|
|
157
|
+
declare function sameValueZeroEqual(a: any, b: any): boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Whether the values passed are equal based on a
|
|
160
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
161
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
162
|
+
*
|
|
163
|
+
* @note
|
|
164
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
165
|
+
* two objects is used.
|
|
166
|
+
*/
|
|
167
|
+
declare function strictEqual(a: any, b: any): boolean;
|
|
162
168
|
|
|
163
169
|
/**
|
|
164
170
|
* Whether the items passed are deeply-equal in value.
|
|
@@ -204,5 +210,5 @@ declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
|
|
204
210
|
*/
|
|
205
211
|
declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
|
206
212
|
|
|
207
|
-
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|
|
208
|
-
export type {
|
|
213
|
+
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictEqual, strictShallowEqual };
|
|
214
|
+
export type { Cache, ComparatorConfig, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator, PrimitiveWrapper, State, TypedArray };
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"bugs": {
|
|
8
8
|
"url": "https://github.com/planttheidea/fast-equals/issues"
|
|
9
9
|
},
|
|
10
|
-
"description": "A blazing
|
|
10
|
+
"description": "A blazing-fast equality comparison utility for a variety of use-cases",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@planttheidea/build-tools": "^2.0.0",
|
|
13
13
|
"@types/lodash": "^4.17.21",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@types/react-dom": "^19.2.3",
|
|
18
18
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
19
19
|
"@typescript-eslint/parser": "^8.50.0",
|
|
20
|
-
"@vitest/coverage-v8": "^4.0.
|
|
20
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
21
21
|
"cli-table3": "^0.6.5",
|
|
22
22
|
"decircularize": "^1.0.0",
|
|
23
23
|
"deep-eql": "^5.0.2",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"typescript-eslint": "^8.50.0",
|
|
43
43
|
"underscore": "^1.13.7",
|
|
44
44
|
"vite": "^7.3.0",
|
|
45
|
-
"vitest": "^4.0.
|
|
45
|
+
"vitest": "^4.0.16"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=6.0.0"
|
|
@@ -109,5 +109,5 @@
|
|
|
109
109
|
"sideEffects": false,
|
|
110
110
|
"type": "module",
|
|
111
111
|
"types": "./index.d.ts",
|
|
112
|
-
"version": "6.0.0
|
|
112
|
+
"version": "6.0.0"
|
|
113
113
|
}
|