fast-equals 5.0.0-beta.2 → 5.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -1,128 +1,34 @@
1
- import { createComparator } from './comparator';
2
- import {
3
- areArraysEqual,
4
- areDatesEqual,
5
- areMapsEqual,
6
- areObjectsEqual,
7
- areObjectsEqualStrict,
8
- arePrimitiveWrappersEqual,
9
- areRegExpsEqual,
10
- areSetsEqual,
11
- } from './equals';
1
+ import { createComparator, createComparatorConfig } from './comparator';
12
2
  import type {
13
3
  CircularState,
14
- ComparatorConfig,
15
- CreateCustomComparatorConfig,
16
- CreateState,
4
+ CustomEqualCreatorOptions,
17
5
  DefaultState,
18
- EqualityComparator,
19
6
  } from './internalTypes';
20
- import {
21
- combineComparators,
22
- createInternalComparator,
23
- createIsCircular,
24
- sameValueZeroEqual,
25
- } from './utils';
7
+ import { createInternalComparator, sameValueZeroEqual } from './utils';
26
8
 
27
9
  export { sameValueZeroEqual };
28
10
  export * from './internalTypes';
29
11
 
30
- interface DefaultEqualCreatorOptions<Meta> {
31
- comparator?: EqualityComparator<Meta>;
32
- circular?: boolean;
33
- strict?: boolean;
34
- }
35
-
36
- interface CustomEqualCreatorOptions<Meta>
37
- extends DefaultEqualCreatorOptions<Meta> {
38
- createCustomConfig?: CreateCustomComparatorConfig<Meta>;
39
- createInternalComparator?: typeof createInternalComparator;
40
- createState?: CreateState<Meta>;
41
- }
42
-
43
- function createComparatorConfig<Meta>({
44
- circular,
45
- strict,
46
- }: DefaultEqualCreatorOptions<Meta>) {
47
- const config: ComparatorConfig<Meta> = {
48
- areArraysEqual,
49
- areDatesEqual,
50
- areMapsEqual,
51
- areObjectsEqual,
52
- arePrimitiveWrappersEqual,
53
- areRegExpsEqual,
54
- areSetsEqual,
55
- };
56
-
57
- if (strict) {
58
- config.areArraysEqual = areObjectsEqual;
59
- config.areMapsEqual = combineComparators(areMapsEqual, areObjectsEqual);
60
- config.areObjectsEqual = areObjectsEqualStrict;
61
- config.areSetsEqual = combineComparators(areSetsEqual, areObjectsEqual);
62
- }
63
-
64
- if (circular) {
65
- config.areArraysEqual = createIsCircular(config.areArraysEqual);
66
- config.areMapsEqual = createIsCircular(config.areMapsEqual);
67
- config.areObjectsEqual = createIsCircular(config.areObjectsEqual);
68
- config.areSetsEqual = createIsCircular(config.areSetsEqual);
69
- }
70
-
71
- return config;
72
- }
73
-
74
- function createDefaultEqualCreator(
75
- options: DefaultEqualCreatorOptions<undefined> = {},
76
- ) {
77
- const config = createComparatorConfig(options);
78
- const isEqual = createComparator(config);
79
- const isEqualComparator =
80
- options.comparator || createInternalComparator(isEqual);
81
- const strict = !!options.strict;
82
-
83
- if (options.circular) {
84
- return function equals<A, B>(a: A, b: B): boolean {
85
- return isEqual(a, b, {
86
- cache: new WeakMap(),
87
- equals: isEqualComparator,
88
- meta: undefined,
89
- strict,
90
- });
91
- };
92
- }
93
-
94
- const state = Object.freeze({
95
- cache: undefined,
96
- equals: isEqualComparator,
97
- meta: undefined,
98
- strict,
99
- });
100
-
101
- return function equals<A, B>(a: A, b: B): boolean {
102
- return isEqual(a, b, state);
103
- };
104
- }
105
-
106
12
  /**
107
13
  * Whether the items passed are deeply-equal in value.
108
14
  */
109
- export const deepEqual = createDefaultEqualCreator();
15
+ export const deepEqual = createCustomEqual();
110
16
 
111
17
  /**
112
18
  * Whether the items passed are deeply-equal in value based on strict comparison.
113
19
  */
114
- export const strictDeepEqual = createDefaultEqualCreator({ strict: true });
20
+ export const strictDeepEqual = createCustomEqual({ strict: true });
115
21
 
116
22
  /**
117
23
  * Whether the items passed are deeply-equal in value, including circular references.
118
24
  */
119
- export const circularDeepEqual = createDefaultEqualCreator({ circular: true });
25
+ export const circularDeepEqual = createCustomEqual({ circular: true });
120
26
 
121
27
  /**
122
28
  * Whether the items passed are deeply-equal in value, including circular references,
123
29
  * based on strict comparison.
124
30
  */
125
- export const strictCircularDeepEqual = createDefaultEqualCreator({
31
+ export const strictCircularDeepEqual = createCustomEqual({
126
32
  circular: true,
127
33
  strict: true,
128
34
  });
@@ -130,14 +36,14 @@ export const strictCircularDeepEqual = createDefaultEqualCreator({
130
36
  /**
131
37
  * Whether the items passed are shallowly-equal in value.
132
38
  */
133
- export const shallowEqual = createDefaultEqualCreator({
39
+ export const shallowEqual = createCustomEqual({
134
40
  comparator: sameValueZeroEqual,
135
41
  });
136
42
 
137
43
  /**
138
44
  * Whether the items passed are shallowly-equal in value based on strict comparison
139
45
  */
140
- export const strictShallowEqual = createDefaultEqualCreator({
46
+ export const strictShallowEqual = createCustomEqual({
141
47
  comparator: sameValueZeroEqual,
142
48
  strict: true,
143
49
  });
@@ -145,7 +51,7 @@ export const strictShallowEqual = createDefaultEqualCreator({
145
51
  /**
146
52
  * Whether the items passed are shallowly-equal in value, including circular references.
147
53
  */
148
- export const circularShallowEqual = createDefaultEqualCreator({
54
+ export const circularShallowEqual = createCustomEqual({
149
55
  comparator: sameValueZeroEqual,
150
56
  circular: true,
151
57
  });
@@ -154,7 +60,7 @@ export const circularShallowEqual = createDefaultEqualCreator({
154
60
  * Whether the items passed are shallowly-equal in value, including circular references,
155
61
  * based on strict comparison.
156
62
  */
157
- export const strictCircularShallowEqual = createDefaultEqualCreator({
63
+ export const strictCircularShallowEqual = createCustomEqual({
158
64
  comparator: sameValueZeroEqual,
159
65
  circular: true,
160
66
  strict: true,
@@ -172,43 +78,50 @@ export function createCustomEqual<Meta>(
172
78
  options: CustomEqualCreatorOptions<Meta> = {},
173
79
  ) {
174
80
  const {
81
+ circular,
175
82
  comparator,
176
83
  createInternalComparator: createCustomInternalComparator,
177
- createCustomConfig,
178
84
  createState,
85
+ strict: baseStrict = false,
179
86
  } = options;
180
87
 
181
- const baseConfig = createComparatorConfig(options);
182
- const config = createCustomConfig
183
- ? Object.assign({}, baseConfig, createCustomConfig(baseConfig))
184
- : baseConfig;
185
- const isEqualCustom = comparator || createComparator(config);
186
- const isEqualCustomComparator = createCustomInternalComparator
187
- ? createCustomInternalComparator(isEqualCustom)
188
- : createInternalComparator(isEqualCustom);
189
- const strict = !!options.strict;
88
+ const config = createComparatorConfig<Meta>(options);
89
+ const isEqualCustom = createComparator(config);
90
+ const isEqualCustomComparator =
91
+ comparator ||
92
+ (createCustomInternalComparator
93
+ ? createCustomInternalComparator(isEqualCustom)
94
+ : createInternalComparator(isEqualCustom));
190
95
 
191
96
  if (createState) {
192
- return function isEqual<A, B>(a: A, b: B, metaOverride?: Meta): boolean {
193
- const customState = createState(isEqualCustom);
97
+ return function isEqual<A, B>(
98
+ a: A,
99
+ b: B,
100
+ metaOverride?: Meta | undefined,
101
+ ): boolean {
102
+ const {
103
+ cache = circular ? new WeakMap() : undefined,
104
+ equals = isEqualCustomComparator,
105
+ meta,
106
+ strict = baseStrict,
107
+ } = createState!(isEqualCustom);
194
108
 
195
109
  return isEqualCustom(a, b, {
196
- cache: customState.cache || new WeakMap(),
197
- equals: customState.equals || isEqualCustomComparator,
198
- // @ts-expect-error - inferred `Meta` may be undefined, which is okay
199
- meta: metaOverride !== undefined ? metaOverride : customState.meta,
200
- strict: customState.strict !== undefined ? customState.strict : strict,
201
- });
110
+ cache,
111
+ equals,
112
+ meta: metaOverride !== undefined ? metaOverride : meta,
113
+ strict,
114
+ } as CircularState<Meta>);
202
115
  };
203
116
  }
204
117
 
205
- if (options.circular) {
118
+ if (circular) {
206
119
  return function equals<A, B>(a: A, b: B): boolean {
207
120
  return isEqualCustom(a, b, {
208
121
  cache: new WeakMap(),
209
122
  equals: isEqualCustomComparator,
210
123
  meta: undefined as Meta,
211
- strict,
124
+ strict: baseStrict,
212
125
  } as CircularState<Meta>);
213
126
  };
214
127
  }
@@ -217,7 +130,7 @@ export function createCustomEqual<Meta>(
217
130
  cache: undefined,
218
131
  equals: isEqualCustomComparator,
219
132
  meta: undefined,
220
- strict,
133
+ strict: baseStrict,
221
134
  });
222
135
 
223
136
  return function equals<A, B>(a: A, b: B): boolean {
@@ -32,6 +32,7 @@ export interface ComparatorConfig<Meta> {
32
32
  arePrimitiveWrappersEqual: TypeEqualityComparator<any, Meta>;
33
33
  areRegExpsEqual: TypeEqualityComparator<any, Meta>;
34
34
  areSetsEqual: TypeEqualityComparator<any, Meta>;
35
+ areTypedArraysEqual: TypeEqualityComparator<any, Meta>;
35
36
  }
36
37
 
37
38
  export type CreateCustomComparatorConfig<Meta> = (
@@ -67,8 +68,30 @@ export type InternalEqualityComparator<Meta> = (
67
68
  state: State<Meta>,
68
69
  ) => boolean;
69
70
 
71
+ export type TypedArray =
72
+ | Float32Array
73
+ | Float64Array
74
+ | Int8Array
75
+ | Int16Array
76
+ | Int32Array
77
+ | Uint16Array
78
+ | Uint32Array
79
+ | Uint8Array
80
+ | Uint8ClampedArray;
81
+
70
82
  export type TypeEqualityComparator<Type, Meta = undefined> = (
71
83
  a: Type,
72
84
  b: Type,
73
85
  state: State<Meta>,
74
86
  ) => boolean;
87
+
88
+ export interface CustomEqualCreatorOptions<Meta> {
89
+ circular?: boolean;
90
+ comparator?: EqualityComparator<Meta>;
91
+ createCustomConfig?: CreateCustomComparatorConfig<Meta>;
92
+ createInternalComparator?: <Meta>(
93
+ compare: EqualityComparator<Meta>,
94
+ ) => InternalEqualityComparator<Meta>;
95
+ createState?: CreateState<Meta>;
96
+ strict?: boolean;
97
+ }
package/src/utils.ts CHANGED
@@ -12,6 +12,12 @@ import {
12
12
  const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
13
13
  const { hasOwnProperty } = Object.prototype;
14
14
 
15
+ const SUPPORTS_ARRAY_BUFFER =
16
+ typeof ArrayBuffer === 'function' && Boolean(ArrayBuffer.isView);
17
+
18
+ /**
19
+ * Combine two comparators into a single comparators.
20
+ */
15
21
  export function combineComparators<Meta>(
16
22
  comparatorA: AnyEqualityComparator<Meta>,
17
23
  comparatorB: AnyEqualityComparator<Meta>,
@@ -79,6 +85,10 @@ export function createIsCircular<
79
85
  } as AreItemsEqual;
80
86
  }
81
87
 
88
+ /**
89
+ * Get the properties to strictly examine, which include both own properties that are
90
+ * not enumerable and symbol properties.
91
+ */
82
92
  export function getStrictProperties(
83
93
  object: Dictionary,
84
94
  ): Array<string | symbol> {
@@ -87,11 +97,18 @@ export function getStrictProperties(
87
97
  );
88
98
  }
89
99
 
100
+ /**
101
+ * Whether the object contains the property passed as an own property.
102
+ */
90
103
  export const hasOwn =
91
104
  Object.hasOwn ||
92
105
  ((object: Dictionary, property: number | string | symbol) =>
93
106
  hasOwnProperty.call(object, property));
94
107
 
108
+ export function isArrayBuffer(value: any): value is ArrayBuffer {
109
+ return SUPPORTS_ARRAY_BUFFER && ArrayBuffer.isView(value);
110
+ }
111
+
95
112
  /**
96
113
  * Whether the values passed are strictly equal or both NaN.
97
114
  */