first commit
This commit is contained in:
360
node_modules/fast-equals/CHANGELOG.md
generated
vendored
Normal file
360
node_modules/fast-equals/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
# fast-equals CHANGELOG
|
||||
|
||||
## 5.3.2
|
||||
|
||||
- [#154](https://github.com/planttheidea/fast-equals/pull/154) - Use include with `"files"` instead of exclude with `.npmignore` (Thanks [@43081j](https://github.com/43081j))
|
||||
- [#155](https://github.com/planttheidea/fast-equals/pull/155) - Upgrade build dependencies to resolve security vulnerabilities
|
||||
|
||||
## 5.3.1
|
||||
|
||||
- [#153](https://github.com/planttheidea/fast-equals/pull/153) - Avoid publishing `.yarn` folder
|
||||
|
||||
## 5.3.0
|
||||
|
||||
- [#150](https://github.com/planttheidea/fast-equals/pull/150/files) - Add support for `unknownTagComparators` in custom configuration (thanks to @mrcljx for the idea)
|
||||
|
||||
## 5.2.2
|
||||
|
||||
- [#139](https://github.com/planttheidea/fast-equals/pull/139/files) - Add file extensions to type definition files to allow it to work in projects with `NodeNext` module resolution
|
||||
|
||||
## 5.2.1
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- [#138](https://github.com/planttheidea/fast-equals/pull/138) - Actually fix reference to `src` code in `index.d.ts` by flattening types in file
|
||||
|
||||
## 5.2.0
|
||||
|
||||
### Enhancements
|
||||
|
||||
- Support Preact objects in equality comparison
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- [#137](https://github.com/planttheidea/fast-equals/pull/137) - Fix circular React references in object comparisons
|
||||
|
||||
## 5.1.3
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [#136](https://github.com/planttheidea/fast-equals/pull/136) - More than double speed of iterables (`Map` / `Set`) equality comparisons
|
||||
|
||||
### Maintenance
|
||||
|
||||
- [#135](https://github.com/planttheidea/fast-equals/pull/135) - Include `dequal` and `dequal/lite` in benchmark comparisons
|
||||
|
||||
## 5.1.2
|
||||
|
||||
### Maintenance
|
||||
|
||||
Re-release of `5.1.0` with correct pre-release setup.
|
||||
|
||||
## 5.1.1
|
||||
|
||||
**DO NOT USE**
|
||||
|
||||
This was an accidental pre-release when cleaning up release setup.
|
||||
|
||||
## 5.1.0
|
||||
|
||||
### Enhancements
|
||||
|
||||
- [#127](https://github.com/planttheidea/fast-equals/pull/127) - Add support for custom `Function` instance comparisons (resolves [#118](https://github.com/planttheidea/fast-equals/issues/118))
|
||||
- [#128](https://github.com/planttheidea/fast-equals/pull/128) - Add support for `URL` instance comparisons (resolves [#121](https://github.com/planttheidea/fast-equals/issues/121))
|
||||
- [#129](https://github.com/planttheidea/fast-equals/pull/129) - Add support for `Error` instance comparisons (resolves [#123](https://github.com/planttheidea/fast-equals/issues/123))
|
||||
- [#130](https://github.com/planttheidea/fast-equals/pull/130) - Add support for custom `Number` instance comparisons (resolves [#112](https://github.com/planttheidea/fast-equals/issues/112))
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- [#132](https://github.com/planttheidea/fast-equals/pull/126) - Fix `assert.deepEqual` check in benchmark (resolves [#125](https://github.com/planttheidea/fast-equals/issues/125))
|
||||
- [#126](https://github.com/planttheidea/fast-equals/pull/132) - Export explicit types via `export type` (attempts to resolve [#114](https://github.com/planttheidea/fast-equals/issues/114))
|
||||
|
||||
## 5.0.1
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- Fix reference to `metaOverride` in typings and documentation (holdover from temporary API in v5 beta)
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
#### `constructor` equality now required
|
||||
|
||||
To align with other implementations common in the community, but also to be more functionally correct, the two objects being compared now must have equal `constructor`s.
|
||||
|
||||
#### `Map` / `Set` comparisons no longer support IE11
|
||||
|
||||
In previous verisons, `.forEach()` was used to ensure that support for `Symbol` was not required, as IE11 did not have `Symbol` and therefore both `Map` and `Set` did not have iterator-based methods such as `.values()` or `.entries()`. Since IE11 is no longer a supported browser, and support for those methods is present in all browsers and Node for quite a while, the comparison has moved to use these methods. This results in a ~20% performance increase.
|
||||
|
||||
#### `createCustomEqual` contract has changed
|
||||
|
||||
To better facilitate strict comparisons, but also to allow for `meta` use separate from caching, the contract for `createCustomEqual` has changed. See the [README documentation](./README.md#createcustomequal) for more details, but froma high-level:
|
||||
|
||||
- `meta` is no longer passed through to equality comparators, but rather a general `state` object which contains `meta`
|
||||
- `cache` now also lives on the `state` object, which allows for use of the `meta` property separate from but in parallel with the circular cache
|
||||
- `equals` is now on `state`, which prevents the need to pass through the separate `isEqual` method for the equality comparator
|
||||
|
||||
#### `createCustomCircularEqual` has been removed
|
||||
|
||||
You can create a custom circular equality comparator through `createCustomEqual` now by providing `circular: true` to the options.
|
||||
|
||||
#### Custom `meta` values are no longer passed at callsite
|
||||
|
||||
To use `meta` properties for comparisons, they must be returned in a `createState` method.
|
||||
|
||||
#### Deep links have changed
|
||||
|
||||
If you were deep-linking into a specific asset type (ESM / CJS / UMD), they have changed location.
|
||||
|
||||
**NOTE**: You may no longer need to deep-link, as [the build resolution has improved](#better-build-system-resolution).
|
||||
|
||||
### Enhancements
|
||||
|
||||
#### New "strict" comparators available
|
||||
|
||||
The following new comparators are available:
|
||||
|
||||
- `strictDeepEqual`
|
||||
- `strictShallowEqual`
|
||||
- `strictCircularDeepEqual`
|
||||
- `strictCircularShallowEqual`
|
||||
|
||||
This will perform the same comparisons as their non-strict counterparts, but will verify additional properties (non-enumerable properties on objects, keyed objects on `Array` / `Map` / `Set`) and that the descriptors for the properties align.
|
||||
|
||||
#### `TypedArray` support
|
||||
|
||||
Support for comparing all typed array values is now supported, and you can provide a custom comparator via the new `areTypedArraysEqual` option in the `createCustomEqual` configuration.
|
||||
|
||||
#### Better build system resolution
|
||||
|
||||
The library now leverages the `exports` property in the `package.json` to provide builds specific to your method of consumption (ESM / CommonJS / UMD). There is still a minified UMD version available if you want to use it instead.
|
||||
|
||||
#### `arePrimitiveWrappersEqual` option added to `createCustomEqual` configuration
|
||||
|
||||
If you want a custom comparator for primitive wrappers (`new Boolean()` / `new Number()` / `new String()`) it is now available.
|
||||
|
||||
## 4.0.3
|
||||
|
||||
- Remove unnecessary second strict equality check for objects in edge-case scenarios
|
||||
|
||||
## 4.0.2
|
||||
|
||||
- [#85](https://github.com/planttheidea/fast-equals/issues/85) - `createCustomCircularEqual` typing is incorrect
|
||||
|
||||
## 4.0.1
|
||||
|
||||
- [#81](https://github.com/planttheidea/fast-equals/issues/81) - Fix typing issues related to importing in `index.d.ts` file
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
#### Certain ES2015 features are now required
|
||||
|
||||
In previous versions, there were automatic fallbacks for certain ES2015 features if they did not exist:
|
||||
|
||||
- [`RegExp.prototype.flags`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags)
|
||||
- [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)
|
||||
|
||||
Due to the omnipresence of support in both browser and NodeJS, these have been deprecated. There is still an option if you require support for these legacy environments, however; see [`createCustomEqual`](./README.md#createcustomequal) and [`createCustomCircularEqual`](./README.md#createcustomcircularequal) for more details.
|
||||
|
||||
#### `createCustomEqual` contract has changed
|
||||
|
||||
To allow more flexibility and customizability for a variety of edge cases, `createCustomEqual` now allows override of specific type value comparisons in addition to the general comparator it did prior. See [the documentation](./README.md#createcustomequal) for more details.
|
||||
|
||||
### Enhancements
|
||||
|
||||
#### `createCustomCircularEqual` added
|
||||
|
||||
Like `createCustomEqual`, it will create a custom equality comparator, with the exception that it will handle circular references. See [the documentation](./README.md#createcustomcircularequal) for more details.
|
||||
|
||||
#### Cross-realm comparisons are now supported
|
||||
|
||||
Prior to `4.x.x.`, `instanceof` was used internally for checking of object classes, which only worked when comparing objects from the same [Realm](https://262.ecma-international.org/6.0/#sec-code-realms). This has changed to instead use an object's [StringTag](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag), which is not realm-specific.
|
||||
|
||||
#### TypeScript typings improved
|
||||
|
||||
For better typing in edge-case scenarios like custom comparators with `meta` values, typings have been refactored for accuracy and better narrow flow-through.
|
||||
|
||||
## 3.0.3
|
||||
|
||||
- Fix [#77](https://github.com/planttheidea/fast-equals/issues/73) - better circular object validation
|
||||
|
||||
## 3.0.2
|
||||
|
||||
- Fix [#73](https://github.com/planttheidea/fast-equals/issues/73) - support comparison of primitive wrappers
|
||||
- [#76](https://github.com/planttheidea/fast-equals/pull/76) - improve speed and accuracy of `RegExp` comparison in modern environments
|
||||
|
||||
## 3.0.1
|
||||
|
||||
- Fix [#71](https://github.com/planttheidea/fast-equals/pull/71) - use generic types for better type flow-through
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
When creating a custom equality comparator via `createCustomEqual`, the equality method has an expanded contract:
|
||||
|
||||
```ts
|
||||
// Before
|
||||
type EqualityComparator = (objectA: any, objectB: any, meta: any) => boolean;
|
||||
|
||||
// After
|
||||
type InternalEqualityComparator = (
|
||||
objectA: any,
|
||||
objectB: any,
|
||||
indexOrKeyA: any,
|
||||
indexOrKeyB: any,
|
||||
parentA: any,
|
||||
parentB: any,
|
||||
meta: any,
|
||||
) => boolean;
|
||||
```
|
||||
|
||||
If you have a custom equality comparator, you can ignore the differences by just passing additional `undefined` parameters, or you can use the parameters to further improve / clarify the logic.
|
||||
|
||||
- Add [#57](https://github.com/planttheidea/fast-equals/pull/57) - support additional metadata for custom equality comparators
|
||||
|
||||
## 2.0.4
|
||||
|
||||
- Fix [#58](https://github.com/planttheidea/fast-equals/issues/58) - duplicate entries in `Map` / `Set` can create false equality success
|
||||
- [#60](https://github.com/planttheidea/fast-equals/issues/60) - Add documentation for key equality of `Map` being a part of `deepEqual`
|
||||
|
||||
## 2.0.3
|
||||
|
||||
- Fix [#50](https://github.com/planttheidea/fast-equals/pull/50) - copy-pasta in cacheable check
|
||||
|
||||
## 2.0.2
|
||||
|
||||
- Optimize iterables comparisons to not double-iterate
|
||||
- Optimize loop-based comparisons for speed
|
||||
- Improve cache handling in circular handlers
|
||||
- Improve stability of memory by reducing variable instantiation
|
||||
|
||||
## 2.0.1
|
||||
|
||||
- Fix [#41](https://github.com/planttheidea/fast-equals/pull/41) - prevent `.rpt2_cache` directory from being published for better CI environment support (thanks [@herberttn](https://github.com/herberttn))
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- There are longer `fast-equals/es`, `fast-equals/lib`, `fast-equals/mjs` locations
|
||||
- Instead, there are 3 builds in `dist` for different consumption types:
|
||||
- `fast-equals.js` (UMD / `browser`)
|
||||
- `fast-equals.esm.js` (ESM / `module`)
|
||||
- `fast-equals.cjs.js` (CommonJS / `main`)
|
||||
- There is no default export anymore, only the previously-existing named exports
|
||||
- To get all into a namespace, use `import * as fe from 'fast-equals`
|
||||
|
||||
### Updates
|
||||
|
||||
- Rewritten completely in TypeScript
|
||||
- Improve speed of `Map` / `Set` comparisons
|
||||
- Improve speed of React element comparisons
|
||||
|
||||
### Fixes
|
||||
|
||||
- Consider pure objects (`Object.create(null)`) to be plain objects
|
||||
- Fix typings for `createCustomEqual`
|
||||
|
||||
## 1.6.3
|
||||
|
||||
- Check the size of the iterable before converting to arrays
|
||||
|
||||
## 1.6.2
|
||||
|
||||
- Fix [#23](https://github.com/planttheidea/fast-equals/issues/23) - false positives for map
|
||||
- Replace `uglify` with `terser`
|
||||
- Use `rollup` to build all the distributables (`main`, `module`, and `browser`)
|
||||
- Maintain `lib` and `es` transpilations in case consumers were deep-linking
|
||||
|
||||
## 1.6.1
|
||||
|
||||
- Upgrade to `babel@7`
|
||||
- Add `"sideEffects": false` to `package.json` for better tree-shaking in `webpack`
|
||||
|
||||
## 1.6.0
|
||||
|
||||
- Add ESM support for NodeJS with separate [`.mjs` extension](https://nodejs.org/api/esm.html) exports
|
||||
|
||||
## 1.5.3
|
||||
|
||||
- Fix `Map` / `Set` comparison to not require order to match to be equal
|
||||
|
||||
## 1.5.2
|
||||
|
||||
- Improve speed of object comparison through custom `hasKey` method
|
||||
|
||||
## 1.5.1
|
||||
|
||||
- Fix lack of support for `unicode` and `sticky` RegExp flag checks
|
||||
|
||||
## 1.5.0
|
||||
|
||||
- Add [`circularDeepEqual`](README.md#circulardeepequal) and [`circularShallowEqual`](README.md#circularshallowequal) methods
|
||||
- Add `meta` third parameter to `comparator` calls, for use with `createCustomEqual` method
|
||||
|
||||
## 1.4.1
|
||||
|
||||
- Fix issue where `lastIndex` was not being tested on `RegExp` objects
|
||||
|
||||
## 1.4.0
|
||||
|
||||
- Add support for comparing promise-like objects (strict equality only)
|
||||
|
||||
## 1.3.1
|
||||
|
||||
- Make `react` comparison more accurate, and a touch faster
|
||||
|
||||
## 1.3.0
|
||||
|
||||
- Add support for deep-equal comparisons between `react` elements
|
||||
- Add comparison with `react-fast-compare`
|
||||
- Use `rollup` for `dist` file builds
|
||||
|
||||
## 1.2.1
|
||||
|
||||
- Fix errors from TypeScript typings in strict mode (thanks [@HitoriSensei](https://github.com/HitoriSensei))
|
||||
|
||||
## 1.2.0
|
||||
|
||||
- Surface `isSameValueZero` as [`sameValueZeroEqual`](#samevaluezeroequal) option
|
||||
|
||||
## 1.1.0
|
||||
|
||||
- Add TypeScript typings (thanks [@josh-sachs](https://github.com/josh-sachs))
|
||||
|
||||
## 1.0.6
|
||||
|
||||
- Support invalid date equality via `isSameValueZero`
|
||||
|
||||
## 1.0.5
|
||||
|
||||
- Replace `isStrictlyEqual` with `isSameValueZero` to ensure that `shallowEqual` accounts for `NaN` equality
|
||||
|
||||
## 1.0.4
|
||||
|
||||
- Only check values when comparing `Set` objects (improves performance of `Set` check by ~12%)
|
||||
|
||||
## 1.0.3
|
||||
|
||||
- Make `Map` and `Set` comparisons more explicit
|
||||
|
||||
## 1.0.2
|
||||
|
||||
- Fix symmetrical comparison of iterables
|
||||
- Reduce footprint
|
||||
|
||||
## 1.0.1
|
||||
|
||||
- Prevent babel transpilation of `typeof` into helper for faster runtime
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- Initial release
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
21
node_modules/fast-equals/LICENSE
generated
vendored
Normal file
21
node_modules/fast-equals/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Tony Quetano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
426
node_modules/fast-equals/README.md
generated
vendored
Normal file
426
node_modules/fast-equals/README.md
generated
vendored
Normal file
@@ -0,0 +1,426 @@
|
||||
# fast-equals
|
||||
|
||||
<img src="https://img.shields.io/badge/build-passing-brightgreen.svg"/>
|
||||
<img src="https://img.shields.io/badge/coverage-100%25-brightgreen.svg"/>
|
||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg"/>
|
||||
|
||||
Perform [blazing fast](#benchmarks) equality comparisons (either deep or shallow) on two objects passed, while also maintaining a high degree of flexibility for various implementation use-cases. It has no dependencies, and is ~2kB when minified and gzipped.
|
||||
|
||||
The following types are handled out-of-the-box:
|
||||
|
||||
- Plain objects (including `react` elements and `Arguments`)
|
||||
- Arrays
|
||||
- Typed Arrays
|
||||
- `Date` objects
|
||||
- `RegExp` objects
|
||||
- `Map` / `Set` iterables
|
||||
- `Promise` objects
|
||||
- Primitive wrappers (`new Boolean()` / `new Number()` / `new String()`)
|
||||
- Custom class instances, including subclasses of native classes
|
||||
|
||||
Methods are available for deep, shallow, or referential equality comparison. In addition, you can opt into support for circular objects, or performing a "strict" comparison with unconventional property definition, or both. You can also customize any specific type comparison based on your application's use-cases.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [fast-equals](#fast-equals)
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Usage](#usage)
|
||||
- [Specific builds](#specific-builds)
|
||||
- [Available methods](#available-methods)
|
||||
- [deepEqual](#deepequal)
|
||||
- [Comparing `Map`s](#comparing-maps)
|
||||
- [shallowEqual](#shallowequal)
|
||||
- [sameValueZeroEqual](#samevaluezeroequal)
|
||||
- [circularDeepEqual](#circulardeepequal)
|
||||
- [circularShallowEqual](#circularshallowequal)
|
||||
- [strictDeepEqual](#strictdeepequal)
|
||||
- [strictShallowEqual](#strictshallowequal)
|
||||
- [strictCircularDeepEqual](#strictcirculardeepequal)
|
||||
- [strictCircularShallowEqual](#strictcircularshallowequal)
|
||||
- [createCustomEqual](#createcustomequal)
|
||||
- [unknownTagComparators](#unknowntagcomparators)
|
||||
- [Recipes](#recipes)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Development](#development)
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { deepEqual } from 'fast-equals';
|
||||
|
||||
console.log(deepEqual({ foo: 'bar' }, { foo: 'bar' })); // true
|
||||
```
|
||||
|
||||
### Specific builds
|
||||
|
||||
By default, npm should resolve the correct build of the package based on your consumption (ESM vs CommonJS). However, if you want to force use of a specific build, they can be located here:
|
||||
|
||||
- ESM => `fast-equals/dist/esm/index.mjs`
|
||||
- CommonJS => `fast-equals/dist/cjs/index.cjs`
|
||||
- UMD => `fast-equals/dist/umd/index.js`
|
||||
- Minified UMD => `fast-equals/dist/min/index.js`
|
||||
|
||||
If you are having issues loading a specific build type, [please file an issue](https://github.com/planttheidea/fast-equals/issues).
|
||||
|
||||
## Available methods
|
||||
|
||||
### deepEqual
|
||||
|
||||
Performs a deep equality comparison on the two objects passed and returns a boolean representing the value equivalency of the objects.
|
||||
|
||||
```ts
|
||||
import { deepEqual } from 'fast-equals';
|
||||
|
||||
const objectA = { foo: { bar: 'baz' } };
|
||||
const objectB = { foo: { bar: 'baz' } };
|
||||
|
||||
console.log(objectA === objectB); // false
|
||||
console.log(deepEqual(objectA, objectB)); // true
|
||||
```
|
||||
|
||||
#### Comparing `Map`s
|
||||
|
||||
`Map` objects support complex keys (objects, Arrays, etc.), however [the spec for key lookups in `Map` are based on `SameZeroValue`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#key_equality). If the spec were followed for comparison, the following would always be `false`:
|
||||
|
||||
```ts
|
||||
const mapA = new Map([[{ foo: 'bar' }, { baz: 'quz' }]]);
|
||||
const mapB = new Map([[{ foo: 'bar' }, { baz: 'quz' }]]);
|
||||
|
||||
deepEqual(mapA, mapB);
|
||||
```
|
||||
|
||||
To support true deep equality of all contents, `fast-equals` will perform a deep equality comparison for key and value parirs. Therefore, the above would be `true`.
|
||||
|
||||
### shallowEqual
|
||||
|
||||
Performs a shallow equality comparison on the two objects passed and returns a boolean representing the value equivalency of the objects.
|
||||
|
||||
```ts
|
||||
import { shallowEqual } from 'fast-equals';
|
||||
|
||||
const nestedObject = { bar: 'baz' };
|
||||
|
||||
const objectA = { foo: nestedObject };
|
||||
const objectB = { foo: nestedObject };
|
||||
const objectC = { foo: { bar: 'baz' } };
|
||||
|
||||
console.log(objectA === objectB); // false
|
||||
console.log(shallowEqual(objectA, objectB)); // true
|
||||
console.log(shallowEqual(objectA, objectC)); // false
|
||||
```
|
||||
|
||||
### sameValueZeroEqual
|
||||
|
||||
Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) comparison on the two objects passed and returns a boolean representing the value equivalency of the objects. In simple terms, this means either strictly equal or both `NaN`.
|
||||
|
||||
```ts
|
||||
import { sameValueZeroEqual } from 'fast-equals';
|
||||
|
||||
const mainObject = { foo: NaN, bar: 'baz' };
|
||||
|
||||
const objectA = 'baz';
|
||||
const objectB = NaN;
|
||||
const objectC = { foo: NaN, bar: 'baz' };
|
||||
|
||||
console.log(sameValueZeroEqual(mainObject.bar, objectA)); // true
|
||||
console.log(sameValueZeroEqual(mainObject.foo, objectB)); // true
|
||||
console.log(sameValueZeroEqual(mainObject, objectC)); // false
|
||||
```
|
||||
|
||||
### circularDeepEqual
|
||||
|
||||
Performs the same comparison as `deepEqual` but supports circular objects. It is slower than `deepEqual`, so only use if you know circular objects are present.
|
||||
|
||||
```ts
|
||||
function Circular(value) {
|
||||
this.me = {
|
||||
deeply: {
|
||||
nested: {
|
||||
reference: this,
|
||||
},
|
||||
},
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
console.log(circularDeepEqual(new Circular('foo'), new Circular('foo'))); // true
|
||||
console.log(circularDeepEqual(new Circular('foo'), new Circular('bar'))); // false
|
||||
```
|
||||
|
||||
Just as with `deepEqual`, [both keys and values are compared for deep equality](#comparing-maps).
|
||||
|
||||
### circularShallowEqual
|
||||
|
||||
Performs the same comparison as `shallowequal` but supports circular objects. It is slower than `shallowEqual`, so only use if you know circular objects are present.
|
||||
|
||||
```ts
|
||||
const array = ['foo'];
|
||||
|
||||
array.push(array);
|
||||
|
||||
console.log(circularShallowEqual(array, ['foo', array])); // true
|
||||
console.log(circularShallowEqual(array, [array])); // false
|
||||
```
|
||||
|
||||
### strictDeepEqual
|
||||
|
||||
Performs the same comparison as `deepEqual` but performs a strict comparison of the objects. In this includes:
|
||||
|
||||
- Checking symbol properties
|
||||
- Checking non-enumerable properties in object comparisons
|
||||
- Checking full descriptor of properties on the object to match
|
||||
- Checking non-index properties on arrays
|
||||
- Checking non-key properties on `Map` / `Set` objects
|
||||
|
||||
```ts
|
||||
const array = [{ foo: 'bar' }];
|
||||
const otherArray = [{ foo: 'bar' }];
|
||||
|
||||
array.bar = 'baz';
|
||||
otherArray.bar = 'baz';
|
||||
|
||||
console.log(strictDeepEqual(array, otherArray)); // true;
|
||||
console.log(strictDeepEqual(array, [{ foo: 'bar' }])); // false;
|
||||
```
|
||||
|
||||
### strictShallowEqual
|
||||
|
||||
Performs the same comparison as `shallowEqual` but performs a strict comparison of the objects. In this includes:
|
||||
|
||||
- Checking non-enumerable properties in object comparisons
|
||||
- Checking full descriptor of properties on the object to match
|
||||
- Checking non-index properties on arrays
|
||||
- Checking non-key properties on `Map` / `Set` objects
|
||||
|
||||
```ts
|
||||
const array = ['foo'];
|
||||
const otherArray = ['foo'];
|
||||
|
||||
array.bar = 'baz';
|
||||
otherArray.bar = 'baz';
|
||||
|
||||
console.log(strictDeepEqual(array, otherArray)); // true;
|
||||
console.log(strictDeepEqual(array, ['foo'])); // false;
|
||||
```
|
||||
|
||||
### strictCircularDeepEqual
|
||||
|
||||
Performs the same comparison as `circularDeepEqual` but performs a strict comparison of the objects. In this includes:
|
||||
|
||||
- Checking `Symbol` properties on the object
|
||||
- Checking non-enumerable properties in object comparisons
|
||||
- Checking full descriptor of properties on the object to match
|
||||
- Checking non-index properties on arrays
|
||||
- Checking non-key properties on `Map` / `Set` objects
|
||||
|
||||
```ts
|
||||
function Circular(value) {
|
||||
this.me = {
|
||||
deeply: {
|
||||
nested: {
|
||||
reference: this,
|
||||
},
|
||||
},
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
const first = new Circular('foo');
|
||||
|
||||
Object.defineProperty(first, 'bar', {
|
||||
enumerable: false,
|
||||
value: 'baz',
|
||||
});
|
||||
|
||||
const second = new Circular('foo');
|
||||
|
||||
Object.defineProperty(second, 'bar', {
|
||||
enumerable: false,
|
||||
value: 'baz',
|
||||
});
|
||||
|
||||
console.log(circularDeepEqual(first, second)); // true
|
||||
console.log(circularDeepEqual(first, new Circular('foo'))); // false
|
||||
```
|
||||
|
||||
### strictCircularShallowEqual
|
||||
|
||||
Performs the same comparison as `circularShallowEqual` but performs a strict comparison of the objects. In this includes:
|
||||
|
||||
- Checking non-enumerable properties in object comparisons
|
||||
- Checking full descriptor of properties on the object to match
|
||||
- Checking non-index properties on arrays
|
||||
- Checking non-key properties on `Map` / `Set` objects
|
||||
|
||||
```ts
|
||||
const array = ['foo'];
|
||||
const otherArray = ['foo'];
|
||||
|
||||
array.push(array);
|
||||
otherArray.push(otherArray);
|
||||
|
||||
array.bar = 'baz';
|
||||
otherArray.bar = 'baz';
|
||||
|
||||
console.log(circularShallowEqual(array, otherArray)); // true
|
||||
console.log(circularShallowEqual(array, ['foo', array])); // false
|
||||
```
|
||||
|
||||
### createCustomEqual
|
||||
|
||||
Creates a custom equality comparator that will be used on nested values in the object. Unlike `deepEqual` and `shallowEqual`, this is a factory method that receives the default options used internally, and allows you to override the defaults as needed. This is generally for extreme edge-cases, or supporting legacy environments.
|
||||
|
||||
The signature is as follows:
|
||||
|
||||
```ts
|
||||
interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
|
||||
interface ComparatorConfig<Meta> {
|
||||
areArraysEqual: TypeEqualityComparator<any[], Meta>;
|
||||
areDatesEqual: TypeEqualityComparator<Date, Meta>;
|
||||
areErrorsEqual: TypeEqualityComparator<Error, Meta>;
|
||||
areFunctionsEqual: TypeEqualityComparator<(...args: any[]) => any, Meta>;
|
||||
areMapsEqual: TypeEqualityComparator<Map<any, any>, Meta>;
|
||||
areObjectsEqual: TypeEqualityComparator<Record<string, any>, Meta>;
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<
|
||||
boolean | string | number,
|
||||
Meta
|
||||
>;
|
||||
areRegExpsEqual: TypeEqualityComparator<RegExp, Meta>;
|
||||
areSetsEqual: TypeEqualityComparator<Set<any>, Meta>;
|
||||
areTypedArraysEqual: TypeEqualityComparator<TypedArray, Meta>;
|
||||
areUrlsEqual: TypeEqualityComparator<URL, Meta>;
|
||||
unknownTagComparators: Record<string, TypeEqualityComparator<string, any>>;
|
||||
}
|
||||
|
||||
function createCustomEqual<Meta>(options: {
|
||||
circular?: boolean;
|
||||
createCustomConfig?: (
|
||||
defaultConfig: ComparatorConfig<Meta>,
|
||||
) => Partial<ComparatorConfig<Meta>>;
|
||||
createInternalComparator?: (
|
||||
compare: <A, B>(a: A, b: B, state: State<Meta>) => boolean,
|
||||
) => (
|
||||
a: any,
|
||||
b: any,
|
||||
indexOrKeyA: any,
|
||||
indexOrKeyB: any,
|
||||
parentA: any,
|
||||
parentB: any,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
createState?: () => { cache?: Cache; meta?: Meta };
|
||||
strict?: boolean;
|
||||
}): <A, B>(a: A, b: B) => boolean;
|
||||
```
|
||||
|
||||
Create a custom equality comparator. This allows complete control over building a bespoke equality method, in case your use-case requires a higher degree of performance, legacy environment support, or any other non-standard usage. The [recipes](#recipes) provide examples of use in different use-cases, but if you have a specific goal in mind and would like assistance feel free to [file an issue](https://github.com/planttheidea/fast-equals/issues).
|
||||
|
||||
_**NOTE**: `Map` implementations compare equality for both keys and value. When using a custom comparator and comparing equality of the keys, the iteration index is provided as both `indexOrKeyA` and `indexOrKeyB` to help use-cases where ordering of keys matters to equality._
|
||||
|
||||
#### unknownTagComparators
|
||||
|
||||
If you want to compare objects that have a custom `@@toStringTag`, you can provide a map of the custom tags you want to support via the `unknownTagComparators` option. See [this recipe]('./recipes/special-objects.md) for an example.
|
||||
|
||||
#### Recipes
|
||||
|
||||
Some recipes have been created to provide examples of use-cases for `createCustomEqual`. Even if not directly applicable to the problem you are solving, they can offer guidance of how to structure your solution.
|
||||
|
||||
- [Legacy environment support for `RegExp` comparators](./recipes/legacy-regexp-support.md)
|
||||
- [Explicit property check](./recipes/explicit-property-check.md)
|
||||
- [Using `meta` in comparison](./recipes//using-meta-in-comparison.md)
|
||||
- [Comparing non-standard properties](./recipes/non-standard-properties.md)
|
||||
- [Strict property descriptor comparison](./recipes/strict-property-descriptor-check.md)
|
||||
- [Legacy environment support for circualr equal comparators](./recipes/legacy-circular-equal-support.md)
|
||||
- [Custom `@@toStringTag` support]('./recipes/special-objects.md)
|
||||
|
||||
## Benchmarks
|
||||
|
||||
All benchmarks were performed on an i9-11900H Ubuntu Linux 24.04 laptop with 64GB of memory using NodeJS version `20.17.0`, and are based on averages of running comparisons based deep equality on the following object types:
|
||||
|
||||
- Primitives (`String`, `Number`, `null`, `undefined`)
|
||||
- `Function`
|
||||
- `Object`
|
||||
- `Array`
|
||||
- `Date`
|
||||
- `RegExp`
|
||||
- `react` elements
|
||||
- A mixed object with a combination of all the above types
|
||||
|
||||
```bash
|
||||
Testing mixed objects equal...
|
||||
┌─────────┬─────────────────────────────────┬────────────────┐
|
||||
│ (index) │ Package │ Ops/sec │
|
||||
├─────────┼─────────────────────────────────┼────────────────┤
|
||||
│ 0 │ 'fast-equals' │ 1256867.529926 │
|
||||
│ 1 │ 'fast-deep-equal' │ 1207041.997437 │
|
||||
│ 2 │ 'shallow-equal-fuzzy' │ 1142536.391324 │
|
||||
│ 3 │ 'react-fast-compare' │ 1140373.249605 │
|
||||
│ 4 │ 'dequal/lite' │ 708240.354044 │
|
||||
│ 5 │ 'dequal' │ 704655.931143 │
|
||||
│ 6 │ 'fast-equals (circular)' │ 595853.718756 │
|
||||
│ 7 │ 'underscore.isEqual' │ 433596.570863 │
|
||||
│ 8 │ 'assert.deepStrictEqual' │ 310595.198662 │
|
||||
│ 9 │ 'lodash.isEqual' │ 232192.454526 │
|
||||
│ 10 │ 'fast-equals (strict)' │ 175941.250843 │
|
||||
│ 11 │ 'fast-equals (strict circular)' │ 154606.328398 │
|
||||
│ 12 │ 'deep-eql' │ 136052.484375 │
|
||||
│ 13 │ 'deep-equal' │ 854.061311 │
|
||||
└─────────┴─────────────────────────────────┴────────────────┘
|
||||
|
||||
Testing mixed objects not equal...
|
||||
┌─────────┬─────────────────────────────────┬────────────────┐
|
||||
│ (index) │ Package │ Ops/sec │
|
||||
├─────────┼─────────────────────────────────┼────────────────┤
|
||||
│ 0 │ 'fast-equals' │ 3795307.779634 │
|
||||
│ 1 │ 'fast-deep-equal' │ 2987150.35694 │
|
||||
│ 2 │ 'react-fast-compare' │ 2733075.404272 │
|
||||
│ 3 │ 'fast-equals (circular)' │ 2311547.685659 │
|
||||
│ 4 │ 'dequal/lite' │ 1156909.54415 │
|
||||
│ 5 │ 'dequal' │ 1151209.161878 │
|
||||
│ 6 │ 'fast-equals (strict)' │ 1102248.247412 │
|
||||
│ 7 │ 'fast-equals (strict circular)' │ 1020639.089577 │
|
||||
│ 8 │ 'nano-equal' │ 1009557.685012 │
|
||||
│ 9 │ 'underscore.isEqual' │ 770286.698227 │
|
||||
│ 10 │ 'lodash.isEqual' │ 296338.570457 │
|
||||
│ 11 │ 'deep-eql' │ 152741.182224 │
|
||||
│ 12 │ 'assert.deepStrictEqual' │ 20163.203513 │
|
||||
│ 13 │ 'deep-equal' │ 3519.448516 │
|
||||
└─────────┴─────────────────────────────────┴────────────────┘
|
||||
```
|
||||
|
||||
Caveats that impact the benchmark (and accuracy of comparison):
|
||||
|
||||
- `Map`s, `Promise`s, and `Set`s were excluded from the benchmark entirely because no library other than `deep-eql` fully supported their comparison
|
||||
- `fast-deep-equal`, `react-fast-compare` and `nano-equal` throw on objects with `null` as prototype (`Object.create(null)`)
|
||||
- `assert.deepStrictEqual` does not support `NaN` or `SameValueZero` equality for dates
|
||||
- `deep-eql` does not support `SameValueZero` equality for zero equality (positive and negative zero are not equal)
|
||||
- `deep-equal` does not support `NaN` and does not strictly compare object type, or date / regexp values, nor uses `SameValueZero` equality for dates
|
||||
- `fast-deep-equal` does not support `NaN` or `SameValueZero` equality for dates
|
||||
- `nano-equal` does not strictly compare object property structure, array length, or object type, nor `SameValueZero` equality for dates
|
||||
- `react-fast-compare` does not support `NaN` or `SameValueZero` equality for dates, and does not compare `function` equality
|
||||
- `shallow-equal-fuzzy` does not strictly compare object type or regexp values, nor `SameValueZero` equality for dates
|
||||
- `underscore.isEqual` does not support `SameValueZero` equality for primitives or dates
|
||||
|
||||
All of these have the potential of inflating the respective library's numbers in comparison to `fast-equals`, but it was the closest apples-to-apples comparison I could create of a reasonable sample size. It should be noted that `react` elements can be circular objects, however simple elements are not; I kept the `react` comparison very basic to allow it to be included.
|
||||
|
||||
## Development
|
||||
|
||||
Standard practice, clone the repo and `npm i` to get the dependencies. The following npm scripts are available:
|
||||
|
||||
- benchmark => run benchmark tests against other equality libraries
|
||||
- build => build `main`, `module`, and `browser` distributables with `rollup`
|
||||
- clean => run `rimraf` on the `dist` folder
|
||||
- dev => start webpack playground App
|
||||
- dist => run `build`
|
||||
- lint => run ESLint on all files in `src` folder (also runs on `dev` script)
|
||||
- lint:fix => run `lint` script, but with auto-fixer
|
||||
- prepublish:compile => run `lint`, `test:coverage`, `transpile:lib`, `transpile:es`, and `dist` scripts
|
||||
- start => run `dev`
|
||||
- test => run AVA with NODE_ENV=test on all files in `test` folder
|
||||
- test:coverage => run same script as `test` with code coverage calculation via `nyc`
|
||||
- test:watch => run same script as `test` but keep persistent watcher
|
||||
638
node_modules/fast-equals/dist/cjs/index.cjs
generated
vendored
Normal file
638
node_modules/fast-equals/dist/cjs/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,638 @@
|
||||
'use strict';
|
||||
|
||||
var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
function combineComparators(comparatorA, comparatorB) {
|
||||
return function isEqual(a, b, state) {
|
||||
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
function createIsCircular(areItemsEqual) {
|
||||
return function isCircular(a, b, state) {
|
||||
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
||||
return areItemsEqual(a, b, state);
|
||||
}
|
||||
var cache = state.cache;
|
||||
var cachedA = cache.get(a);
|
||||
var cachedB = cache.get(b);
|
||||
if (cachedA && cachedB) {
|
||||
return cachedA === b && cachedB === a;
|
||||
}
|
||||
cache.set(a, b);
|
||||
cache.set(b, a);
|
||||
var result = areItemsEqual(a, b, state);
|
||||
cache.delete(a);
|
||||
cache.delete(b);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
function getShortTag(value) {
|
||||
return value != null ? value[Symbol.toStringTag] : undefined;
|
||||
}
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
function getStrictProperties(object) {
|
||||
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
||||
}
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
var hasOwn = Object.hasOwn ||
|
||||
(function (object, property) {
|
||||
return hasOwnProperty.call(object, property);
|
||||
});
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
function sameValueZeroEqual(a, b) {
|
||||
return a === b || (!a && !b && a !== a && b !== b);
|
||||
}
|
||||
|
||||
var PREACT_VNODE = '__v';
|
||||
var PREACT_OWNER = '__o';
|
||||
var REACT_OWNER = '_owner';
|
||||
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
function areArraysEqual(a, b, state) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
function areDatesEqual(a, b) {
|
||||
return sameValueZeroEqual(a.getTime(), b.getTime());
|
||||
}
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
function areErrorsEqual(a, b) {
|
||||
return (a.name === b.name &&
|
||||
a.message === b.message &&
|
||||
a.cause === b.cause &&
|
||||
a.stack === b.stack);
|
||||
}
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
function areFunctionsEqual(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
function areMapsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.entries();
|
||||
var aResult;
|
||||
var bResult;
|
||||
var index = 0;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.entries();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (matchedIndices[matchIndex]) {
|
||||
matchIndex++;
|
||||
continue;
|
||||
}
|
||||
var aEntry = aResult.value;
|
||||
var bEntry = bResult.value;
|
||||
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) &&
|
||||
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
var areNumbersEqual = sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
function areObjectsEqual(a, b, state) {
|
||||
var properties = keys(a);
|
||||
var index = properties.length;
|
||||
if (keys(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
if (!isPropertyEqual(a, b, state, properties[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
function areObjectsEqualStrict(a, b, state) {
|
||||
var properties = getStrictProperties(a);
|
||||
var index = properties.length;
|
||||
if (getStrictProperties(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
var property;
|
||||
var descriptorA;
|
||||
var descriptorB;
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
property = properties[index];
|
||||
if (!isPropertyEqual(a, b, state, property)) {
|
||||
return false;
|
||||
}
|
||||
descriptorA = getOwnPropertyDescriptor(a, property);
|
||||
descriptorB = getOwnPropertyDescriptor(b, property);
|
||||
if ((descriptorA || descriptorB) &&
|
||||
(!descriptorA ||
|
||||
!descriptorB ||
|
||||
descriptorA.configurable !== descriptorB.configurable ||
|
||||
descriptorA.enumerable !== descriptorB.enumerable ||
|
||||
descriptorA.writable !== descriptorB.writable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
function arePrimitiveWrappersEqual(a, b) {
|
||||
return sameValueZeroEqual(a.valueOf(), b.valueOf());
|
||||
}
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
function areRegExpsEqual(a, b) {
|
||||
return a.source === b.source && a.flags === b.flags;
|
||||
}
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
function areSetsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.values();
|
||||
var aResult;
|
||||
var bResult;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.values();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (!matchedIndices[matchIndex] &&
|
||||
state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
function areTypedArraysEqual(a, b) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (a[index] !== b[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
function areUrlsEqual(a, b) {
|
||||
return (a.hostname === b.hostname &&
|
||||
a.pathname === b.pathname &&
|
||||
a.protocol === b.protocol &&
|
||||
a.port === b.port &&
|
||||
a.hash === b.hash &&
|
||||
a.username === b.username &&
|
||||
a.password === b.password);
|
||||
}
|
||||
function isPropertyEqual(a, b, state, property) {
|
||||
if ((property === REACT_OWNER ||
|
||||
property === PREACT_OWNER ||
|
||||
property === PREACT_VNODE) &&
|
||||
(a.$$typeof || b.$$typeof)) {
|
||||
return true;
|
||||
}
|
||||
return (hasOwn(b, property) &&
|
||||
state.equals(a[property], b[property], property, property, a, b, state));
|
||||
}
|
||||
|
||||
var ARGUMENTS_TAG = '[object Arguments]';
|
||||
var BOOLEAN_TAG = '[object Boolean]';
|
||||
var DATE_TAG = '[object Date]';
|
||||
var ERROR_TAG = '[object Error]';
|
||||
var MAP_TAG = '[object Map]';
|
||||
var NUMBER_TAG = '[object Number]';
|
||||
var OBJECT_TAG = '[object Object]';
|
||||
var REG_EXP_TAG = '[object RegExp]';
|
||||
var SET_TAG = '[object Set]';
|
||||
var STRING_TAG = '[object String]';
|
||||
var URL_TAG = '[object URL]';
|
||||
var isArray = Array.isArray;
|
||||
var isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView
|
||||
? ArrayBuffer.isView
|
||||
: null;
|
||||
var assign = Object.assign;
|
||||
var getTag = Object.prototype.toString.call.bind(Object.prototype.toString);
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
function createEqualityComparator(_a) {
|
||||
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;
|
||||
/**
|
||||
* compare the value of the two objects and return true if they are equivalent in values
|
||||
*/
|
||||
return function comparator(a, b, state) {
|
||||
// If the items are strictly equal, no need to do a value comparison.
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
// If either of the items are nullish and fail the strictly equal check
|
||||
// above, then they must be unequal.
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
var type = typeof a;
|
||||
if (type !== typeof b) {
|
||||
return false;
|
||||
}
|
||||
if (type !== 'object') {
|
||||
if (type === 'number') {
|
||||
return areNumbersEqual(a, b, state);
|
||||
}
|
||||
if (type === 'function') {
|
||||
return areFunctionsEqual(a, b, state);
|
||||
}
|
||||
// If a primitive value that is not strictly equal, it must be unequal.
|
||||
return false;
|
||||
}
|
||||
var constructor = a.constructor;
|
||||
// Checks are listed in order of commonality of use-case:
|
||||
// 1. Common complex object types (plain object, array)
|
||||
// 2. Common data values (date, regexp)
|
||||
// 3. Less-common complex object types (map, set)
|
||||
// 4. Less-common data values (promise, primitive wrappers)
|
||||
// Inherently this is both subjective and assumptive, however
|
||||
// when reviewing comparable libraries in the wild this order
|
||||
// appears to be generally consistent.
|
||||
// Constructors should match, otherwise there is potential for false positives
|
||||
// between class and subclass or custom object and POJO.
|
||||
if (constructor !== b.constructor) {
|
||||
return false;
|
||||
}
|
||||
// `isPlainObject` only checks against the object's own realm. Cross-realm
|
||||
// comparisons are rare, and will be handled in the ultimate fallback, so
|
||||
// we can avoid capturing the string tag.
|
||||
if (constructor === Object) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
||||
// the string tag or doing an `instanceof` check.
|
||||
if (isArray(a)) {
|
||||
return areArraysEqual(a, b, state);
|
||||
}
|
||||
// `isTypedArray()` works on all possible TypedArray classes, so we can avoid
|
||||
// capturing the string tag or comparing against all possible constructors.
|
||||
if (isTypedArray != null && isTypedArray(a)) {
|
||||
return areTypedArraysEqual(a, b, state);
|
||||
}
|
||||
// Try to fast-path equality checks for other complex object types in the
|
||||
// same realm to avoid capturing the string tag. Strict equality is used
|
||||
// instead of `instanceof` because it is more performant for the common
|
||||
// use-case. If someone is subclassing a native class, it will be handled
|
||||
// with the string tag comparison.
|
||||
if (constructor === Date) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
if (constructor === RegExp) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Map) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Set) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
// Since this is a custom object, capture the string tag to determing its type.
|
||||
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
||||
var tag = getTag(a);
|
||||
if (tag === DATE_TAG) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
||||
// tested like a standard object.
|
||||
if (tag === REG_EXP_TAG) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (tag === MAP_TAG) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (tag === SET_TAG) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
if (tag === OBJECT_TAG) {
|
||||
// The exception for value comparison is custom `Promise`-like class instances. These should
|
||||
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
||||
// it reaches this point then that strict equality comparison has already failed.
|
||||
return (typeof a.then !== 'function' &&
|
||||
typeof b.then !== 'function' &&
|
||||
areObjectsEqual(a, b, state));
|
||||
}
|
||||
// If a URL tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === URL_TAG) {
|
||||
return areUrlsEqual(a, b, state);
|
||||
}
|
||||
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === ERROR_TAG) {
|
||||
return areErrorsEqual(a, b, state);
|
||||
}
|
||||
// If an arguments tag, it should be treated as a standard object.
|
||||
if (tag === ARGUMENTS_TAG) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// As the penultimate fallback, check if the values passed are primitive wrappers. This
|
||||
// is very rare in modern JS, which is why it is deprioritized compared to all other object
|
||||
// types.
|
||||
if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {
|
||||
return arePrimitiveWrappersEqual(a, b, state);
|
||||
}
|
||||
if (unknownTagComparators) {
|
||||
var unknownTagComparator = unknownTagComparators[tag];
|
||||
if (!unknownTagComparator) {
|
||||
var shortTag = getShortTag(a);
|
||||
if (shortTag) {
|
||||
unknownTagComparator = unknownTagComparators[shortTag];
|
||||
}
|
||||
}
|
||||
// If the custom config has an unknown tag comparator that matches the captured tag or the
|
||||
// @@toStringTag, it is the source of truth for whether the values are equal.
|
||||
if (unknownTagComparator) {
|
||||
return unknownTagComparator(a, b, state);
|
||||
}
|
||||
}
|
||||
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
||||
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
||||
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
||||
// comparison that can be made.
|
||||
// - For types that can be introspected, but rarely have requirements to be compared
|
||||
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
||||
// use-cases (may be included in a future release, if requested enough).
|
||||
// - For types that can be introspected but do not have an objective definition of what
|
||||
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
||||
// In all cases, these decisions should be reevaluated based on changes to the language and
|
||||
// common development practices.
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
function createEqualityComparatorConfig(_a) {
|
||||
var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;
|
||||
var config = {
|
||||
areArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areArraysEqual,
|
||||
areDatesEqual: areDatesEqual,
|
||||
areErrorsEqual: areErrorsEqual,
|
||||
areFunctionsEqual: areFunctionsEqual,
|
||||
areMapsEqual: strict
|
||||
? combineComparators(areMapsEqual, areObjectsEqualStrict)
|
||||
: areMapsEqual,
|
||||
areNumbersEqual: areNumbersEqual,
|
||||
areObjectsEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areObjectsEqual,
|
||||
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
||||
areRegExpsEqual: areRegExpsEqual,
|
||||
areSetsEqual: strict
|
||||
? combineComparators(areSetsEqual, areObjectsEqualStrict)
|
||||
: areSetsEqual,
|
||||
areTypedArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areTypedArraysEqual,
|
||||
areUrlsEqual: areUrlsEqual,
|
||||
unknownTagComparators: undefined,
|
||||
};
|
||||
if (createCustomConfig) {
|
||||
config = assign({}, config, createCustomConfig(config));
|
||||
}
|
||||
if (circular) {
|
||||
var areArraysEqual$1 = createIsCircular(config.areArraysEqual);
|
||||
var areMapsEqual$1 = createIsCircular(config.areMapsEqual);
|
||||
var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);
|
||||
var areSetsEqual$1 = createIsCircular(config.areSetsEqual);
|
||||
config = assign({}, config, {
|
||||
areArraysEqual: areArraysEqual$1,
|
||||
areMapsEqual: areMapsEqual$1,
|
||||
areObjectsEqual: areObjectsEqual$1,
|
||||
areSetsEqual: areSetsEqual$1,
|
||||
});
|
||||
}
|
||||
return config;
|
||||
}
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
function createInternalEqualityComparator(compare) {
|
||||
return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
|
||||
return compare(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
function createIsEqual(_a) {
|
||||
var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;
|
||||
if (createState) {
|
||||
return function isEqual(a, b) {
|
||||
var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;
|
||||
return comparator(a, b, {
|
||||
cache: cache,
|
||||
equals: equals,
|
||||
meta: meta,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (circular) {
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, {
|
||||
cache: new WeakMap(),
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
var state = {
|
||||
cache: undefined,
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
};
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, state);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
var deepEqual = createCustomEqual();
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
var strictDeepEqual = createCustomEqual({ strict: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
var circularDeepEqual = createCustomEqual({ circular: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularDeepEqual = createCustomEqual({
|
||||
circular: true,
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
var shallowEqual = createCustomEqual({
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
var strictShallowEqual = createCustomEqual({
|
||||
strict: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
var circularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
function createCustomEqual(options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;
|
||||
var config = createEqualityComparatorConfig(options);
|
||||
var comparator = createEqualityComparator(config);
|
||||
var equals = createCustomInternalComparator
|
||||
? createCustomInternalComparator(comparator)
|
||||
: createInternalEqualityComparator(comparator);
|
||||
return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });
|
||||
}
|
||||
|
||||
exports.circularDeepEqual = circularDeepEqual;
|
||||
exports.circularShallowEqual = circularShallowEqual;
|
||||
exports.createCustomEqual = createCustomEqual;
|
||||
exports.deepEqual = deepEqual;
|
||||
exports.sameValueZeroEqual = sameValueZeroEqual;
|
||||
exports.shallowEqual = shallowEqual;
|
||||
exports.strictCircularDeepEqual = strictCircularDeepEqual;
|
||||
exports.strictCircularShallowEqual = strictCircularShallowEqual;
|
||||
exports.strictDeepEqual = strictDeepEqual;
|
||||
exports.strictShallowEqual = strictShallowEqual;
|
||||
//# sourceMappingURL=index.cjs.map
|
||||
1
node_modules/fast-equals/dist/cjs/index.cjs.map
generated
vendored
Normal file
1
node_modules/fast-equals/dist/cjs/index.cjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/fast-equals/dist/cjs/types/comparator.d.ts
generated
vendored
Normal file
26
node_modules/fast-equals/dist/cjs/types/comparator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ComparatorConfig, CreateState, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator } from './internalTypes.d.ts';
|
||||
interface CreateIsEqualOptions<Meta> {
|
||||
circular: boolean;
|
||||
comparator: EqualityComparator<Meta>;
|
||||
createState: CreateState<Meta> | undefined;
|
||||
equals: InternalEqualityComparator<Meta>;
|
||||
strict: boolean;
|
||||
}
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
export declare function createEqualityComparator<Meta>({ areArraysEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators, }: ComparatorConfig<Meta>): EqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
export declare function createEqualityComparatorConfig<Meta>({ circular, createCustomConfig, strict, }: CustomEqualCreatorOptions<Meta>): ComparatorConfig<Meta>;
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
export declare function createInternalEqualityComparator<Meta>(compare: EqualityComparator<Meta>): InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
export declare function createIsEqual<Meta>({ circular, comparator, createState, equals, strict, }: CreateIsEqualOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
export {};
|
||||
54
node_modules/fast-equals/dist/cjs/types/equals.d.ts
generated
vendored
Normal file
54
node_modules/fast-equals/dist/cjs/types/equals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
import type { Dictionary, PrimitiveWrapper, State, TypedArray } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
export declare function areArraysEqual(a: any[], b: any[], state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
export declare function areDatesEqual(a: Date, b: Date): boolean;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
export declare function areErrorsEqual(a: Error, b: Error): boolean;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
export declare function areFunctionsEqual(a: (...args: any[]) => any, b: (...args: any[]) => any): boolean;
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
export declare function areMapsEqual(a: Map<any, any>, b: Map<any, any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
export declare const areNumbersEqual: typeof sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
export declare function areObjectsEqual(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
export declare function areObjectsEqualStrict(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
export declare function arePrimitiveWrappersEqual(a: PrimitiveWrapper, b: PrimitiveWrapper): boolean;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
export declare function areRegExpsEqual(a: RegExp, b: RegExp): boolean;
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
export declare function areSetsEqual(a: Set<any>, b: Set<any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
export declare function areTypedArraysEqual(a: TypedArray, b: TypedArray): boolean;
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
export declare function areUrlsEqual(a: URL, b: URL): boolean;
|
||||
47
node_modules/fast-equals/dist/cjs/types/index.d.ts
generated
vendored
Normal file
47
node_modules/fast-equals/dist/cjs/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { CustomEqualCreatorOptions } from './internalTypes.d.ts';
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
export { sameValueZeroEqual };
|
||||
export type { AnyEqualityComparator, Cache, CircularState, ComparatorConfig, CreateCustomComparatorConfig, CreateState, CustomEqualCreatorOptions, DefaultState, Dictionary, EqualityComparator, EqualityComparatorCreator, InternalEqualityComparator, PrimitiveWrapper, State, TypeEqualityComparator, TypedArray, } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export declare const deepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export declare const strictDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export declare const shallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export declare const strictShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
export declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
157
node_modules/fast-equals/dist/cjs/types/internalTypes.d.ts
generated
vendored
Normal file
157
node_modules/fast-equals/dist/cjs/types/internalTypes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators: Record<string, TypeEqualityComparator<any, Meta>> | undefined;
|
||||
}
|
||||
export type CreateCustomComparatorConfig<Meta> = (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
export type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
||||
export type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
export type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray = Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (compare: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
28
node_modules/fast-equals/dist/cjs/types/utils.d.ts
generated
vendored
Normal file
28
node_modules/fast-equals/dist/cjs/types/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { AnyEqualityComparator, Dictionary, State, TypeEqualityComparator } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
export declare function combineComparators<Meta>(comparatorA: AnyEqualityComparator<Meta>, comparatorB: AnyEqualityComparator<Meta>): <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
export declare function createIsCircular<AreItemsEqual extends TypeEqualityComparator<any, any>>(areItemsEqual: AreItemsEqual): AreItemsEqual;
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
export declare function getShortTag(value: any): string | undefined;
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
export declare function getStrictProperties(object: Dictionary): Array<string | symbol>;
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
export declare const hasOwn: (o: object, v: PropertyKey) => boolean;
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export declare function sameValueZeroEqual(a: any, b: any): boolean;
|
||||
627
node_modules/fast-equals/dist/esm/index.mjs
generated
vendored
Normal file
627
node_modules/fast-equals/dist/esm/index.mjs
generated
vendored
Normal file
@@ -0,0 +1,627 @@
|
||||
var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
function combineComparators(comparatorA, comparatorB) {
|
||||
return function isEqual(a, b, state) {
|
||||
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
function createIsCircular(areItemsEqual) {
|
||||
return function isCircular(a, b, state) {
|
||||
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
||||
return areItemsEqual(a, b, state);
|
||||
}
|
||||
var cache = state.cache;
|
||||
var cachedA = cache.get(a);
|
||||
var cachedB = cache.get(b);
|
||||
if (cachedA && cachedB) {
|
||||
return cachedA === b && cachedB === a;
|
||||
}
|
||||
cache.set(a, b);
|
||||
cache.set(b, a);
|
||||
var result = areItemsEqual(a, b, state);
|
||||
cache.delete(a);
|
||||
cache.delete(b);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
function getShortTag(value) {
|
||||
return value != null ? value[Symbol.toStringTag] : undefined;
|
||||
}
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
function getStrictProperties(object) {
|
||||
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
||||
}
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
var hasOwn = Object.hasOwn ||
|
||||
(function (object, property) {
|
||||
return hasOwnProperty.call(object, property);
|
||||
});
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
function sameValueZeroEqual(a, b) {
|
||||
return a === b || (!a && !b && a !== a && b !== b);
|
||||
}
|
||||
|
||||
var PREACT_VNODE = '__v';
|
||||
var PREACT_OWNER = '__o';
|
||||
var REACT_OWNER = '_owner';
|
||||
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
function areArraysEqual(a, b, state) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
function areDatesEqual(a, b) {
|
||||
return sameValueZeroEqual(a.getTime(), b.getTime());
|
||||
}
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
function areErrorsEqual(a, b) {
|
||||
return (a.name === b.name &&
|
||||
a.message === b.message &&
|
||||
a.cause === b.cause &&
|
||||
a.stack === b.stack);
|
||||
}
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
function areFunctionsEqual(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
function areMapsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.entries();
|
||||
var aResult;
|
||||
var bResult;
|
||||
var index = 0;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.entries();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (matchedIndices[matchIndex]) {
|
||||
matchIndex++;
|
||||
continue;
|
||||
}
|
||||
var aEntry = aResult.value;
|
||||
var bEntry = bResult.value;
|
||||
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) &&
|
||||
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
var areNumbersEqual = sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
function areObjectsEqual(a, b, state) {
|
||||
var properties = keys(a);
|
||||
var index = properties.length;
|
||||
if (keys(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
if (!isPropertyEqual(a, b, state, properties[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
function areObjectsEqualStrict(a, b, state) {
|
||||
var properties = getStrictProperties(a);
|
||||
var index = properties.length;
|
||||
if (getStrictProperties(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
var property;
|
||||
var descriptorA;
|
||||
var descriptorB;
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
property = properties[index];
|
||||
if (!isPropertyEqual(a, b, state, property)) {
|
||||
return false;
|
||||
}
|
||||
descriptorA = getOwnPropertyDescriptor(a, property);
|
||||
descriptorB = getOwnPropertyDescriptor(b, property);
|
||||
if ((descriptorA || descriptorB) &&
|
||||
(!descriptorA ||
|
||||
!descriptorB ||
|
||||
descriptorA.configurable !== descriptorB.configurable ||
|
||||
descriptorA.enumerable !== descriptorB.enumerable ||
|
||||
descriptorA.writable !== descriptorB.writable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
function arePrimitiveWrappersEqual(a, b) {
|
||||
return sameValueZeroEqual(a.valueOf(), b.valueOf());
|
||||
}
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
function areRegExpsEqual(a, b) {
|
||||
return a.source === b.source && a.flags === b.flags;
|
||||
}
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
function areSetsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.values();
|
||||
var aResult;
|
||||
var bResult;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.values();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (!matchedIndices[matchIndex] &&
|
||||
state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
function areTypedArraysEqual(a, b) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (a[index] !== b[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
function areUrlsEqual(a, b) {
|
||||
return (a.hostname === b.hostname &&
|
||||
a.pathname === b.pathname &&
|
||||
a.protocol === b.protocol &&
|
||||
a.port === b.port &&
|
||||
a.hash === b.hash &&
|
||||
a.username === b.username &&
|
||||
a.password === b.password);
|
||||
}
|
||||
function isPropertyEqual(a, b, state, property) {
|
||||
if ((property === REACT_OWNER ||
|
||||
property === PREACT_OWNER ||
|
||||
property === PREACT_VNODE) &&
|
||||
(a.$$typeof || b.$$typeof)) {
|
||||
return true;
|
||||
}
|
||||
return (hasOwn(b, property) &&
|
||||
state.equals(a[property], b[property], property, property, a, b, state));
|
||||
}
|
||||
|
||||
var ARGUMENTS_TAG = '[object Arguments]';
|
||||
var BOOLEAN_TAG = '[object Boolean]';
|
||||
var DATE_TAG = '[object Date]';
|
||||
var ERROR_TAG = '[object Error]';
|
||||
var MAP_TAG = '[object Map]';
|
||||
var NUMBER_TAG = '[object Number]';
|
||||
var OBJECT_TAG = '[object Object]';
|
||||
var REG_EXP_TAG = '[object RegExp]';
|
||||
var SET_TAG = '[object Set]';
|
||||
var STRING_TAG = '[object String]';
|
||||
var URL_TAG = '[object URL]';
|
||||
var isArray = Array.isArray;
|
||||
var isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView
|
||||
? ArrayBuffer.isView
|
||||
: null;
|
||||
var assign = Object.assign;
|
||||
var getTag = Object.prototype.toString.call.bind(Object.prototype.toString);
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
function createEqualityComparator(_a) {
|
||||
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;
|
||||
/**
|
||||
* compare the value of the two objects and return true if they are equivalent in values
|
||||
*/
|
||||
return function comparator(a, b, state) {
|
||||
// If the items are strictly equal, no need to do a value comparison.
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
// If either of the items are nullish and fail the strictly equal check
|
||||
// above, then they must be unequal.
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
var type = typeof a;
|
||||
if (type !== typeof b) {
|
||||
return false;
|
||||
}
|
||||
if (type !== 'object') {
|
||||
if (type === 'number') {
|
||||
return areNumbersEqual(a, b, state);
|
||||
}
|
||||
if (type === 'function') {
|
||||
return areFunctionsEqual(a, b, state);
|
||||
}
|
||||
// If a primitive value that is not strictly equal, it must be unequal.
|
||||
return false;
|
||||
}
|
||||
var constructor = a.constructor;
|
||||
// Checks are listed in order of commonality of use-case:
|
||||
// 1. Common complex object types (plain object, array)
|
||||
// 2. Common data values (date, regexp)
|
||||
// 3. Less-common complex object types (map, set)
|
||||
// 4. Less-common data values (promise, primitive wrappers)
|
||||
// Inherently this is both subjective and assumptive, however
|
||||
// when reviewing comparable libraries in the wild this order
|
||||
// appears to be generally consistent.
|
||||
// Constructors should match, otherwise there is potential for false positives
|
||||
// between class and subclass or custom object and POJO.
|
||||
if (constructor !== b.constructor) {
|
||||
return false;
|
||||
}
|
||||
// `isPlainObject` only checks against the object's own realm. Cross-realm
|
||||
// comparisons are rare, and will be handled in the ultimate fallback, so
|
||||
// we can avoid capturing the string tag.
|
||||
if (constructor === Object) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
||||
// the string tag or doing an `instanceof` check.
|
||||
if (isArray(a)) {
|
||||
return areArraysEqual(a, b, state);
|
||||
}
|
||||
// `isTypedArray()` works on all possible TypedArray classes, so we can avoid
|
||||
// capturing the string tag or comparing against all possible constructors.
|
||||
if (isTypedArray != null && isTypedArray(a)) {
|
||||
return areTypedArraysEqual(a, b, state);
|
||||
}
|
||||
// Try to fast-path equality checks for other complex object types in the
|
||||
// same realm to avoid capturing the string tag. Strict equality is used
|
||||
// instead of `instanceof` because it is more performant for the common
|
||||
// use-case. If someone is subclassing a native class, it will be handled
|
||||
// with the string tag comparison.
|
||||
if (constructor === Date) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
if (constructor === RegExp) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Map) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Set) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
// Since this is a custom object, capture the string tag to determing its type.
|
||||
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
||||
var tag = getTag(a);
|
||||
if (tag === DATE_TAG) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
||||
// tested like a standard object.
|
||||
if (tag === REG_EXP_TAG) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (tag === MAP_TAG) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (tag === SET_TAG) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
if (tag === OBJECT_TAG) {
|
||||
// The exception for value comparison is custom `Promise`-like class instances. These should
|
||||
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
||||
// it reaches this point then that strict equality comparison has already failed.
|
||||
return (typeof a.then !== 'function' &&
|
||||
typeof b.then !== 'function' &&
|
||||
areObjectsEqual(a, b, state));
|
||||
}
|
||||
// If a URL tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === URL_TAG) {
|
||||
return areUrlsEqual(a, b, state);
|
||||
}
|
||||
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === ERROR_TAG) {
|
||||
return areErrorsEqual(a, b, state);
|
||||
}
|
||||
// If an arguments tag, it should be treated as a standard object.
|
||||
if (tag === ARGUMENTS_TAG) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// As the penultimate fallback, check if the values passed are primitive wrappers. This
|
||||
// is very rare in modern JS, which is why it is deprioritized compared to all other object
|
||||
// types.
|
||||
if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {
|
||||
return arePrimitiveWrappersEqual(a, b, state);
|
||||
}
|
||||
if (unknownTagComparators) {
|
||||
var unknownTagComparator = unknownTagComparators[tag];
|
||||
if (!unknownTagComparator) {
|
||||
var shortTag = getShortTag(a);
|
||||
if (shortTag) {
|
||||
unknownTagComparator = unknownTagComparators[shortTag];
|
||||
}
|
||||
}
|
||||
// If the custom config has an unknown tag comparator that matches the captured tag or the
|
||||
// @@toStringTag, it is the source of truth for whether the values are equal.
|
||||
if (unknownTagComparator) {
|
||||
return unknownTagComparator(a, b, state);
|
||||
}
|
||||
}
|
||||
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
||||
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
||||
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
||||
// comparison that can be made.
|
||||
// - For types that can be introspected, but rarely have requirements to be compared
|
||||
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
||||
// use-cases (may be included in a future release, if requested enough).
|
||||
// - For types that can be introspected but do not have an objective definition of what
|
||||
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
||||
// In all cases, these decisions should be reevaluated based on changes to the language and
|
||||
// common development practices.
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
function createEqualityComparatorConfig(_a) {
|
||||
var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;
|
||||
var config = {
|
||||
areArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areArraysEqual,
|
||||
areDatesEqual: areDatesEqual,
|
||||
areErrorsEqual: areErrorsEqual,
|
||||
areFunctionsEqual: areFunctionsEqual,
|
||||
areMapsEqual: strict
|
||||
? combineComparators(areMapsEqual, areObjectsEqualStrict)
|
||||
: areMapsEqual,
|
||||
areNumbersEqual: areNumbersEqual,
|
||||
areObjectsEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areObjectsEqual,
|
||||
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
||||
areRegExpsEqual: areRegExpsEqual,
|
||||
areSetsEqual: strict
|
||||
? combineComparators(areSetsEqual, areObjectsEqualStrict)
|
||||
: areSetsEqual,
|
||||
areTypedArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areTypedArraysEqual,
|
||||
areUrlsEqual: areUrlsEqual,
|
||||
unknownTagComparators: undefined,
|
||||
};
|
||||
if (createCustomConfig) {
|
||||
config = assign({}, config, createCustomConfig(config));
|
||||
}
|
||||
if (circular) {
|
||||
var areArraysEqual$1 = createIsCircular(config.areArraysEqual);
|
||||
var areMapsEqual$1 = createIsCircular(config.areMapsEqual);
|
||||
var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);
|
||||
var areSetsEqual$1 = createIsCircular(config.areSetsEqual);
|
||||
config = assign({}, config, {
|
||||
areArraysEqual: areArraysEqual$1,
|
||||
areMapsEqual: areMapsEqual$1,
|
||||
areObjectsEqual: areObjectsEqual$1,
|
||||
areSetsEqual: areSetsEqual$1,
|
||||
});
|
||||
}
|
||||
return config;
|
||||
}
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
function createInternalEqualityComparator(compare) {
|
||||
return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
|
||||
return compare(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
function createIsEqual(_a) {
|
||||
var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;
|
||||
if (createState) {
|
||||
return function isEqual(a, b) {
|
||||
var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;
|
||||
return comparator(a, b, {
|
||||
cache: cache,
|
||||
equals: equals,
|
||||
meta: meta,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (circular) {
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, {
|
||||
cache: new WeakMap(),
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
var state = {
|
||||
cache: undefined,
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
};
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, state);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
var deepEqual = createCustomEqual();
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
var strictDeepEqual = createCustomEqual({ strict: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
var circularDeepEqual = createCustomEqual({ circular: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularDeepEqual = createCustomEqual({
|
||||
circular: true,
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
var shallowEqual = createCustomEqual({
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
var strictShallowEqual = createCustomEqual({
|
||||
strict: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
var circularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
function createCustomEqual(options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;
|
||||
var config = createEqualityComparatorConfig(options);
|
||||
var comparator = createEqualityComparator(config);
|
||||
var equals = createCustomInternalComparator
|
||||
? createCustomInternalComparator(comparator)
|
||||
: createInternalEqualityComparator(comparator);
|
||||
return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });
|
||||
}
|
||||
|
||||
export { circularDeepEqual, circularShallowEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual, strictCircularDeepEqual, strictCircularShallowEqual, strictDeepEqual, strictShallowEqual };
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
1
node_modules/fast-equals/dist/esm/index.mjs.map
generated
vendored
Normal file
1
node_modules/fast-equals/dist/esm/index.mjs.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/fast-equals/dist/esm/types/comparator.d.ts
generated
vendored
Normal file
26
node_modules/fast-equals/dist/esm/types/comparator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ComparatorConfig, CreateState, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator } from './internalTypes.d.ts';
|
||||
interface CreateIsEqualOptions<Meta> {
|
||||
circular: boolean;
|
||||
comparator: EqualityComparator<Meta>;
|
||||
createState: CreateState<Meta> | undefined;
|
||||
equals: InternalEqualityComparator<Meta>;
|
||||
strict: boolean;
|
||||
}
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
export declare function createEqualityComparator<Meta>({ areArraysEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators, }: ComparatorConfig<Meta>): EqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
export declare function createEqualityComparatorConfig<Meta>({ circular, createCustomConfig, strict, }: CustomEqualCreatorOptions<Meta>): ComparatorConfig<Meta>;
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
export declare function createInternalEqualityComparator<Meta>(compare: EqualityComparator<Meta>): InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
export declare function createIsEqual<Meta>({ circular, comparator, createState, equals, strict, }: CreateIsEqualOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
export {};
|
||||
54
node_modules/fast-equals/dist/esm/types/equals.d.ts
generated
vendored
Normal file
54
node_modules/fast-equals/dist/esm/types/equals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
import type { Dictionary, PrimitiveWrapper, State, TypedArray } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
export declare function areArraysEqual(a: any[], b: any[], state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
export declare function areDatesEqual(a: Date, b: Date): boolean;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
export declare function areErrorsEqual(a: Error, b: Error): boolean;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
export declare function areFunctionsEqual(a: (...args: any[]) => any, b: (...args: any[]) => any): boolean;
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
export declare function areMapsEqual(a: Map<any, any>, b: Map<any, any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
export declare const areNumbersEqual: typeof sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
export declare function areObjectsEqual(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
export declare function areObjectsEqualStrict(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
export declare function arePrimitiveWrappersEqual(a: PrimitiveWrapper, b: PrimitiveWrapper): boolean;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
export declare function areRegExpsEqual(a: RegExp, b: RegExp): boolean;
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
export declare function areSetsEqual(a: Set<any>, b: Set<any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
export declare function areTypedArraysEqual(a: TypedArray, b: TypedArray): boolean;
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
export declare function areUrlsEqual(a: URL, b: URL): boolean;
|
||||
47
node_modules/fast-equals/dist/esm/types/index.d.ts
generated
vendored
Normal file
47
node_modules/fast-equals/dist/esm/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { CustomEqualCreatorOptions } from './internalTypes.d.ts';
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
export { sameValueZeroEqual };
|
||||
export type { AnyEqualityComparator, Cache, CircularState, ComparatorConfig, CreateCustomComparatorConfig, CreateState, CustomEqualCreatorOptions, DefaultState, Dictionary, EqualityComparator, EqualityComparatorCreator, InternalEqualityComparator, PrimitiveWrapper, State, TypeEqualityComparator, TypedArray, } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export declare const deepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export declare const strictDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export declare const shallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export declare const strictShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
export declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
157
node_modules/fast-equals/dist/esm/types/internalTypes.d.ts
generated
vendored
Normal file
157
node_modules/fast-equals/dist/esm/types/internalTypes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators: Record<string, TypeEqualityComparator<any, Meta>> | undefined;
|
||||
}
|
||||
export type CreateCustomComparatorConfig<Meta> = (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
export type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
||||
export type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
export type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray = Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (compare: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
28
node_modules/fast-equals/dist/esm/types/utils.d.ts
generated
vendored
Normal file
28
node_modules/fast-equals/dist/esm/types/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { AnyEqualityComparator, Dictionary, State, TypeEqualityComparator } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
export declare function combineComparators<Meta>(comparatorA: AnyEqualityComparator<Meta>, comparatorB: AnyEqualityComparator<Meta>): <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
export declare function createIsCircular<AreItemsEqual extends TypeEqualityComparator<any, any>>(areItemsEqual: AreItemsEqual): AreItemsEqual;
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
export declare function getShortTag(value: any): string | undefined;
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
export declare function getStrictProperties(object: Dictionary): Array<string | symbol>;
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
export declare const hasOwn: (o: object, v: PropertyKey) => boolean;
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export declare function sameValueZeroEqual(a: any, b: any): boolean;
|
||||
1
node_modules/fast-equals/dist/min/index.js
generated
vendored
Normal file
1
node_modules/fast-equals/dist/min/index.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/fast-equals/dist/min/types/comparator.d.ts
generated
vendored
Normal file
26
node_modules/fast-equals/dist/min/types/comparator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ComparatorConfig, CreateState, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator } from './internalTypes.d.ts';
|
||||
interface CreateIsEqualOptions<Meta> {
|
||||
circular: boolean;
|
||||
comparator: EqualityComparator<Meta>;
|
||||
createState: CreateState<Meta> | undefined;
|
||||
equals: InternalEqualityComparator<Meta>;
|
||||
strict: boolean;
|
||||
}
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
export declare function createEqualityComparator<Meta>({ areArraysEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators, }: ComparatorConfig<Meta>): EqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
export declare function createEqualityComparatorConfig<Meta>({ circular, createCustomConfig, strict, }: CustomEqualCreatorOptions<Meta>): ComparatorConfig<Meta>;
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
export declare function createInternalEqualityComparator<Meta>(compare: EqualityComparator<Meta>): InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
export declare function createIsEqual<Meta>({ circular, comparator, createState, equals, strict, }: CreateIsEqualOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
export {};
|
||||
54
node_modules/fast-equals/dist/min/types/equals.d.ts
generated
vendored
Normal file
54
node_modules/fast-equals/dist/min/types/equals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
import type { Dictionary, PrimitiveWrapper, State, TypedArray } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
export declare function areArraysEqual(a: any[], b: any[], state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
export declare function areDatesEqual(a: Date, b: Date): boolean;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
export declare function areErrorsEqual(a: Error, b: Error): boolean;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
export declare function areFunctionsEqual(a: (...args: any[]) => any, b: (...args: any[]) => any): boolean;
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
export declare function areMapsEqual(a: Map<any, any>, b: Map<any, any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
export declare const areNumbersEqual: typeof sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
export declare function areObjectsEqual(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
export declare function areObjectsEqualStrict(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
export declare function arePrimitiveWrappersEqual(a: PrimitiveWrapper, b: PrimitiveWrapper): boolean;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
export declare function areRegExpsEqual(a: RegExp, b: RegExp): boolean;
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
export declare function areSetsEqual(a: Set<any>, b: Set<any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
export declare function areTypedArraysEqual(a: TypedArray, b: TypedArray): boolean;
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
export declare function areUrlsEqual(a: URL, b: URL): boolean;
|
||||
47
node_modules/fast-equals/dist/min/types/index.d.ts
generated
vendored
Normal file
47
node_modules/fast-equals/dist/min/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { CustomEqualCreatorOptions } from './internalTypes.d.ts';
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
export { sameValueZeroEqual };
|
||||
export type { AnyEqualityComparator, Cache, CircularState, ComparatorConfig, CreateCustomComparatorConfig, CreateState, CustomEqualCreatorOptions, DefaultState, Dictionary, EqualityComparator, EqualityComparatorCreator, InternalEqualityComparator, PrimitiveWrapper, State, TypeEqualityComparator, TypedArray, } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export declare const deepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export declare const strictDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export declare const shallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export declare const strictShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
export declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
157
node_modules/fast-equals/dist/min/types/internalTypes.d.ts
generated
vendored
Normal file
157
node_modules/fast-equals/dist/min/types/internalTypes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators: Record<string, TypeEqualityComparator<any, Meta>> | undefined;
|
||||
}
|
||||
export type CreateCustomComparatorConfig<Meta> = (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
export type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
||||
export type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
export type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray = Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (compare: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
28
node_modules/fast-equals/dist/min/types/utils.d.ts
generated
vendored
Normal file
28
node_modules/fast-equals/dist/min/types/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { AnyEqualityComparator, Dictionary, State, TypeEqualityComparator } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
export declare function combineComparators<Meta>(comparatorA: AnyEqualityComparator<Meta>, comparatorB: AnyEqualityComparator<Meta>): <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
export declare function createIsCircular<AreItemsEqual extends TypeEqualityComparator<any, any>>(areItemsEqual: AreItemsEqual): AreItemsEqual;
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
export declare function getShortTag(value: any): string | undefined;
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
export declare function getStrictProperties(object: Dictionary): Array<string | symbol>;
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
export declare const hasOwn: (o: object, v: PropertyKey) => boolean;
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export declare function sameValueZeroEqual(a: any, b: any): boolean;
|
||||
644
node_modules/fast-equals/dist/umd/index.js
generated
vendored
Normal file
644
node_modules/fast-equals/dist/umd/index.js
generated
vendored
Normal file
@@ -0,0 +1,644 @@
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["fast-equals"] = {}));
|
||||
})(this, (function (exports) { 'use strict';
|
||||
|
||||
var getOwnPropertyNames = Object.getOwnPropertyNames, getOwnPropertySymbols = Object.getOwnPropertySymbols;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
function combineComparators(comparatorA, comparatorB) {
|
||||
return function isEqual(a, b, state) {
|
||||
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
function createIsCircular(areItemsEqual) {
|
||||
return function isCircular(a, b, state) {
|
||||
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
||||
return areItemsEqual(a, b, state);
|
||||
}
|
||||
var cache = state.cache;
|
||||
var cachedA = cache.get(a);
|
||||
var cachedB = cache.get(b);
|
||||
if (cachedA && cachedB) {
|
||||
return cachedA === b && cachedB === a;
|
||||
}
|
||||
cache.set(a, b);
|
||||
cache.set(b, a);
|
||||
var result = areItemsEqual(a, b, state);
|
||||
cache.delete(a);
|
||||
cache.delete(b);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
function getShortTag(value) {
|
||||
return value != null ? value[Symbol.toStringTag] : undefined;
|
||||
}
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
function getStrictProperties(object) {
|
||||
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
||||
}
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
var hasOwn = Object.hasOwn ||
|
||||
(function (object, property) {
|
||||
return hasOwnProperty.call(object, property);
|
||||
});
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
function sameValueZeroEqual(a, b) {
|
||||
return a === b || (!a && !b && a !== a && b !== b);
|
||||
}
|
||||
|
||||
var PREACT_VNODE = '__v';
|
||||
var PREACT_OWNER = '__o';
|
||||
var REACT_OWNER = '_owner';
|
||||
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor, keys = Object.keys;
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
function areArraysEqual(a, b, state) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
function areDatesEqual(a, b) {
|
||||
return sameValueZeroEqual(a.getTime(), b.getTime());
|
||||
}
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
function areErrorsEqual(a, b) {
|
||||
return (a.name === b.name &&
|
||||
a.message === b.message &&
|
||||
a.cause === b.cause &&
|
||||
a.stack === b.stack);
|
||||
}
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
function areFunctionsEqual(a, b) {
|
||||
return a === b;
|
||||
}
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
function areMapsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.entries();
|
||||
var aResult;
|
||||
var bResult;
|
||||
var index = 0;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.entries();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (matchedIndices[matchIndex]) {
|
||||
matchIndex++;
|
||||
continue;
|
||||
}
|
||||
var aEntry = aResult.value;
|
||||
var bEntry = bResult.value;
|
||||
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) &&
|
||||
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
var areNumbersEqual = sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
function areObjectsEqual(a, b, state) {
|
||||
var properties = keys(a);
|
||||
var index = properties.length;
|
||||
if (keys(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
if (!isPropertyEqual(a, b, state, properties[index])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
function areObjectsEqualStrict(a, b, state) {
|
||||
var properties = getStrictProperties(a);
|
||||
var index = properties.length;
|
||||
if (getStrictProperties(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
var property;
|
||||
var descriptorA;
|
||||
var descriptorB;
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
property = properties[index];
|
||||
if (!isPropertyEqual(a, b, state, property)) {
|
||||
return false;
|
||||
}
|
||||
descriptorA = getOwnPropertyDescriptor(a, property);
|
||||
descriptorB = getOwnPropertyDescriptor(b, property);
|
||||
if ((descriptorA || descriptorB) &&
|
||||
(!descriptorA ||
|
||||
!descriptorB ||
|
||||
descriptorA.configurable !== descriptorB.configurable ||
|
||||
descriptorA.enumerable !== descriptorB.enumerable ||
|
||||
descriptorA.writable !== descriptorB.writable)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
function arePrimitiveWrappersEqual(a, b) {
|
||||
return sameValueZeroEqual(a.valueOf(), b.valueOf());
|
||||
}
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
function areRegExpsEqual(a, b) {
|
||||
return a.source === b.source && a.flags === b.flags;
|
||||
}
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
function areSetsEqual(a, b, state) {
|
||||
var size = a.size;
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
var matchedIndices = new Array(size);
|
||||
var aIterable = a.values();
|
||||
var aResult;
|
||||
var bResult;
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
var bIterable = b.values();
|
||||
var hasMatch = false;
|
||||
var matchIndex = 0;
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
if (!matchedIndices[matchIndex] &&
|
||||
state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
matchIndex++;
|
||||
}
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
function areTypedArraysEqual(a, b) {
|
||||
var index = a.length;
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
while (index-- > 0) {
|
||||
if (a[index] !== b[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
function areUrlsEqual(a, b) {
|
||||
return (a.hostname === b.hostname &&
|
||||
a.pathname === b.pathname &&
|
||||
a.protocol === b.protocol &&
|
||||
a.port === b.port &&
|
||||
a.hash === b.hash &&
|
||||
a.username === b.username &&
|
||||
a.password === b.password);
|
||||
}
|
||||
function isPropertyEqual(a, b, state, property) {
|
||||
if ((property === REACT_OWNER ||
|
||||
property === PREACT_OWNER ||
|
||||
property === PREACT_VNODE) &&
|
||||
(a.$$typeof || b.$$typeof)) {
|
||||
return true;
|
||||
}
|
||||
return (hasOwn(b, property) &&
|
||||
state.equals(a[property], b[property], property, property, a, b, state));
|
||||
}
|
||||
|
||||
var ARGUMENTS_TAG = '[object Arguments]';
|
||||
var BOOLEAN_TAG = '[object Boolean]';
|
||||
var DATE_TAG = '[object Date]';
|
||||
var ERROR_TAG = '[object Error]';
|
||||
var MAP_TAG = '[object Map]';
|
||||
var NUMBER_TAG = '[object Number]';
|
||||
var OBJECT_TAG = '[object Object]';
|
||||
var REG_EXP_TAG = '[object RegExp]';
|
||||
var SET_TAG = '[object Set]';
|
||||
var STRING_TAG = '[object String]';
|
||||
var URL_TAG = '[object URL]';
|
||||
var isArray = Array.isArray;
|
||||
var isTypedArray = typeof ArrayBuffer === 'function' && ArrayBuffer.isView
|
||||
? ArrayBuffer.isView
|
||||
: null;
|
||||
var assign = Object.assign;
|
||||
var getTag = Object.prototype.toString.call.bind(Object.prototype.toString);
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
function createEqualityComparator(_a) {
|
||||
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;
|
||||
/**
|
||||
* compare the value of the two objects and return true if they are equivalent in values
|
||||
*/
|
||||
return function comparator(a, b, state) {
|
||||
// If the items are strictly equal, no need to do a value comparison.
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
// If either of the items are nullish and fail the strictly equal check
|
||||
// above, then they must be unequal.
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
var type = typeof a;
|
||||
if (type !== typeof b) {
|
||||
return false;
|
||||
}
|
||||
if (type !== 'object') {
|
||||
if (type === 'number') {
|
||||
return areNumbersEqual(a, b, state);
|
||||
}
|
||||
if (type === 'function') {
|
||||
return areFunctionsEqual(a, b, state);
|
||||
}
|
||||
// If a primitive value that is not strictly equal, it must be unequal.
|
||||
return false;
|
||||
}
|
||||
var constructor = a.constructor;
|
||||
// Checks are listed in order of commonality of use-case:
|
||||
// 1. Common complex object types (plain object, array)
|
||||
// 2. Common data values (date, regexp)
|
||||
// 3. Less-common complex object types (map, set)
|
||||
// 4. Less-common data values (promise, primitive wrappers)
|
||||
// Inherently this is both subjective and assumptive, however
|
||||
// when reviewing comparable libraries in the wild this order
|
||||
// appears to be generally consistent.
|
||||
// Constructors should match, otherwise there is potential for false positives
|
||||
// between class and subclass or custom object and POJO.
|
||||
if (constructor !== b.constructor) {
|
||||
return false;
|
||||
}
|
||||
// `isPlainObject` only checks against the object's own realm. Cross-realm
|
||||
// comparisons are rare, and will be handled in the ultimate fallback, so
|
||||
// we can avoid capturing the string tag.
|
||||
if (constructor === Object) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
||||
// the string tag or doing an `instanceof` check.
|
||||
if (isArray(a)) {
|
||||
return areArraysEqual(a, b, state);
|
||||
}
|
||||
// `isTypedArray()` works on all possible TypedArray classes, so we can avoid
|
||||
// capturing the string tag or comparing against all possible constructors.
|
||||
if (isTypedArray != null && isTypedArray(a)) {
|
||||
return areTypedArraysEqual(a, b, state);
|
||||
}
|
||||
// Try to fast-path equality checks for other complex object types in the
|
||||
// same realm to avoid capturing the string tag. Strict equality is used
|
||||
// instead of `instanceof` because it is more performant for the common
|
||||
// use-case. If someone is subclassing a native class, it will be handled
|
||||
// with the string tag comparison.
|
||||
if (constructor === Date) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
if (constructor === RegExp) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Map) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (constructor === Set) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
// Since this is a custom object, capture the string tag to determing its type.
|
||||
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
||||
var tag = getTag(a);
|
||||
if (tag === DATE_TAG) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
||||
// tested like a standard object.
|
||||
if (tag === REG_EXP_TAG) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
if (tag === MAP_TAG) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
if (tag === SET_TAG) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
if (tag === OBJECT_TAG) {
|
||||
// The exception for value comparison is custom `Promise`-like class instances. These should
|
||||
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
||||
// it reaches this point then that strict equality comparison has already failed.
|
||||
return (typeof a.then !== 'function' &&
|
||||
typeof b.then !== 'function' &&
|
||||
areObjectsEqual(a, b, state));
|
||||
}
|
||||
// If a URL tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === URL_TAG) {
|
||||
return areUrlsEqual(a, b, state);
|
||||
}
|
||||
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === ERROR_TAG) {
|
||||
return areErrorsEqual(a, b, state);
|
||||
}
|
||||
// If an arguments tag, it should be treated as a standard object.
|
||||
if (tag === ARGUMENTS_TAG) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
// As the penultimate fallback, check if the values passed are primitive wrappers. This
|
||||
// is very rare in modern JS, which is why it is deprioritized compared to all other object
|
||||
// types.
|
||||
if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {
|
||||
return arePrimitiveWrappersEqual(a, b, state);
|
||||
}
|
||||
if (unknownTagComparators) {
|
||||
var unknownTagComparator = unknownTagComparators[tag];
|
||||
if (!unknownTagComparator) {
|
||||
var shortTag = getShortTag(a);
|
||||
if (shortTag) {
|
||||
unknownTagComparator = unknownTagComparators[shortTag];
|
||||
}
|
||||
}
|
||||
// If the custom config has an unknown tag comparator that matches the captured tag or the
|
||||
// @@toStringTag, it is the source of truth for whether the values are equal.
|
||||
if (unknownTagComparator) {
|
||||
return unknownTagComparator(a, b, state);
|
||||
}
|
||||
}
|
||||
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
||||
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
||||
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
||||
// comparison that can be made.
|
||||
// - For types that can be introspected, but rarely have requirements to be compared
|
||||
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
||||
// use-cases (may be included in a future release, if requested enough).
|
||||
// - For types that can be introspected but do not have an objective definition of what
|
||||
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
||||
// In all cases, these decisions should be reevaluated based on changes to the language and
|
||||
// common development practices.
|
||||
return false;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
function createEqualityComparatorConfig(_a) {
|
||||
var circular = _a.circular, createCustomConfig = _a.createCustomConfig, strict = _a.strict;
|
||||
var config = {
|
||||
areArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areArraysEqual,
|
||||
areDatesEqual: areDatesEqual,
|
||||
areErrorsEqual: areErrorsEqual,
|
||||
areFunctionsEqual: areFunctionsEqual,
|
||||
areMapsEqual: strict
|
||||
? combineComparators(areMapsEqual, areObjectsEqualStrict)
|
||||
: areMapsEqual,
|
||||
areNumbersEqual: areNumbersEqual,
|
||||
areObjectsEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areObjectsEqual,
|
||||
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
||||
areRegExpsEqual: areRegExpsEqual,
|
||||
areSetsEqual: strict
|
||||
? combineComparators(areSetsEqual, areObjectsEqualStrict)
|
||||
: areSetsEqual,
|
||||
areTypedArraysEqual: strict
|
||||
? areObjectsEqualStrict
|
||||
: areTypedArraysEqual,
|
||||
areUrlsEqual: areUrlsEqual,
|
||||
unknownTagComparators: undefined,
|
||||
};
|
||||
if (createCustomConfig) {
|
||||
config = assign({}, config, createCustomConfig(config));
|
||||
}
|
||||
if (circular) {
|
||||
var areArraysEqual$1 = createIsCircular(config.areArraysEqual);
|
||||
var areMapsEqual$1 = createIsCircular(config.areMapsEqual);
|
||||
var areObjectsEqual$1 = createIsCircular(config.areObjectsEqual);
|
||||
var areSetsEqual$1 = createIsCircular(config.areSetsEqual);
|
||||
config = assign({}, config, {
|
||||
areArraysEqual: areArraysEqual$1,
|
||||
areMapsEqual: areMapsEqual$1,
|
||||
areObjectsEqual: areObjectsEqual$1,
|
||||
areSetsEqual: areSetsEqual$1,
|
||||
});
|
||||
}
|
||||
return config;
|
||||
}
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
function createInternalEqualityComparator(compare) {
|
||||
return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
|
||||
return compare(a, b, state);
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
function createIsEqual(_a) {
|
||||
var circular = _a.circular, comparator = _a.comparator, createState = _a.createState, equals = _a.equals, strict = _a.strict;
|
||||
if (createState) {
|
||||
return function isEqual(a, b) {
|
||||
var _a = createState(), _b = _a.cache, cache = _b === void 0 ? circular ? new WeakMap() : undefined : _b, meta = _a.meta;
|
||||
return comparator(a, b, {
|
||||
cache: cache,
|
||||
equals: equals,
|
||||
meta: meta,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
if (circular) {
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, {
|
||||
cache: new WeakMap(),
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
});
|
||||
};
|
||||
}
|
||||
var state = {
|
||||
cache: undefined,
|
||||
equals: equals,
|
||||
meta: undefined,
|
||||
strict: strict,
|
||||
};
|
||||
return function isEqual(a, b) {
|
||||
return comparator(a, b, state);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
var deepEqual = createCustomEqual();
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
var strictDeepEqual = createCustomEqual({ strict: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
var circularDeepEqual = createCustomEqual({ circular: true });
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularDeepEqual = createCustomEqual({
|
||||
circular: true,
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
var shallowEqual = createCustomEqual({
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
var strictShallowEqual = createCustomEqual({
|
||||
strict: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
var circularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
});
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
var strictCircularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: function () { return sameValueZeroEqual; },
|
||||
strict: true,
|
||||
});
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
function createCustomEqual(options) {
|
||||
if (options === void 0) { options = {}; }
|
||||
var _a = options.circular, circular = _a === void 0 ? false : _a, createCustomInternalComparator = options.createInternalComparator, createState = options.createState, _b = options.strict, strict = _b === void 0 ? false : _b;
|
||||
var config = createEqualityComparatorConfig(options);
|
||||
var comparator = createEqualityComparator(config);
|
||||
var equals = createCustomInternalComparator
|
||||
? createCustomInternalComparator(comparator)
|
||||
: createInternalEqualityComparator(comparator);
|
||||
return createIsEqual({ circular: circular, comparator: comparator, createState: createState, equals: equals, strict: strict });
|
||||
}
|
||||
|
||||
exports.circularDeepEqual = circularDeepEqual;
|
||||
exports.circularShallowEqual = circularShallowEqual;
|
||||
exports.createCustomEqual = createCustomEqual;
|
||||
exports.deepEqual = deepEqual;
|
||||
exports.sameValueZeroEqual = sameValueZeroEqual;
|
||||
exports.shallowEqual = shallowEqual;
|
||||
exports.strictCircularDeepEqual = strictCircularDeepEqual;
|
||||
exports.strictCircularShallowEqual = strictCircularShallowEqual;
|
||||
exports.strictDeepEqual = strictDeepEqual;
|
||||
exports.strictShallowEqual = strictShallowEqual;
|
||||
|
||||
}));
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/fast-equals/dist/umd/index.js.map
generated
vendored
Normal file
1
node_modules/fast-equals/dist/umd/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
node_modules/fast-equals/dist/umd/types/comparator.d.ts
generated
vendored
Normal file
26
node_modules/fast-equals/dist/umd/types/comparator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { ComparatorConfig, CreateState, CustomEqualCreatorOptions, EqualityComparator, InternalEqualityComparator } from './internalTypes.d.ts';
|
||||
interface CreateIsEqualOptions<Meta> {
|
||||
circular: boolean;
|
||||
comparator: EqualityComparator<Meta>;
|
||||
createState: CreateState<Meta> | undefined;
|
||||
equals: InternalEqualityComparator<Meta>;
|
||||
strict: boolean;
|
||||
}
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
export declare function createEqualityComparator<Meta>({ areArraysEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, unknownTagComparators, }: ComparatorConfig<Meta>): EqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
export declare function createEqualityComparatorConfig<Meta>({ circular, createCustomConfig, strict, }: CustomEqualCreatorOptions<Meta>): ComparatorConfig<Meta>;
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
export declare function createInternalEqualityComparator<Meta>(compare: EqualityComparator<Meta>): InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
export declare function createIsEqual<Meta>({ circular, comparator, createState, equals, strict, }: CreateIsEqualOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
export {};
|
||||
54
node_modules/fast-equals/dist/umd/types/equals.d.ts
generated
vendored
Normal file
54
node_modules/fast-equals/dist/umd/types/equals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
import type { Dictionary, PrimitiveWrapper, State, TypedArray } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
export declare function areArraysEqual(a: any[], b: any[], state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
export declare function areDatesEqual(a: Date, b: Date): boolean;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
export declare function areErrorsEqual(a: Error, b: Error): boolean;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
export declare function areFunctionsEqual(a: (...args: any[]) => any, b: (...args: any[]) => any): boolean;
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
export declare function areMapsEqual(a: Map<any, any>, b: Map<any, any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
export declare const areNumbersEqual: typeof sameValueZeroEqual;
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
export declare function areObjectsEqual(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
export declare function areObjectsEqualStrict(a: Dictionary, b: Dictionary, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
export declare function arePrimitiveWrappersEqual(a: PrimitiveWrapper, b: PrimitiveWrapper): boolean;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
export declare function areRegExpsEqual(a: RegExp, b: RegExp): boolean;
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
export declare function areSetsEqual(a: Set<any>, b: Set<any>, state: State<any>): boolean;
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
export declare function areTypedArraysEqual(a: TypedArray, b: TypedArray): boolean;
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
export declare function areUrlsEqual(a: URL, b: URL): boolean;
|
||||
47
node_modules/fast-equals/dist/umd/types/index.d.ts
generated
vendored
Normal file
47
node_modules/fast-equals/dist/umd/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { CustomEqualCreatorOptions } from './internalTypes.d.ts';
|
||||
import { sameValueZeroEqual } from './utils.ts';
|
||||
export { sameValueZeroEqual };
|
||||
export type { AnyEqualityComparator, Cache, CircularState, ComparatorConfig, CreateCustomComparatorConfig, CreateState, CustomEqualCreatorOptions, DefaultState, Dictionary, EqualityComparator, EqualityComparatorCreator, InternalEqualityComparator, PrimitiveWrapper, State, TypeEqualityComparator, TypedArray, } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export declare const deepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export declare const strictDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export declare const shallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export declare const strictShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
export declare function createCustomEqual<Meta = undefined>(options?: CustomEqualCreatorOptions<Meta>): <A, B>(a: A, b: B) => boolean;
|
||||
157
node_modules/fast-equals/dist/umd/types/internalTypes.d.ts
generated
vendored
Normal file
157
node_modules/fast-equals/dist/umd/types/internalTypes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators: Record<string, TypeEqualityComparator<any, Meta>> | undefined;
|
||||
}
|
||||
export type CreateCustomComparatorConfig<Meta> = (config: ComparatorConfig<Meta>) => Partial<ComparatorConfig<Meta>>;
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
export type EqualityComparator<Meta> = <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (a: any, b: any, state: State<Meta>) => boolean;
|
||||
export type EqualityComparatorCreator<Meta> = (fn: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
export type InternalEqualityComparator<Meta> = (a: any, b: any, indexOrKeyA: any, indexOrKeyB: any, parentA: any, parentB: any, state: State<Meta>) => boolean;
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray = Float32Array | Float64Array | Int8Array | Int16Array | Int32Array | Uint16Array | Uint32Array | Uint8Array | Uint8ClampedArray;
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (a: Type, b: Type, state: State<Meta>) => boolean;
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (compare: EqualityComparator<Meta>) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
28
node_modules/fast-equals/dist/umd/types/utils.d.ts
generated
vendored
Normal file
28
node_modules/fast-equals/dist/umd/types/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { AnyEqualityComparator, Dictionary, State, TypeEqualityComparator } from './internalTypes.d.ts';
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
export declare function combineComparators<Meta>(comparatorA: AnyEqualityComparator<Meta>, comparatorB: AnyEqualityComparator<Meta>): <A, B>(a: A, b: B, state: State<Meta>) => boolean;
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
export declare function createIsCircular<AreItemsEqual extends TypeEqualityComparator<any, any>>(areItemsEqual: AreItemsEqual): AreItemsEqual;
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
export declare function getShortTag(value: any): string | undefined;
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
export declare function getStrictProperties(object: Dictionary): Array<string | symbol>;
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
export declare const hasOwn: (o: object, v: PropertyKey) => boolean;
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export declare function sameValueZeroEqual(a: any, b: any): boolean;
|
||||
262
node_modules/fast-equals/index.d.ts
generated
vendored
Normal file
262
node_modules/fast-equals/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators:
|
||||
| Record<string, TypeEqualityComparator<any, Meta>>
|
||||
| undefined;
|
||||
}
|
||||
|
||||
export type CreateCustomComparatorConfig<Meta> = (
|
||||
config: ComparatorConfig<Meta>,
|
||||
) => Partial<ComparatorConfig<Meta>>;
|
||||
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
|
||||
export type EqualityComparator<Meta> = <A, B>(
|
||||
a: A,
|
||||
b: B,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (
|
||||
a: any,
|
||||
b: any,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
export type EqualityComparatorCreator<Meta> = (
|
||||
fn: EqualityComparator<Meta>,
|
||||
) => InternalEqualityComparator<Meta>;
|
||||
|
||||
export type InternalEqualityComparator<Meta> = (
|
||||
a: any,
|
||||
b: any,
|
||||
indexOrKeyA: any,
|
||||
indexOrKeyB: any,
|
||||
parentA: any,
|
||||
parentB: any,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
// We explicitly check for primitive wrapper types
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray =
|
||||
| Float32Array
|
||||
| Float64Array
|
||||
| Int8Array
|
||||
| Int16Array
|
||||
| Int32Array
|
||||
| Uint16Array
|
||||
| Uint32Array
|
||||
| Uint8Array
|
||||
| Uint8ClampedArray;
|
||||
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (
|
||||
a: Type,
|
||||
b: Type,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (
|
||||
compare: EqualityComparator<Meta>,
|
||||
) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export declare const sameValueZeroEqual: <A, B>(a: A, b: B) => boolean;
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export declare const deepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export declare const strictDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularDeepEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export declare const shallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export declare const strictShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export declare const circularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export declare const strictCircularShallowEqual: <A, B>(a: A, b: B) => boolean;
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that cannot polyfill for modern features expected by
|
||||
* `fast-equals`, such as `WeakMap` or `RegExp.prototype.flags`.
|
||||
*/
|
||||
export declare function createCustomEqual<Meta = undefined>(
|
||||
options?: CustomEqualCreatorOptions<Meta>,
|
||||
): <A, B>(a: A, b: B) => boolean;
|
||||
123
node_modules/fast-equals/package.json
generated
vendored
Normal file
123
node_modules/fast-equals/package.json
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
{
|
||||
"author": "tony_quetano@planttheidea.com",
|
||||
"browser": "dist/umd/index.js",
|
||||
"bugs": {
|
||||
"url": "https://github.com/planttheidea/fast-equals/issues"
|
||||
},
|
||||
"description": "A blazing fast equality comparison, either shallow or deep",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^24.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.1",
|
||||
"@rollup/plugin-replace": "^5.0.7",
|
||||
"@rollup/plugin-terser": "^0.4.0",
|
||||
"@rollup/plugin-typescript": "^11.1.6",
|
||||
"@types/jest": "^29.5.0",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@types/node": "^18.19.69",
|
||||
"@types/ramda": "^0.28.25",
|
||||
"@types/react": "^18.3.18",
|
||||
"@types/react-dom": "^18.3.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"decircularize": "^1.0.0",
|
||||
"deep-eql": "^4.1.4",
|
||||
"deep-equal": "^2.0.5",
|
||||
"dequal": "^2.0.3",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-friendly-formatter": "^4.0.1",
|
||||
"eslint-webpack-plugin": "^4.0.0",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-glob": "^3.3.3",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"in-publish": "^2.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"jest-expect-message": "^1.1.3",
|
||||
"lodash": "^4.17.21",
|
||||
"nano-equal": "^2.0.2",
|
||||
"prettier": "^2.8.8",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-fast-compare": "^3.2.1",
|
||||
"release-it": "^19.0.5",
|
||||
"rollup": "^3.29.5",
|
||||
"shallow-equal-fuzzy": "^0.0.2",
|
||||
"tinybench": "^2.9.0",
|
||||
"ts-jest": "^29.0.3",
|
||||
"ts-loader": "^9.4.2",
|
||||
"typescript": "^4.9.5",
|
||||
"underscore": "^1.13.4",
|
||||
"webpack": "^5.101.3",
|
||||
"webpack-cli": "^6.0.1",
|
||||
"webpack-dev-server": "^5.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"import": {
|
||||
"types": "./dist/esm/types/index.d.ts",
|
||||
"default": "./dist/esm/index.mjs"
|
||||
},
|
||||
"require": {
|
||||
"types": "./dist/cjs/types/index.d.ts",
|
||||
"default": "./dist/cjs/index.cjs"
|
||||
},
|
||||
"default": {
|
||||
"types": "./dist/umd/types/index.d.ts",
|
||||
"default": "./dist/umd/index.js"
|
||||
}
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"CHANGELOG.md",
|
||||
"index.d.ts",
|
||||
"LICENSE",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"homepage": "https://github.com/planttheidea/fast-equals#readme",
|
||||
"keywords": [
|
||||
"fast",
|
||||
"equal",
|
||||
"equals",
|
||||
"deep-equal",
|
||||
"equivalent"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "dist/cjs/index.cjs",
|
||||
"module": "dist/esm/index.mjs",
|
||||
"name": "fast-equals",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/planttheidea/fast-equals.git"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "npm run build:esm && node benchmark/index.js",
|
||||
"build": "npm run build:esm && npm run build:cjs && npm run build:umd && npm run build:min && npm run build:types",
|
||||
"build:cjs": "rm -rf dist/cjs && NODE_ENV=production rollup -c config/rollup/config.cjs.js && tsc -p ./config/tsconfig/cjs.json",
|
||||
"build:esm": "rm -rf dist/esm && NODE_ENV=production rollup -c config/rollup/config.esm.js && tsc -p ./config/tsconfig/esm.json",
|
||||
"build:min": "rm -rf dist/min && NODE_ENV=production rollup -c config/rollup/config.min.js && tsc -p ./config/tsconfig/min.json",
|
||||
"build:types": "node scripts/fallback-types.mjs && node scripts/apply-type-file-extensions.mjs",
|
||||
"build:umd": "rm -rf dist/umd && NODE_ENV=production rollup -c config/rollup/config.umd.js && tsc -p ./config/tsconfig/umd.json",
|
||||
"dev": "NODE_ENV=development webpack serve --progress --config=config/webpack.config.js",
|
||||
"format": "prettier **/*.ts --write",
|
||||
"lint": "eslint src/*.ts",
|
||||
"lint:fix": "npm run lint -- --fix",
|
||||
"start": "npm run dev",
|
||||
"release": "release-it",
|
||||
"release:beta": "release-it --config=.release-it.beta.json",
|
||||
"release:scripts": "npm run typecheck && npm run lint && npm run test:coverage && npm run build",
|
||||
"test": "NODE_PATH=. jest",
|
||||
"test:coverage": "rm -rf coverage && npm test -- --coverage",
|
||||
"test:watch": "npm test -- --watch",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"version": "5.3.2"
|
||||
}
|
||||
376
node_modules/fast-equals/src/comparator.ts
generated
vendored
Normal file
376
node_modules/fast-equals/src/comparator.ts
generated
vendored
Normal file
@@ -0,0 +1,376 @@
|
||||
import {
|
||||
areArraysEqual as areArraysEqualDefault,
|
||||
areDatesEqual as areDatesEqualDefault,
|
||||
areErrorsEqual as areErrorsEqualDefault,
|
||||
areFunctionsEqual as areFunctionsEqualDefault,
|
||||
areMapsEqual as areMapsEqualDefault,
|
||||
areNumbersEqual as areNumbersEqualDefault,
|
||||
areObjectsEqual as areObjectsEqualDefault,
|
||||
areObjectsEqualStrict as areObjectsEqualStrictDefault,
|
||||
arePrimitiveWrappersEqual as arePrimitiveWrappersEqualDefault,
|
||||
areRegExpsEqual as areRegExpsEqualDefault,
|
||||
areSetsEqual as areSetsEqualDefault,
|
||||
areTypedArraysEqual as areTypedArraysEqualDefault,
|
||||
areUrlsEqual as areUrlsEqualDefault,
|
||||
} from './equals';
|
||||
import { combineComparators, createIsCircular, getShortTag } from './utils';
|
||||
import type {
|
||||
ComparatorConfig,
|
||||
CreateState,
|
||||
CustomEqualCreatorOptions,
|
||||
EqualityComparator,
|
||||
InternalEqualityComparator,
|
||||
State,
|
||||
} from './internalTypes';
|
||||
|
||||
const ARGUMENTS_TAG = '[object Arguments]';
|
||||
const BOOLEAN_TAG = '[object Boolean]';
|
||||
const DATE_TAG = '[object Date]';
|
||||
const ERROR_TAG = '[object Error]';
|
||||
const MAP_TAG = '[object Map]';
|
||||
const NUMBER_TAG = '[object Number]';
|
||||
const OBJECT_TAG = '[object Object]';
|
||||
const REG_EXP_TAG = '[object RegExp]';
|
||||
const SET_TAG = '[object Set]';
|
||||
const STRING_TAG = '[object String]';
|
||||
const URL_TAG = '[object URL]';
|
||||
|
||||
const { isArray } = Array;
|
||||
const isTypedArray =
|
||||
typeof ArrayBuffer === 'function' && ArrayBuffer.isView
|
||||
? ArrayBuffer.isView
|
||||
: null;
|
||||
const { assign } = Object;
|
||||
const getTag = Object.prototype.toString.call.bind(
|
||||
Object.prototype.toString,
|
||||
) as (a: object) => string;
|
||||
|
||||
interface CreateIsEqualOptions<Meta> {
|
||||
circular: boolean;
|
||||
comparator: EqualityComparator<Meta>;
|
||||
createState: CreateState<Meta> | undefined;
|
||||
equals: InternalEqualityComparator<Meta>;
|
||||
strict: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a comparator method based on the type-specific equality comparators passed.
|
||||
*/
|
||||
export function createEqualityComparator<Meta>({
|
||||
areArraysEqual,
|
||||
areDatesEqual,
|
||||
areErrorsEqual,
|
||||
areFunctionsEqual,
|
||||
areMapsEqual,
|
||||
areNumbersEqual,
|
||||
areObjectsEqual,
|
||||
arePrimitiveWrappersEqual,
|
||||
areRegExpsEqual,
|
||||
areSetsEqual,
|
||||
areTypedArraysEqual,
|
||||
areUrlsEqual,
|
||||
unknownTagComparators,
|
||||
}: ComparatorConfig<Meta>): EqualityComparator<Meta> {
|
||||
/**
|
||||
* compare the value of the two objects and return true if they are equivalent in values
|
||||
*/
|
||||
return function comparator(a: any, b: any, state: State<Meta>): boolean {
|
||||
// If the items are strictly equal, no need to do a value comparison.
|
||||
if (a === b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If either of the items are nullish and fail the strictly equal check
|
||||
// above, then they must be unequal.
|
||||
if (a == null || b == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const type = typeof a;
|
||||
|
||||
if (type !== typeof b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type !== 'object') {
|
||||
if (type === 'number') {
|
||||
return areNumbersEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (type === 'function') {
|
||||
return areFunctionsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// If a primitive value that is not strictly equal, it must be unequal.
|
||||
return false;
|
||||
}
|
||||
|
||||
const constructor = a.constructor;
|
||||
|
||||
// Checks are listed in order of commonality of use-case:
|
||||
// 1. Common complex object types (plain object, array)
|
||||
// 2. Common data values (date, regexp)
|
||||
// 3. Less-common complex object types (map, set)
|
||||
// 4. Less-common data values (promise, primitive wrappers)
|
||||
// Inherently this is both subjective and assumptive, however
|
||||
// when reviewing comparable libraries in the wild this order
|
||||
// appears to be generally consistent.
|
||||
|
||||
// Constructors should match, otherwise there is potential for false positives
|
||||
// between class and subclass or custom object and POJO.
|
||||
if (constructor !== b.constructor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// `isPlainObject` only checks against the object's own realm. Cross-realm
|
||||
// comparisons are rare, and will be handled in the ultimate fallback, so
|
||||
// we can avoid capturing the string tag.
|
||||
if (constructor === Object) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
||||
// the string tag or doing an `instanceof` check.
|
||||
if (isArray(a)) {
|
||||
return areArraysEqual(a, b, state);
|
||||
}
|
||||
|
||||
// `isTypedArray()` works on all possible TypedArray classes, so we can avoid
|
||||
// capturing the string tag or comparing against all possible constructors.
|
||||
if (isTypedArray != null && isTypedArray(a)) {
|
||||
return areTypedArraysEqual(a, b, state);
|
||||
}
|
||||
|
||||
// Try to fast-path equality checks for other complex object types in the
|
||||
// same realm to avoid capturing the string tag. Strict equality is used
|
||||
// instead of `instanceof` because it is more performant for the common
|
||||
// use-case. If someone is subclassing a native class, it will be handled
|
||||
// with the string tag comparison.
|
||||
|
||||
if (constructor === Date) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (constructor === RegExp) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (constructor === Map) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (constructor === Set) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// Since this is a custom object, capture the string tag to determing its type.
|
||||
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
||||
const tag = getTag(a);
|
||||
|
||||
if (tag === DATE_TAG) {
|
||||
return areDatesEqual(a, b, state);
|
||||
}
|
||||
|
||||
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
||||
// tested like a standard object.
|
||||
if (tag === REG_EXP_TAG) {
|
||||
return areRegExpsEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (tag === MAP_TAG) {
|
||||
return areMapsEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (tag === SET_TAG) {
|
||||
return areSetsEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (tag === OBJECT_TAG) {
|
||||
// The exception for value comparison is custom `Promise`-like class instances. These should
|
||||
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
||||
// it reaches this point then that strict equality comparison has already failed.
|
||||
return (
|
||||
typeof a.then !== 'function' &&
|
||||
typeof b.then !== 'function' &&
|
||||
areObjectsEqual(a, b, state)
|
||||
);
|
||||
}
|
||||
|
||||
// If a URL tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === URL_TAG) {
|
||||
return areUrlsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
||||
// enumerable, and therefore will give false positives if tested like a standard object.
|
||||
if (tag === ERROR_TAG) {
|
||||
return areErrorsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// If an arguments tag, it should be treated as a standard object.
|
||||
if (tag === ARGUMENTS_TAG) {
|
||||
return areObjectsEqual(a, b, state);
|
||||
}
|
||||
|
||||
// As the penultimate fallback, check if the values passed are primitive wrappers. This
|
||||
// is very rare in modern JS, which is why it is deprioritized compared to all other object
|
||||
// types.
|
||||
if (tag === BOOLEAN_TAG || tag === NUMBER_TAG || tag === STRING_TAG) {
|
||||
return arePrimitiveWrappersEqual(a, b, state);
|
||||
}
|
||||
|
||||
if (unknownTagComparators) {
|
||||
let unknownTagComparator = unknownTagComparators[tag];
|
||||
|
||||
if (!unknownTagComparator) {
|
||||
const shortTag = getShortTag(a);
|
||||
|
||||
if (shortTag) {
|
||||
unknownTagComparator = unknownTagComparators[shortTag];
|
||||
}
|
||||
}
|
||||
|
||||
// If the custom config has an unknown tag comparator that matches the captured tag or the
|
||||
// @@toStringTag, it is the source of truth for whether the values are equal.
|
||||
if (unknownTagComparator) {
|
||||
return unknownTagComparator(a, b, state);
|
||||
}
|
||||
}
|
||||
|
||||
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
||||
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
||||
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
||||
// comparison that can be made.
|
||||
// - For types that can be introspected, but rarely have requirements to be compared
|
||||
// (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
|
||||
// use-cases (may be included in a future release, if requested enough).
|
||||
// - For types that can be introspected but do not have an objective definition of what
|
||||
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
||||
// In all cases, these decisions should be reevaluated based on changes to the language and
|
||||
// common development practices.
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the configuration object used for building comparators.
|
||||
*/
|
||||
export function createEqualityComparatorConfig<Meta>({
|
||||
circular,
|
||||
createCustomConfig,
|
||||
strict,
|
||||
}: CustomEqualCreatorOptions<Meta>): ComparatorConfig<Meta> {
|
||||
let config = {
|
||||
areArraysEqual: strict
|
||||
? areObjectsEqualStrictDefault
|
||||
: areArraysEqualDefault,
|
||||
areDatesEqual: areDatesEqualDefault,
|
||||
areErrorsEqual: areErrorsEqualDefault,
|
||||
areFunctionsEqual: areFunctionsEqualDefault,
|
||||
areMapsEqual: strict
|
||||
? combineComparators(areMapsEqualDefault, areObjectsEqualStrictDefault)
|
||||
: areMapsEqualDefault,
|
||||
areNumbersEqual: areNumbersEqualDefault,
|
||||
areObjectsEqual: strict
|
||||
? areObjectsEqualStrictDefault
|
||||
: areObjectsEqualDefault,
|
||||
arePrimitiveWrappersEqual: arePrimitiveWrappersEqualDefault,
|
||||
areRegExpsEqual: areRegExpsEqualDefault,
|
||||
areSetsEqual: strict
|
||||
? combineComparators(areSetsEqualDefault, areObjectsEqualStrictDefault)
|
||||
: areSetsEqualDefault,
|
||||
areTypedArraysEqual: strict
|
||||
? areObjectsEqualStrictDefault
|
||||
: areTypedArraysEqualDefault,
|
||||
areUrlsEqual: areUrlsEqualDefault,
|
||||
unknownTagComparators: undefined,
|
||||
};
|
||||
|
||||
if (createCustomConfig) {
|
||||
config = assign({}, config, createCustomConfig(config));
|
||||
}
|
||||
|
||||
if (circular) {
|
||||
const areArraysEqual = createIsCircular(config.areArraysEqual);
|
||||
const areMapsEqual = createIsCircular(config.areMapsEqual);
|
||||
const areObjectsEqual = createIsCircular(config.areObjectsEqual);
|
||||
const areSetsEqual = createIsCircular(config.areSetsEqual);
|
||||
|
||||
config = assign({}, config, {
|
||||
areArraysEqual,
|
||||
areMapsEqual,
|
||||
areObjectsEqual,
|
||||
areSetsEqual,
|
||||
});
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
||||
* use inside the built comparator.
|
||||
*/
|
||||
export function createInternalEqualityComparator<Meta>(
|
||||
compare: EqualityComparator<Meta>,
|
||||
): InternalEqualityComparator<Meta> {
|
||||
return function (
|
||||
a: any,
|
||||
b: any,
|
||||
_indexOrKeyA: any,
|
||||
_indexOrKeyB: any,
|
||||
_parentA: any,
|
||||
_parentB: any,
|
||||
state: State<Meta>,
|
||||
) {
|
||||
return compare(a, b, state);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the `isEqual` function used by the consuming application.
|
||||
*/
|
||||
export function createIsEqual<Meta>({
|
||||
circular,
|
||||
comparator,
|
||||
createState,
|
||||
equals,
|
||||
strict,
|
||||
}: CreateIsEqualOptions<Meta>) {
|
||||
if (createState) {
|
||||
return function isEqual<A, B>(a: A, b: B): boolean {
|
||||
const { cache = circular ? new WeakMap() : undefined, meta } =
|
||||
createState!();
|
||||
|
||||
return comparator(a, b, {
|
||||
cache,
|
||||
equals,
|
||||
meta,
|
||||
strict,
|
||||
} as State<Meta>);
|
||||
};
|
||||
}
|
||||
|
||||
if (circular) {
|
||||
return function isEqual<A, B>(a: A, b: B): boolean {
|
||||
return comparator(a, b, {
|
||||
cache: new WeakMap(),
|
||||
equals,
|
||||
meta: undefined as Meta,
|
||||
strict,
|
||||
} as State<Meta>);
|
||||
};
|
||||
}
|
||||
|
||||
const state = {
|
||||
cache: undefined,
|
||||
equals,
|
||||
meta: undefined,
|
||||
strict,
|
||||
} as State<Meta>;
|
||||
|
||||
return function isEqual<A, B>(a: A, b: B): boolean {
|
||||
return comparator(a, b, state);
|
||||
};
|
||||
}
|
||||
351
node_modules/fast-equals/src/equals.ts
generated
vendored
Normal file
351
node_modules/fast-equals/src/equals.ts
generated
vendored
Normal file
@@ -0,0 +1,351 @@
|
||||
import { getStrictProperties, hasOwn, sameValueZeroEqual } from './utils';
|
||||
import type {
|
||||
Dictionary,
|
||||
PrimitiveWrapper,
|
||||
State,
|
||||
TypedArray,
|
||||
} from './internalTypes';
|
||||
|
||||
const PREACT_VNODE = '__v';
|
||||
const PREACT_OWNER = '__o';
|
||||
const REACT_OWNER = '_owner';
|
||||
|
||||
const { getOwnPropertyDescriptor, keys } = Object;
|
||||
|
||||
/**
|
||||
* Whether the arrays are equal in value.
|
||||
*/
|
||||
export function areArraysEqual(a: any[], b: any[], state: State<any>) {
|
||||
let index = a.length;
|
||||
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (index-- > 0) {
|
||||
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
export function areDatesEqual(a: Date, b: Date): boolean {
|
||||
return sameValueZeroEqual(a.getTime(), b.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
export function areErrorsEqual(a: Error, b: Error): boolean {
|
||||
return (
|
||||
a.name === b.name &&
|
||||
a.message === b.message &&
|
||||
a.cause === b.cause &&
|
||||
a.stack === b.stack
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
export function areFunctionsEqual(
|
||||
a: (...args: any[]) => any,
|
||||
b: (...args: any[]) => any,
|
||||
): boolean {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the `Map`s are equal in value.
|
||||
*/
|
||||
export function areMapsEqual(
|
||||
a: Map<any, any>,
|
||||
b: Map<any, any>,
|
||||
state: State<any>,
|
||||
): boolean {
|
||||
const size = a.size;
|
||||
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const matchedIndices: Array<true | undefined> = new Array(size);
|
||||
const aIterable = a.entries();
|
||||
|
||||
let aResult: IteratorResult<[any, any]>;
|
||||
let bResult: IteratorResult<[any, any]>;
|
||||
let index = 0;
|
||||
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
|
||||
const bIterable = b.entries();
|
||||
|
||||
let hasMatch = false;
|
||||
let matchIndex = 0;
|
||||
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (matchedIndices[matchIndex]) {
|
||||
matchIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const aEntry = aResult.value;
|
||||
const bEntry = bResult.value;
|
||||
|
||||
if (
|
||||
state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state) &&
|
||||
state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)
|
||||
) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
matchIndex++;
|
||||
}
|
||||
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the numbers are equal in value.
|
||||
*/
|
||||
export const areNumbersEqual = sameValueZeroEqual;
|
||||
|
||||
/**
|
||||
* Whether the objects are equal in value.
|
||||
*/
|
||||
export function areObjectsEqual(
|
||||
a: Dictionary,
|
||||
b: Dictionary,
|
||||
state: State<any>,
|
||||
): boolean {
|
||||
const properties = keys(a);
|
||||
|
||||
let index = properties.length;
|
||||
|
||||
if (keys(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
if (!isPropertyEqual(a, b, state, properties[index]!)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the objects are equal in value with strict property checking.
|
||||
*/
|
||||
export function areObjectsEqualStrict(
|
||||
a: Dictionary,
|
||||
b: Dictionary,
|
||||
state: State<any>,
|
||||
): boolean {
|
||||
const properties = getStrictProperties(a);
|
||||
|
||||
let index = properties.length;
|
||||
|
||||
if (getStrictProperties(b).length !== index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let property: string | symbol;
|
||||
let descriptorA: ReturnType<typeof getOwnPropertyDescriptor>;
|
||||
let descriptorB: ReturnType<typeof getOwnPropertyDescriptor>;
|
||||
|
||||
// Decrementing `while` showed faster results than either incrementing or
|
||||
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
||||
// methods like `some` / `every` were not used to avoid incurring the garbage
|
||||
// cost of anonymous callbacks.
|
||||
while (index-- > 0) {
|
||||
property = properties[index]!;
|
||||
|
||||
if (!isPropertyEqual(a, b, state, property)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
descriptorA = getOwnPropertyDescriptor(a, property);
|
||||
descriptorB = getOwnPropertyDescriptor(b, property);
|
||||
|
||||
if (
|
||||
(descriptorA || descriptorB) &&
|
||||
(!descriptorA ||
|
||||
!descriptorB ||
|
||||
descriptorA.configurable !== descriptorB.configurable ||
|
||||
descriptorA.enumerable !== descriptorB.enumerable ||
|
||||
descriptorA.writable !== descriptorB.writable)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
export function arePrimitiveWrappersEqual(
|
||||
a: PrimitiveWrapper,
|
||||
b: PrimitiveWrapper,
|
||||
): boolean {
|
||||
return sameValueZeroEqual(a.valueOf(), b.valueOf());
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
export function areRegExpsEqual(a: RegExp, b: RegExp): boolean {
|
||||
return a.source === b.source && a.flags === b.flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the `Set`s are equal in value.
|
||||
*/
|
||||
export function areSetsEqual(
|
||||
a: Set<any>,
|
||||
b: Set<any>,
|
||||
state: State<any>,
|
||||
): boolean {
|
||||
const size = a.size;
|
||||
|
||||
if (size !== b.size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!size) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const matchedIndices: Array<true | undefined> = new Array(size);
|
||||
const aIterable = a.values();
|
||||
|
||||
let aResult: IteratorResult<any>;
|
||||
let bResult: IteratorResult<any>;
|
||||
|
||||
while ((aResult = aIterable.next())) {
|
||||
if (aResult.done) {
|
||||
break;
|
||||
}
|
||||
|
||||
const bIterable = b.values();
|
||||
|
||||
let hasMatch = false;
|
||||
let matchIndex = 0;
|
||||
|
||||
while ((bResult = bIterable.next())) {
|
||||
if (bResult.done) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
!matchedIndices[matchIndex] &&
|
||||
state.equals(
|
||||
aResult.value,
|
||||
bResult.value,
|
||||
aResult.value,
|
||||
bResult.value,
|
||||
a,
|
||||
b,
|
||||
state,
|
||||
)
|
||||
) {
|
||||
hasMatch = matchedIndices[matchIndex] = true;
|
||||
break;
|
||||
}
|
||||
|
||||
matchIndex++;
|
||||
}
|
||||
|
||||
if (!hasMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the TypedArray instances are equal in value.
|
||||
*/
|
||||
export function areTypedArraysEqual(a: TypedArray, b: TypedArray) {
|
||||
let index = a.length;
|
||||
|
||||
if (b.length !== index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (index-- > 0) {
|
||||
if (a[index] !== b[index]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the URL instances are equal in value.
|
||||
*/
|
||||
export function areUrlsEqual(a: URL, b: URL): boolean {
|
||||
return (
|
||||
a.hostname === b.hostname &&
|
||||
a.pathname === b.pathname &&
|
||||
a.protocol === b.protocol &&
|
||||
a.port === b.port &&
|
||||
a.hash === b.hash &&
|
||||
a.username === b.username &&
|
||||
a.password === b.password
|
||||
);
|
||||
}
|
||||
|
||||
function isPropertyEqual(
|
||||
a: Dictionary,
|
||||
b: Dictionary,
|
||||
state: State<any>,
|
||||
property: string | symbol,
|
||||
) {
|
||||
if (
|
||||
(property === REACT_OWNER ||
|
||||
property === PREACT_OWNER ||
|
||||
property === PREACT_VNODE) &&
|
||||
(a.$$typeof || b.$$typeof)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
hasOwn(b, property) &&
|
||||
state.equals(a[property], b[property], property, property, a, b, state)
|
||||
);
|
||||
}
|
||||
112
node_modules/fast-equals/src/index.ts
generated
vendored
Normal file
112
node_modules/fast-equals/src/index.ts
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
import {
|
||||
createEqualityComparatorConfig,
|
||||
createEqualityComparator,
|
||||
createInternalEqualityComparator,
|
||||
createIsEqual,
|
||||
} from './comparator';
|
||||
import type { CustomEqualCreatorOptions } from './internalTypes';
|
||||
import { sameValueZeroEqual } from './utils';
|
||||
|
||||
export { sameValueZeroEqual };
|
||||
export type {
|
||||
AnyEqualityComparator,
|
||||
Cache,
|
||||
CircularState,
|
||||
ComparatorConfig,
|
||||
CreateCustomComparatorConfig,
|
||||
CreateState,
|
||||
CustomEqualCreatorOptions,
|
||||
DefaultState,
|
||||
Dictionary,
|
||||
EqualityComparator,
|
||||
EqualityComparatorCreator,
|
||||
InternalEqualityComparator,
|
||||
PrimitiveWrapper,
|
||||
State,
|
||||
TypeEqualityComparator,
|
||||
TypedArray,
|
||||
} from './internalTypes';
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value.
|
||||
*/
|
||||
export const deepEqual = createCustomEqual();
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value based on strict comparison.
|
||||
*/
|
||||
export const strictDeepEqual = createCustomEqual({ strict: true });
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references.
|
||||
*/
|
||||
export const circularDeepEqual = createCustomEqual({ circular: true });
|
||||
|
||||
/**
|
||||
* Whether the items passed are deeply-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export const strictCircularDeepEqual = createCustomEqual({
|
||||
circular: true,
|
||||
strict: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value.
|
||||
*/
|
||||
export const shallowEqual = createCustomEqual({
|
||||
createInternalComparator: () => sameValueZeroEqual,
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value based on strict comparison
|
||||
*/
|
||||
export const strictShallowEqual = createCustomEqual({
|
||||
strict: true,
|
||||
createInternalComparator: () => sameValueZeroEqual,
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references.
|
||||
*/
|
||||
export const circularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: () => sameValueZeroEqual,
|
||||
});
|
||||
|
||||
/**
|
||||
* Whether the items passed are shallowly-equal in value, including circular references,
|
||||
* based on strict comparison.
|
||||
*/
|
||||
export const strictCircularShallowEqual = createCustomEqual({
|
||||
circular: true,
|
||||
createInternalComparator: () => sameValueZeroEqual,
|
||||
strict: true,
|
||||
});
|
||||
|
||||
/**
|
||||
* Create a custom equality comparison method.
|
||||
*
|
||||
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
||||
* where the standard methods are not performant enough, but can also be used to provide
|
||||
* support for legacy environments that do not support expected features like
|
||||
* `RegExp.prototype.flags` out of the box.
|
||||
*/
|
||||
export function createCustomEqual<Meta = undefined>(
|
||||
options: CustomEqualCreatorOptions<Meta> = {},
|
||||
) {
|
||||
const {
|
||||
circular = false,
|
||||
createInternalComparator: createCustomInternalComparator,
|
||||
createState,
|
||||
strict = false,
|
||||
} = options;
|
||||
|
||||
const config = createEqualityComparatorConfig<Meta>(options);
|
||||
const comparator = createEqualityComparator(config);
|
||||
const equals = createCustomInternalComparator
|
||||
? createCustomInternalComparator(comparator)
|
||||
: createInternalEqualityComparator(comparator);
|
||||
|
||||
return createIsEqual({ circular, comparator, createState, equals, strict });
|
||||
}
|
||||
210
node_modules/fast-equals/src/internalTypes.ts
generated
vendored
Normal file
210
node_modules/fast-equals/src/internalTypes.ts
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* Cache used to store references to objects, used for circular
|
||||
* reference checks.
|
||||
*/
|
||||
export interface Cache<Key extends object, Value> {
|
||||
delete(key: Key): boolean;
|
||||
get(key: Key): Value | undefined;
|
||||
set(key: Key, value: any): any;
|
||||
}
|
||||
|
||||
export interface State<Meta> {
|
||||
/**
|
||||
* Cache used to identify circular references
|
||||
*/
|
||||
readonly cache: Cache<any, any> | undefined;
|
||||
/**
|
||||
* Method used to determine equality of nested value.
|
||||
*/
|
||||
readonly equals: InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Additional value that can be used for comparisons.
|
||||
*/
|
||||
meta: Meta;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
readonly strict: boolean;
|
||||
}
|
||||
|
||||
export interface CircularState<Meta> extends State<Meta> {
|
||||
readonly cache: Cache<any, any>;
|
||||
}
|
||||
|
||||
export interface DefaultState<Meta> extends State<Meta> {
|
||||
readonly cache: undefined;
|
||||
}
|
||||
|
||||
export interface Dictionary<Value = any> {
|
||||
[key: string | symbol]: Value;
|
||||
$$typeof?: any;
|
||||
}
|
||||
|
||||
export interface ComparatorConfig<Meta> {
|
||||
/**
|
||||
* Whether the arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the array.
|
||||
*/
|
||||
areArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the dates passed are equal in value.
|
||||
*/
|
||||
areDatesEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the errors passed are equal in value.
|
||||
*/
|
||||
areErrorsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the functions passed are equal in value.
|
||||
*/
|
||||
areFunctionsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the maps passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the map.
|
||||
*/
|
||||
areMapsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the numbers passed are equal in value.
|
||||
*/
|
||||
areNumbersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the objects passed are equal in value. In strict mode, this includes
|
||||
* non-enumerable properties added to the map, as well as symbol properties.
|
||||
*/
|
||||
areObjectsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the primitive wrappers passed are equal in value.
|
||||
*/
|
||||
arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the regexps passed are equal in value.
|
||||
*/
|
||||
areRegExpsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the sets passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the set.
|
||||
*/
|
||||
areSetsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the typed arrays passed are equal in value. In strict mode, this includes
|
||||
* additional properties added to the typed array.
|
||||
*/
|
||||
areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether the URLs passed are equal in value.
|
||||
*/
|
||||
areUrlsEqual: TypeEqualityComparator<any, Meta>;
|
||||
/**
|
||||
* Whether two values with unknown `@@toStringTag` are equal in value. This comparator is
|
||||
* called when no other comparator applies.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag
|
||||
*/
|
||||
unknownTagComparators:
|
||||
| Record<string, TypeEqualityComparator<any, Meta>>
|
||||
| undefined;
|
||||
}
|
||||
|
||||
export type CreateCustomComparatorConfig<Meta> = (
|
||||
config: ComparatorConfig<Meta>,
|
||||
) => Partial<ComparatorConfig<Meta>>;
|
||||
|
||||
export type CreateState<Meta> = () => {
|
||||
cache?: Cache<any, any> | undefined;
|
||||
meta?: Meta;
|
||||
};
|
||||
|
||||
export type EqualityComparator<Meta> = <A, B>(
|
||||
a: A,
|
||||
b: B,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
export type AnyEqualityComparator<Meta> = (
|
||||
a: any,
|
||||
b: any,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
export type EqualityComparatorCreator<Meta> = (
|
||||
fn: EqualityComparator<Meta>,
|
||||
) => InternalEqualityComparator<Meta>;
|
||||
|
||||
export type InternalEqualityComparator<Meta> = (
|
||||
a: any,
|
||||
b: any,
|
||||
indexOrKeyA: any,
|
||||
indexOrKeyB: any,
|
||||
parentA: any,
|
||||
parentB: any,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
// We explicitly check for primitive wrapper types
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export type PrimitiveWrapper = Boolean | Number | String;
|
||||
|
||||
/**
|
||||
* Type which encompasses possible instances of TypedArray
|
||||
* classes.
|
||||
*
|
||||
* **NOTE**: This does not include `BigInt64Array` and
|
||||
* `BitUint64Array` because those are part of ES2020 and
|
||||
* not supported by certain TS configurations. If using
|
||||
* either in `areTypedArraysEqual`, you can cast the
|
||||
* instance as `TypedArray` and it will work as expected,
|
||||
* because runtime checks will still work for those classes.
|
||||
*/
|
||||
export type TypedArray =
|
||||
| Float32Array
|
||||
| Float64Array
|
||||
| Int8Array
|
||||
| Int16Array
|
||||
| Int32Array
|
||||
| Uint16Array
|
||||
| Uint32Array
|
||||
| Uint8Array
|
||||
| Uint8ClampedArray;
|
||||
|
||||
export type TypeEqualityComparator<Type, Meta = undefined> = (
|
||||
a: Type,
|
||||
b: Type,
|
||||
state: State<Meta>,
|
||||
) => boolean;
|
||||
|
||||
export interface CustomEqualCreatorOptions<Meta> {
|
||||
/**
|
||||
* Whether circular references should be supported. It causes the
|
||||
* comparison to be slower, but for objects that have circular references
|
||||
* it is required to avoid stack overflows.
|
||||
*/
|
||||
circular?: boolean;
|
||||
/**
|
||||
* Create a custom configuration of type-specific equality comparators.
|
||||
* This receives the default configuration, which allows either replacement
|
||||
* or supersetting of the default methods.
|
||||
*/
|
||||
createCustomConfig?: CreateCustomComparatorConfig<Meta>;
|
||||
/**
|
||||
* Create a custom internal comparator, which is used as an override to the
|
||||
* default entry point for nested value equality comparisons. This is often
|
||||
* used for doing custom logic for specific types (such as handling a specific
|
||||
* class instance differently than other objects) or to incorporate `meta` in
|
||||
* the comparison. See the recipes for examples.
|
||||
*/
|
||||
createInternalComparator?: (
|
||||
compare: EqualityComparator<Meta>,
|
||||
) => InternalEqualityComparator<Meta>;
|
||||
/**
|
||||
* Create a custom `state` object passed between the methods. This allows for
|
||||
* custom `cache` and/or `meta` values to be used.
|
||||
*/
|
||||
createState?: CreateState<Meta>;
|
||||
/**
|
||||
* Whether the equality comparison is strict, meaning it matches
|
||||
* all properties (including symbols and non-enumerable properties)
|
||||
* with equal shape of descriptors.
|
||||
*/
|
||||
strict?: boolean;
|
||||
}
|
||||
95
node_modules/fast-equals/src/utils.ts
generated
vendored
Normal file
95
node_modules/fast-equals/src/utils.ts
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
import type {
|
||||
AnyEqualityComparator,
|
||||
Cache,
|
||||
CircularState,
|
||||
Dictionary,
|
||||
State,
|
||||
TypeEqualityComparator,
|
||||
} from './internalTypes';
|
||||
|
||||
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
|
||||
/**
|
||||
* Combine two comparators into a single comparators.
|
||||
*/
|
||||
export function combineComparators<Meta>(
|
||||
comparatorA: AnyEqualityComparator<Meta>,
|
||||
comparatorB: AnyEqualityComparator<Meta>,
|
||||
) {
|
||||
return function isEqual<A, B>(a: A, b: B, state: State<Meta>) {
|
||||
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
||||
* for circular references to be safely included in the comparison without creating
|
||||
* stack overflows.
|
||||
*/
|
||||
export function createIsCircular<
|
||||
AreItemsEqual extends TypeEqualityComparator<any, any>,
|
||||
>(areItemsEqual: AreItemsEqual): AreItemsEqual {
|
||||
return function isCircular(
|
||||
a: any,
|
||||
b: any,
|
||||
state: CircularState<Cache<any, any>>,
|
||||
) {
|
||||
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
||||
return areItemsEqual(a, b, state);
|
||||
}
|
||||
|
||||
const { cache } = state;
|
||||
|
||||
const cachedA = cache.get(a);
|
||||
const cachedB = cache.get(b);
|
||||
|
||||
if (cachedA && cachedB) {
|
||||
return cachedA === b && cachedB === a;
|
||||
}
|
||||
|
||||
cache.set(a, b);
|
||||
cache.set(b, a);
|
||||
|
||||
const result = areItemsEqual(a, b, state);
|
||||
|
||||
cache.delete(a);
|
||||
cache.delete(b);
|
||||
|
||||
return result;
|
||||
} as AreItemsEqual;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the `@@toStringTag` of the value, if it exists.
|
||||
*/
|
||||
export function getShortTag(value: any): string | undefined {
|
||||
return value != null ? value[Symbol.toStringTag] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properties to strictly examine, which include both own properties that are
|
||||
* not enumerable and symbol properties.
|
||||
*/
|
||||
export function getStrictProperties(
|
||||
object: Dictionary,
|
||||
): Array<string | symbol> {
|
||||
return (getOwnPropertyNames(object) as Array<string | symbol>).concat(
|
||||
getOwnPropertySymbols(object),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the object contains the property passed as an own property.
|
||||
*/
|
||||
export const hasOwn =
|
||||
Object.hasOwn ||
|
||||
((object: Dictionary, property: number | string | symbol) =>
|
||||
hasOwnProperty.call(object, property));
|
||||
|
||||
/**
|
||||
* Whether the values passed are strictly equal or both NaN.
|
||||
*/
|
||||
export function sameValueZeroEqual(a: any, b: any): boolean {
|
||||
return a === b || (!a && !b && a !== a && b !== b);
|
||||
}
|
||||
Reference in New Issue
Block a user