fast-equals 5.3.1 → 5.3.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +1 -1
  3. package/dist/cjs/index.cjs +9 -3
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/types/{comparator.d.ts → comparator.d.cts} +1 -1
  6. package/dist/{esm/types/equals.d.ts → cjs/types/equals.d.cts} +2 -2
  7. package/dist/cjs/types/{index.d.ts → index.d.cts} +3 -3
  8. package/dist/{esm/types/utils.d.ts → cjs/types/utils.d.cts} +1 -1
  9. package/dist/esm/index.mjs +9 -3
  10. package/dist/esm/index.mjs.map +1 -1
  11. package/dist/esm/types/{comparator.d.ts → comparator.d.mts} +1 -1
  12. package/dist/{cjs/types/equals.d.ts → esm/types/equals.d.mts} +2 -2
  13. package/dist/esm/types/{index.d.ts → index.d.mts} +3 -3
  14. package/dist/{cjs/types/utils.d.ts → esm/types/utils.d.mts} +1 -1
  15. package/dist/min/index.js +1 -1
  16. package/dist/min/types/comparator.d.ts +1 -1
  17. package/dist/min/types/equals.d.ts +1 -1
  18. package/dist/min/types/index.d.ts +2 -2
  19. package/dist/min/types/utils.d.ts +1 -1
  20. package/dist/umd/index.js +9 -3
  21. package/dist/umd/index.js.map +1 -1
  22. package/dist/umd/types/comparator.d.ts +1 -1
  23. package/dist/umd/types/equals.d.ts +1 -1
  24. package/dist/umd/types/index.d.ts +2 -2
  25. package/dist/umd/types/utils.d.ts +1 -1
  26. package/index.d.ts +1 -1
  27. package/package.json +51 -41
  28. package/src/comparator.ts +7 -7
  29. package/src/equals.ts +8 -4
  30. package/src/index.ts +4 -4
  31. package/src/internalTypes.ts +1 -1
  32. package/src/utils.ts +2 -1
  33. package/.babelrc +0 -34
  34. package/.prettierrc +0 -8
  35. package/.release-it.beta.json +0 -18
  36. package/.release-it.json +0 -14
  37. package/.yarnrc.yml +0 -5
  38. package/BUILD.md +0 -37
  39. package/config/rollup/config.base.js +0 -49
  40. package/config/rollup/config.cjs.js +0 -10
  41. package/config/rollup/config.esm.js +0 -10
  42. package/config/rollup/config.min.js +0 -13
  43. package/config/rollup/config.umd.js +0 -10
  44. package/config/tsconfig/base.json +0 -32
  45. package/config/tsconfig/cjs.json +0 -8
  46. package/config/tsconfig/declarations.json +0 -9
  47. package/config/tsconfig/esm.json +0 -8
  48. package/config/tsconfig/min.json +0 -8
  49. package/config/tsconfig/umd.json +0 -8
  50. package/config/webpack.config.js +0 -57
  51. package/recipes/explicit-property-check.md +0 -26
  52. package/recipes/legacy-circular-equal-support.md +0 -75
  53. package/recipes/legacy-regexp-support.md +0 -24
  54. package/recipes/non-standard-properties.md +0 -48
  55. package/recipes/special-objects.md +0 -25
  56. package/recipes/using-meta-in-comparison.md +0 -20
  57. package/scripts/apply-type-file-extensions.mjs +0 -33
  58. package/scripts/fallback-types.mjs +0 -64
  59. /package/dist/cjs/types/{internalTypes.d.ts → internalTypes.d.cts} +0 -0
  60. /package/dist/esm/types/{internalTypes.d.ts → internalTypes.d.mts} +0 -0
package/src/equals.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { getStrictProperties, hasOwn, sameValueZeroEqual } from './utils';
1
+ import { getStrictProperties, hasOwn, sameValueZeroEqual } from './utils.ts';
2
2
  import type {
3
3
  Dictionary,
4
4
  PrimitiveWrapper,
5
5
  State,
6
6
  TypedArray,
7
- } from './internalTypes';
7
+ } from './internalTypes.ts';
8
8
 
9
9
  const PREACT_VNODE = '__v';
10
10
  const PREACT_OWNER = '__o';
@@ -78,13 +78,14 @@ export function areMapsEqual(
78
78
  return true;
79
79
  }
80
80
 
81
- const matchedIndices: Array<true | undefined> = new Array(size);
81
+ const matchedIndices = new Array<true | undefined>(size);
82
82
  const aIterable = a.entries();
83
83
 
84
84
  let aResult: IteratorResult<[any, any]>;
85
85
  let bResult: IteratorResult<[any, any]>;
86
86
  let index = 0;
87
87
 
88
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
88
89
  while ((aResult = aIterable.next())) {
89
90
  if (aResult.done) {
90
91
  break;
@@ -95,6 +96,7 @@ export function areMapsEqual(
95
96
  let hasMatch = false;
96
97
  let matchIndex = 0;
97
98
 
99
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
98
100
  while ((bResult = bIterable.next())) {
99
101
  if (bResult.done) {
100
102
  break;
@@ -247,12 +249,13 @@ export function areSetsEqual(
247
249
  return true;
248
250
  }
249
251
 
250
- const matchedIndices: Array<true | undefined> = new Array(size);
252
+ const matchedIndices = new Array<true | undefined>(size);
251
253
  const aIterable = a.values();
252
254
 
253
255
  let aResult: IteratorResult<any>;
254
256
  let bResult: IteratorResult<any>;
255
257
 
258
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
256
259
  while ((aResult = aIterable.next())) {
257
260
  if (aResult.done) {
258
261
  break;
@@ -263,6 +266,7 @@ export function areSetsEqual(
263
266
  let hasMatch = false;
264
267
  let matchIndex = 0;
265
268
 
269
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
266
270
  while ((bResult = bIterable.next())) {
267
271
  if (bResult.done) {
268
272
  break;
package/src/index.ts CHANGED
@@ -3,9 +3,9 @@ import {
3
3
  createEqualityComparator,
4
4
  createInternalEqualityComparator,
5
5
  createIsEqual,
6
- } from './comparator';
7
- import type { CustomEqualCreatorOptions } from './internalTypes';
8
- import { sameValueZeroEqual } from './utils';
6
+ } from './comparator.ts';
7
+ import type { CustomEqualCreatorOptions } from './internalTypes.ts';
8
+ import { sameValueZeroEqual } from './utils.ts';
9
9
 
10
10
  export { sameValueZeroEqual };
11
11
  export type {
@@ -25,7 +25,7 @@ export type {
25
25
  State,
26
26
  TypeEqualityComparator,
27
27
  TypedArray,
28
- } from './internalTypes';
28
+ } from './internalTypes.ts';
29
29
 
30
30
  /**
31
31
  * Whether the items passed are deeply-equal in value.
@@ -142,7 +142,7 @@ export type InternalEqualityComparator<Meta> = (
142
142
  ) => boolean;
143
143
 
144
144
  // We explicitly check for primitive wrapper types
145
- // eslint-disable-next-line @typescript-eslint/ban-types
145
+ // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
146
146
  export type PrimitiveWrapper = Boolean | Number | String;
147
147
 
148
148
  /**
package/src/utils.ts CHANGED
@@ -5,7 +5,7 @@ import type {
5
5
  Dictionary,
6
6
  State,
7
7
  TypeEqualityComparator,
8
- } from './internalTypes';
8
+ } from './internalTypes.ts';
9
9
 
10
10
  const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
11
11
  const { hasOwnProperty } = Object.prototype;
@@ -83,6 +83,7 @@ export function getStrictProperties(
83
83
  * Whether the object contains the property passed as an own property.
84
84
  */
85
85
  export const hasOwn =
86
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
86
87
  Object.hasOwn ||
87
88
  ((object: Dictionary, property: number | string | symbol) =>
88
89
  hasOwnProperty.call(object, property));
package/.babelrc DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "env": {
3
- "lib": {
4
- "presets": [
5
- [
6
- "@babel/preset-env",
7
- {
8
- "loose": true
9
- }
10
- ]
11
- ]
12
- },
13
- "test": {
14
- "presets": [
15
- [
16
- "@babel/preset-env",
17
- {
18
- "loose": true
19
- }
20
- ]
21
- ]
22
- }
23
- },
24
- "presets": [
25
- "@babel/preset-typescript",
26
- [
27
- "@babel/preset-env",
28
- {
29
- "loose": true,
30
- "modules": false
31
- }
32
- ]
33
- ]
34
- }
package/.prettierrc DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "arrowParens": "always",
3
- "bracketSpacing": true,
4
- "semi": true,
5
- "singleQuote": true,
6
- "tabWidth": 2,
7
- "trailingComma": "all"
8
- }
@@ -1,18 +0,0 @@
1
- {
2
- "github": {
3
- "release": true,
4
- "tagName": "v${version}"
5
- },
6
- "hooks": {
7
- "before:init": [
8
- "npm run typecheck",
9
- "npm run lint",
10
- "npm run test",
11
- "npm run build"
12
- ]
13
- },
14
- "npm": {
15
- "tag": "next"
16
- },
17
- "preReleaseId": "beta"
18
- }
package/.release-it.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "github": {
3
- "release": true,
4
- "tagName": "v${version}"
5
- },
6
- "hooks": {
7
- "before:init": [
8
- "npm run typecheck",
9
- "npm run lint",
10
- "npm run test",
11
- "npm run build"
12
- ]
13
- }
14
- }
package/.yarnrc.yml DELETED
@@ -1,5 +0,0 @@
1
- compressionLevel: mixed
2
-
3
- enableGlobalCache: false
4
-
5
- nodeLinker: node-modules
package/BUILD.md DELETED
@@ -1,37 +0,0 @@
1
- # Reproducing a build
2
-
3
- ## Clone version
4
-
5
- ```
6
- git clone https://github.com/planttheidea/fast-equals.git
7
- cd fast-equals
8
- git checkout {version}
9
- ```
10
-
11
- Replace `{version}` above with the appropriate package version. If you want to compare a version older than `1.6.2`, you'll need to use a commit hash directly.
12
-
13
- ## Install
14
-
15
- ```
16
- yarn install
17
- ```
18
-
19
- We use `yarn` for our package management, so to ensure that exact dependencies you should also use it.
20
-
21
- ## Build artifacts
22
-
23
- ```
24
- yarn run build
25
- ```
26
-
27
- **NOTE**: To get an exact checksum match with the versions released on npm, it may be necessary to change line endings. For example, on Linux you might run:
28
-
29
- ```
30
- unix2dos dist/fast-equals.min.js
31
- ```
32
-
33
- ## Get checksum
34
-
35
- ```
36
- sha256sum dist/fast-equals.min.js
37
- ```
@@ -1,49 +0,0 @@
1
- import commonjs from '@rollup/plugin-commonjs';
2
- import { nodeResolve } from '@rollup/plugin-node-resolve';
3
- import replace from '@rollup/plugin-replace';
4
- import typescript from '@rollup/plugin-typescript';
5
- import fs from 'fs';
6
- import path from 'path';
7
- import tsc from 'typescript';
8
- import { fileURLToPath } from 'url';
9
-
10
- const ROOT = fileURLToPath(new URL('../..', import.meta.url));
11
-
12
- export const PACKAGE_JSON = JSON.parse(
13
- fs.readFileSync(path.resolve(ROOT, 'package.json')),
14
- );
15
-
16
- const external = [
17
- ...Object.keys(PACKAGE_JSON.dependencies || {}),
18
- ...Object.keys(PACKAGE_JSON.peerDependencies || {}),
19
- ];
20
- const globals = external.reduce((globals, name) => {
21
- globals[name] = name;
22
-
23
- return globals;
24
- }, {});
25
-
26
- export const BASE_CONFIG = {
27
- external,
28
- input: path.resolve(ROOT, 'src', 'index.ts'),
29
- output: {
30
- exports: 'named',
31
- globals,
32
- name: 'fast-equals',
33
- sourcemap: true,
34
- },
35
- plugins: [
36
- replace({
37
- 'process.env.NODE_ENV': JSON.stringify('production'),
38
- preventAssignment: true,
39
- }),
40
- nodeResolve({
41
- mainFields: ['module', 'browser', 'main'],
42
- }),
43
- commonjs({ include: /use-sync-external-store/ }),
44
- typescript({
45
- tsconfig: path.resolve(ROOT, 'config', 'tsconfig', 'base.json'),
46
- typescript: tsc,
47
- }),
48
- ],
49
- };
@@ -1,10 +0,0 @@
1
- import { BASE_CONFIG, PACKAGE_JSON } from './config.base.js';
2
-
3
- export default {
4
- ...BASE_CONFIG,
5
- output: {
6
- ...BASE_CONFIG.output,
7
- file: PACKAGE_JSON.main,
8
- format: 'cjs',
9
- },
10
- };
@@ -1,10 +0,0 @@
1
- import { BASE_CONFIG, PACKAGE_JSON } from './config.base.js';
2
-
3
- export default {
4
- ...BASE_CONFIG,
5
- output: {
6
- ...BASE_CONFIG.output,
7
- file: PACKAGE_JSON.module,
8
- format: 'es',
9
- },
10
- };
@@ -1,13 +0,0 @@
1
- import { BASE_CONFIG, PACKAGE_JSON } from './config.base.js';
2
- import terser from '@rollup/plugin-terser';
3
-
4
- export default {
5
- ...BASE_CONFIG,
6
- output: {
7
- ...BASE_CONFIG.output,
8
- file: PACKAGE_JSON.browser.replace('umd', 'min'),
9
- format: 'umd',
10
- sourcemap: false,
11
- },
12
- plugins: [...BASE_CONFIG.plugins, terser()],
13
- };
@@ -1,10 +0,0 @@
1
- import { BASE_CONFIG, PACKAGE_JSON } from './config.base.js';
2
-
3
- export default {
4
- ...BASE_CONFIG,
5
- output: {
6
- ...BASE_CONFIG.output,
7
- file: PACKAGE_JSON.browser,
8
- format: 'umd',
9
- },
10
- };
@@ -1,32 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "allowUnreachableCode": false,
5
- "baseUrl": "../../src",
6
- "esModuleInterop": true,
7
- "jsx": "react-jsx",
8
- "lib": ["DOM", "ESNext"],
9
- "module": "ESNext",
10
- "moduleResolution": "Node",
11
- "noFallthroughCasesInSwitch": true,
12
- "noImplicitAny": true,
13
- "noImplicitReturns": true,
14
- "noImplicitThis": true,
15
- "noUncheckedIndexedAccess": true,
16
- "noUnusedLocals": true,
17
- "noUnusedParameters": true,
18
- "outDir": "../../../dist",
19
- "resolveJsonModule": true,
20
- "skipLibCheck": true,
21
- "sourceMap": true,
22
- "strict": true,
23
- "strictBindCallApply": true,
24
- "strictNullChecks": true,
25
- "inlineSources": true,
26
- "target": "es5",
27
- "types": ["jest", "node", "react"]
28
- },
29
- "exclude": ["../../node_modules"],
30
- "include": ["../../src/**/*", "../../__tests__/**/*", "../../DEV_ONLY/**/*"],
31
- "files": ["../../node_modules/jest-expect-message/types/index.d.ts"]
32
- }
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "./declarations.json",
3
- "compilerOptions": {
4
- "declarationDir": "../../dist/cjs/types",
5
- "module": "CommonJS",
6
- "outDir": "../../dist/cjs"
7
- }
8
- }
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "./base.json",
3
- "compilerOptions": {
4
- "declaration": true,
5
- "emitDeclarationOnly": true,
6
- "resolveJsonModule": false
7
- },
8
- "include": ["../../src/*"]
9
- }
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "./declarations.json",
3
- "compilerOptions": {
4
- "declarationDir": "../../dist/esm/types",
5
- "module": "ESNext",
6
- "outDir": "../../dist/esm"
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "./declarations.json",
3
- "compilerOptions": {
4
- "declarationDir": "../../dist/min/types",
5
- "module": "UMD",
6
- "outDir": "../../dist/min"
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "./declarations.json",
3
- "compilerOptions": {
4
- "declarationDir": "../../dist/umd/types",
5
- "module": "UMD",
6
- "outDir": "../../dist/umd"
7
- }
8
- }
@@ -1,57 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-var-requires */
2
-
3
- import ESLintWebpackPlugin from 'eslint-webpack-plugin';
4
- import HtmlWebpackPlugin from 'html-webpack-plugin';
5
- import path from 'path';
6
- import { fileURLToPath } from 'url';
7
- import webpack from 'webpack';
8
-
9
- const ROOT = fileURLToPath(new URL('..', import.meta.url));
10
- const PORT = 3000;
11
-
12
- export default {
13
- cache: true,
14
-
15
- devServer: {
16
- host: 'localhost',
17
- port: PORT,
18
- },
19
-
20
- devtool: 'source-map',
21
-
22
- entry: [path.resolve(ROOT, 'DEV_ONLY', 'index.tsx')],
23
-
24
- mode: 'development',
25
-
26
- module: {
27
- rules: [
28
- {
29
- include: [path.resolve(ROOT, 'src'), path.resolve(ROOT, 'DEV_ONLY')],
30
- loader: 'ts-loader',
31
- options: {
32
- reportFiles: ['src/*.{ts|tsx}'],
33
- },
34
- test: /\.(ts|tsx)$/,
35
- },
36
- ],
37
- },
38
-
39
- output: {
40
- filename: 'fast-equals.js',
41
- library: 'fastEquals',
42
- libraryTarget: 'umd',
43
- path: path.resolve(ROOT, 'dist'),
44
- publicPath: `http://localhost:${PORT}/`,
45
- umdNamedDefine: true,
46
- },
47
-
48
- plugins: [
49
- new ESLintWebpackPlugin(),
50
- new webpack.EnvironmentPlugin(['NODE_ENV']),
51
- new HtmlWebpackPlugin(),
52
- ],
53
-
54
- resolve: {
55
- extensions: ['.tsx', '.ts', '.js'],
56
- },
57
- };
@@ -1,26 +0,0 @@
1
- # Explicit property check
2
-
3
- Sometimes it is necessary to squeeze every once of performance out of your runtime code, and deep equality checks can be a bottleneck. When this is occurs, it can be advantageous to build a custom comparison that allows for highly specific equality checks.
4
-
5
- An example where you know the shape of the objects being passed in, where the `foo` property is a simple primitive and the `bar` property is a nested object:
6
-
7
- ```ts
8
- import { createCustomEqual } from 'fast-equals';
9
- import type { TypeEqualityComparator } from 'fast-equals';
10
-
11
- interface SpecialObject {
12
- foo: string;
13
- bar: {
14
- baz: number;
15
- };
16
- }
17
-
18
- const areObjectsEqual: TypeEqualityComparator<SpecialObject, undefined> = (
19
- a,
20
- b,
21
- ) => a.foo === b.foo && a.bar.baz === b.bar.baz;
22
-
23
- const isSpecialObjectEqual = createCustomEqual({
24
- createCustomConfig: () => ({ areObjectsEqual }),
25
- });
26
- ```
@@ -1,75 +0,0 @@
1
- # Legacy environment support for circular equal comparators
2
-
3
- Starting in `4.x.x`, `WeakMap` is expected to be available in the environment. All modern browsers support this global object, however there may be situations where a legacy environmental support is required (example: IE11). If you need to support such an environment and polyfilling is not an option, creating a custom comparator that uses a custom cache implementation with the same contract is a simple solution.
4
-
5
- ```ts
6
- import { createCustomEqual, sameValueZeroEqual } from 'fast-equals';
7
- import type { Cache } from 'fast-equals';
8
-
9
- function getCache(): Cache<any, any> {
10
- const entries: Array<[object, any]> = [];
11
-
12
- return {
13
- delete(key) {
14
- for (let index = 0; index < entries.length; ++index) {
15
- if (entries[index][0] === key) {
16
- entries.splice(index, 1);
17
- return true;
18
- }
19
- }
20
-
21
- return false;
22
- },
23
-
24
- get(key) {
25
- for (let index = 0; index < entries.length; ++index) {
26
- if (entries[index][0] === key) {
27
- return entries[index][1];
28
- }
29
- }
30
- },
31
-
32
- set(key, value) {
33
- for (let index = 0; index < entries.length; ++index) {
34
- if (entries[index][0] === key) {
35
- entries[index][1] = value;
36
- return this;
37
- }
38
- }
39
-
40
- entries.push([key, value]);
41
-
42
- return this;
43
- },
44
- };
45
- }
46
-
47
- interface Meta {
48
- customMethod(): void;
49
- customValue: string;
50
- }
51
-
52
- const meta = {
53
- customMethod() {
54
- console.log('hello!');
55
- },
56
- customValue: 'goodbye',
57
- };
58
-
59
- const circularDeepEqual = createCustomEqual<Cache>({
60
- circular: true,
61
- createState: () => ({
62
- cache: getCache(),
63
- meta,
64
- }),
65
- });
66
-
67
- const circularShallowEqual = createCustomEqual<Cache>({
68
- circular: true,
69
- comparator: sameValueZeroEqual,
70
- createState: () => ({
71
- cache: getCache(),
72
- meta,
73
- }),
74
- });
75
- ```
@@ -1,24 +0,0 @@
1
- # Legacy environment support for `RegExp` comparators
2
-
3
- Starting in `4.x.x`, `RegExp.prototype.flags` is expected to be available in the environment. All modern browsers support this feature, however there may be situations where a legacy environmental support is required (example: IE11). If you need to support such an environment and polyfilling is not an option, creating a custom comparator that uses a more verbose comparison of all possible flags is a simple solution.
4
-
5
- ```ts
6
- import { createCustomEqual, sameValueZeroEqual } from 'deep-Equals';
7
-
8
- const areRegExpsEqual = (a: RegExp, b: RegExp) =>
9
- a.source === b.source &&
10
- a.global === b.global &&
11
- a.ignoreCase === b.ignoreCase &&
12
- a.multiline === b.multiline &&
13
- a.unicode === b.unicode &&
14
- a.sticky === b.sticky &&
15
- a.lastIndex === b.lastIndex;
16
-
17
- const deepEqual = createCustomEqual({
18
- createCustomConfig: () => ({ areRegExpsEqual }),
19
- });
20
- const shallowEqual = createCustomEqual({
21
- comparator: sameValueZero,
22
- createCustomConfig: () => ({ areRegExpsEqual }),
23
- });
24
- ```
@@ -1,48 +0,0 @@
1
- # Non-standard properties
2
-
3
- Sometimes, objects require a comparison that extend beyond its own keys, or even its own properties or symbols. Using a custom object comparator with `createCustomEqual` allows these kinds of comparisons.
4
-
5
- ```ts
6
- import { createCustomEqual } from 'fast-equals';
7
- import type { TypeEqualityComparator } from 'fast-equals';
8
-
9
- type AreObjectsEqual = TypeEqualityComparator<Record<any, any>, undefined>;
10
-
11
- class HiddenProperty {
12
- visible: boolean;
13
- #hidden: string;
14
-
15
- constructor(value: string) {
16
- this.visible = true;
17
- this.#hidden = value;
18
- }
19
-
20
- get hidden() {
21
- return this.#hidden;
22
- }
23
- }
24
-
25
- function createAreObjectsEqual(
26
- areObjectsEqual: AreObjectsEqual,
27
- ): AreObjectsEqual {
28
- return function (a, b, state) {
29
- if (!areObjectsEqual(a, b, state)) {
30
- return false;
31
- }
32
-
33
- const aInstance = a instanceof HiddenProperty;
34
- const bInstance = b instanceof HiddenProperty;
35
-
36
- if (aInstance || bInstance) {
37
- return aInstance && bInstance && a.hidden === b.hidden;
38
- }
39
-
40
- return true;
41
- };
42
- }
43
-
44
- const deepEqual = createCustomEqual({
45
- createCustomConfig: ({ areObjectsEqual }) =>
46
- createAreObjectsEqual(areObjectsEqual),
47
- });
48
- ```
@@ -1,25 +0,0 @@
1
- # Handling special (built-in) objects
2
-
3
- The `createCustomEqual` uses `@@toStringTag` to decide which well-known comparator to call. However, some values might not fit either of them. For example `WeakMap` is compared intentionally. Additionally, it's possible that new built-in objects are added to the language. Third parties might also add `@@toStringTag` to their objects.
4
-
5
- For example the [TC39 Temporal spec](https://tc39.es/proposal-temporal/docs/) requires `@@toStringTag` being implemetend and the polyfills do that. Passing `areObjectsEqual` will not work in that scenario. Instead you'll have to register a handler for the tag instead.
6
-
7
- ```ts
8
- import { createCustomEqual } from 'fast-equals';
9
- import type { TypeEqualityComparator } from 'fast-equals';
10
-
11
- const areZonedDateTimesEqual: TypeEqualityComparator<unknown, undefined> = (
12
- a,
13
- b,
14
- ) => a instanceof Temporal.ZonedDateTime
15
- && b instanceof Temporal.ZonedDateTime
16
- && a.equals(b);
17
-
18
- const isSpecialObjectEqual = createCustomEqual({
19
- createCustomConfig: () => ({
20
- unknownTagComparators: {
21
- "Temporal.ZonedDateTime", areZonedDateTimesEqual,
22
- }
23
- }),
24
- });
25
- ```