fast-equals 4.0.2 → 5.0.0-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 (71) hide show
  1. package/.babelrc +34 -0
  2. package/.prettierrc +4 -0
  3. package/CHANGELOG.md +43 -0
  4. package/README.md +146 -40
  5. package/build/rollup/config.base.js +49 -0
  6. package/build/rollup/config.cjs.js +10 -0
  7. package/build/rollup/config.esm.js +10 -0
  8. package/build/rollup/config.min.js +13 -0
  9. package/build/rollup/config.umd.js +10 -0
  10. package/build/tsconfig/base.json +32 -0
  11. package/build/tsconfig/cjs.json +8 -0
  12. package/build/tsconfig/declarations.json +9 -0
  13. package/build/tsconfig/esm.json +8 -0
  14. package/build/tsconfig/min.json +8 -0
  15. package/build/tsconfig/umd.json +8 -0
  16. package/build/webpack.config.js +57 -0
  17. package/dist/cjs/index.cjs +510 -0
  18. package/dist/cjs/index.cjs.map +1 -0
  19. package/dist/cjs/types/comparator.d.ts +2 -0
  20. package/dist/cjs/types/equals.d.ts +46 -0
  21. package/dist/cjs/types/index.d.ts +56 -0
  22. package/dist/cjs/types/internalTypes.d.ts +36 -0
  23. package/dist/cjs/types/utils.d.ts +19 -0
  24. package/dist/esm/index.mjs +499 -0
  25. package/dist/esm/index.mjs.map +1 -0
  26. package/dist/esm/types/comparator.d.ts +2 -0
  27. package/dist/esm/types/equals.d.ts +46 -0
  28. package/dist/esm/types/index.d.ts +56 -0
  29. package/dist/esm/types/internalTypes.d.ts +36 -0
  30. package/dist/esm/types/utils.d.ts +19 -0
  31. package/dist/min/index.js +1 -0
  32. package/dist/min/types/comparator.d.ts +2 -0
  33. package/dist/min/types/equals.d.ts +46 -0
  34. package/dist/min/types/index.d.ts +56 -0
  35. package/dist/min/types/internalTypes.d.ts +36 -0
  36. package/dist/min/types/utils.d.ts +19 -0
  37. package/dist/umd/index.js +516 -0
  38. package/dist/umd/index.js.map +1 -0
  39. package/dist/umd/types/comparator.d.ts +2 -0
  40. package/dist/umd/types/equals.d.ts +46 -0
  41. package/dist/umd/types/index.d.ts +56 -0
  42. package/dist/umd/types/internalTypes.d.ts +36 -0
  43. package/dist/umd/types/utils.d.ts +19 -0
  44. package/package.json +62 -41
  45. package/recipes/explicit-property-check.md +4 -6
  46. package/recipes/legacy-circular-equal-support.md +28 -20
  47. package/recipes/legacy-regexp-support.md +15 -16
  48. package/recipes/non-standard-properties.md +35 -23
  49. package/recipes/using-meta-in-comparison.md +10 -13
  50. package/src/comparator.ts +50 -47
  51. package/src/equals.ts +263 -0
  52. package/src/index.ts +183 -79
  53. package/src/internalTypes.ts +74 -0
  54. package/src/utils.ts +42 -49
  55. package/dist/fast-equals.cjs.js +0 -434
  56. package/dist/fast-equals.cjs.js.map +0 -1
  57. package/dist/fast-equals.esm.js +0 -424
  58. package/dist/fast-equals.esm.js.map +0 -1
  59. package/dist/fast-equals.js +0 -440
  60. package/dist/fast-equals.js.map +0 -1
  61. package/dist/fast-equals.min.js +0 -1
  62. package/dist/fast-equals.mjs +0 -424
  63. package/dist/fast-equals.mjs.map +0 -1
  64. package/index.d.ts +0 -58
  65. package/recipes/strict-property-descriptor-check.md +0 -42
  66. package/src/arrays.ts +0 -36
  67. package/src/dates.ts +0 -12
  68. package/src/maps.ts +0 -66
  69. package/src/objects.ts +0 -62
  70. package/src/regexps.ts +0 -11
  71. package/src/sets.ts +0 -61
@@ -1,424 +0,0 @@
1
- /**
2
- * Default equality comparator pass-through, used as the standard `isEqual` creator for
3
- * use inside the built comparator.
4
- */
5
- function createDefaultIsNestedEqual(comparator) {
6
- return function isEqual(a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, meta) {
7
- return comparator(a, b, meta);
8
- };
9
- }
10
- /**
11
- * Wrap the provided `areItemsEqual` method to manage the circular cache, allowing
12
- * for circular references to be safely included in the comparison without creating
13
- * stack overflows.
14
- */
15
- function createIsCircular(areItemsEqual) {
16
- return function isCircular(a, b, isEqual, cache) {
17
- if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
18
- return areItemsEqual(a, b, isEqual, cache);
19
- }
20
- var cachedA = cache.get(a);
21
- var cachedB = cache.get(b);
22
- if (cachedA && cachedB) {
23
- return cachedA === b && cachedB === a;
24
- }
25
- cache.set(a, b);
26
- cache.set(b, a);
27
- var result = areItemsEqual(a, b, isEqual, cache);
28
- cache.delete(a);
29
- cache.delete(b);
30
- return result;
31
- };
32
- }
33
- /**
34
- * Targeted shallow merge of two objects.
35
- *
36
- * @NOTE
37
- * This exists as a tinier compiled version of the `__assign` helper that
38
- * `tsc` injects in case of `Object.assign` not being present.
39
- */
40
- function merge(a, b) {
41
- var merged = {};
42
- for (var key in a) {
43
- merged[key] = a[key];
44
- }
45
- for (var key in b) {
46
- merged[key] = b[key];
47
- }
48
- return merged;
49
- }
50
- /**
51
- * Whether the value is a plain object.
52
- *
53
- * @NOTE
54
- * This is a same-realm compariosn only.
55
- */
56
- function isPlainObject(value) {
57
- return value.constructor === Object || value.constructor == null;
58
- }
59
- /**
60
- * When the value is `Promise`-like, aka "then-able".
61
- */
62
- function isPromiseLike(value) {
63
- return typeof value.then === 'function';
64
- }
65
- /**
66
- * Whether the values passed are strictly equal or both NaN.
67
- */
68
- var sameValueZeroEqual = Object.is ||
69
- function sameValueZeroEqual(a, b) {
70
- return a === b || (a !== a && b !== b);
71
- };
72
-
73
- var ARGUMENTS_TAG = '[object Arguments]';
74
- var BOOLEAN_TAG = '[object Boolean]';
75
- var DATE_TAG = '[object Date]';
76
- var REG_EXP_TAG = '[object RegExp]';
77
- var MAP_TAG = '[object Map]';
78
- var NUMBER_TAG = '[object Number]';
79
- var OBJECT_TAG = '[object Object]';
80
- var SET_TAG = '[object Set]';
81
- var STRING_TAG = '[object String]';
82
- var toString = Object.prototype.toString;
83
- function createComparator(_a) {
84
- var areArraysEqual = _a.areArraysEqual, areDatesEqual = _a.areDatesEqual, areMapsEqual = _a.areMapsEqual, areObjectsEqual = _a.areObjectsEqual, areRegExpsEqual = _a.areRegExpsEqual, areSetsEqual = _a.areSetsEqual, createIsNestedEqual = _a.createIsNestedEqual;
85
- var isEqual = createIsNestedEqual(comparator);
86
- /**
87
- * compare the value of the two objects and return true if they are equivalent in values
88
- */
89
- function comparator(a, b, meta) {
90
- // If the items are strictly equal, no need to do a value comparison.
91
- if (a === b) {
92
- return true;
93
- }
94
- // If the items are not non-nullish objects, then the only possibility
95
- // of them being equal but not strictly is if they are both `NaN`. Since
96
- // `NaN` is uniquely not equal to itself, we can use self-comparison of
97
- // both objects, which is faster than `isNaN()`.
98
- if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
99
- return a !== a && b !== b;
100
- }
101
- // Checks are listed in order of commonality of use-case:
102
- // 1. Common complex object types (plain object, array)
103
- // 2. Common data values (date, regexp)
104
- // 3. Less-common complex object types (map, set)
105
- // 4. Less-common data values (promise, primitive wrappers)
106
- // Inherently this is both subjective and assumptive, however
107
- // when reviewing comparable libraries in the wild this order
108
- // appears to be generally consistent.
109
- // `isPlainObject` only checks against the object's own realm. Cross-realm
110
- // comparisons are rare, and will be handled in the ultimate fallback, so
111
- // we can avoid the `toString.call()` cost unless necessary.
112
- if (isPlainObject(a) && isPlainObject(b)) {
113
- return areObjectsEqual(a, b, isEqual, meta);
114
- }
115
- // `isArray()` works on subclasses and is cross-realm, so we can again avoid
116
- // the `toString.call()` cost unless necessary by just checking if either
117
- // and then both are arrays.
118
- var aArray = Array.isArray(a);
119
- var bArray = Array.isArray(b);
120
- if (aArray || bArray) {
121
- return aArray === bArray && areArraysEqual(a, b, isEqual, meta);
122
- }
123
- // Since this is a custom object, use the classic `toString.call()` to get its
124
- // type. This is reasonably performant in modern environments like v8 and
125
- // SpiderMonkey, and allows for cross-realm comparison when other checks like
126
- // `instanceof` do not.
127
- var aTag = toString.call(a);
128
- if (aTag !== toString.call(b)) {
129
- return false;
130
- }
131
- if (aTag === DATE_TAG) {
132
- // `getTime()` showed better results compared to alternatives like `valueOf()`
133
- // or the unary `+` operator.
134
- return areDatesEqual(a, b, isEqual, meta);
135
- }
136
- if (aTag === REG_EXP_TAG) {
137
- return areRegExpsEqual(a, b, isEqual, meta);
138
- }
139
- if (aTag === MAP_TAG) {
140
- return areMapsEqual(a, b, isEqual, meta);
141
- }
142
- if (aTag === SET_TAG) {
143
- return areSetsEqual(a, b, isEqual, meta);
144
- }
145
- // If a simple object tag, then we can prioritize a simple object comparison because
146
- // it is likely a custom class. If an arguments tag, it should be treated as a standard
147
- // object.
148
- if (aTag === OBJECT_TAG || aTag === ARGUMENTS_TAG) {
149
- // The exception for value comparison is `Promise`-like contracts. These should be
150
- // treated the same as standard `Promise` objects, which means strict equality.
151
- return isPromiseLike(a) || isPromiseLike(b)
152
- ? a === b
153
- : areObjectsEqual(a, b, isEqual, meta);
154
- }
155
- // As the penultimate fallback, check if the values passed are primitive wrappers. This
156
- // is very rare in modern JS, which is why it is deprioritized compared to all other object
157
- // types.
158
- if (aTag === BOOLEAN_TAG || aTag === NUMBER_TAG || aTag === STRING_TAG) {
159
- return sameValueZeroEqual(a.valueOf(), b.valueOf());
160
- }
161
- // If not matching any tags that require a specific type of comparison, then use strict
162
- // equality. This is for a few reasons:
163
- // - For types that cannot be introspected (`Promise`, `WeakMap`, etc.), this is the only
164
- // comparison that can be made.
165
- // - For types that can be introspected, but rarely have requirements to be compared
166
- // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common
167
- // use-cases.
168
- // - For types that can be introspected, but do not have an objective definition of what
169
- // equality is (`Error`, etc.), the subjective decision was to be conservative.
170
- // In all cases, these decisions should be reevaluated based on changes to the language and
171
- // common development practices.
172
- return a === b;
173
- }
174
- return comparator;
175
- }
176
-
177
- /**
178
- * Whether the arrays are equal in value.
179
- */
180
- function areArraysEqual(a, b, isEqual, meta) {
181
- var index = a.length;
182
- if (b.length !== index) {
183
- return false;
184
- }
185
- // Decrementing `while` showed faster results than either incrementing or
186
- // decrementing `for` loop and than an incrementing `while` loop. Declarative
187
- // methods like `some` / `every` were not used to avoid incurring the garbage
188
- // cost of anonymous callbacks.
189
- while (index-- > 0) {
190
- if (!isEqual(a[index], b[index], index, index, a, b, meta)) {
191
- return false;
192
- }
193
- }
194
- return true;
195
- }
196
- /**
197
- * Whether the arrays are equal in value, including circular references.
198
- */
199
- var areArraysEqualCircular = createIsCircular(areArraysEqual);
200
-
201
- /**
202
- * Whether the dates passed are equal in value.
203
- *
204
- * @NOTE
205
- * This is a standalone function instead of done inline in the comparator
206
- * to allow for overrides.
207
- */
208
- function areDatesEqual(a, b) {
209
- return sameValueZeroEqual(a.valueOf(), b.valueOf());
210
- }
211
-
212
- /**
213
- * Whether the `Map`s are equal in value.
214
- */
215
- function areMapsEqual(a, b, isEqual, meta) {
216
- var isValueEqual = a.size === b.size;
217
- if (!isValueEqual) {
218
- return false;
219
- }
220
- if (!a.size) {
221
- return true;
222
- }
223
- // The use of `forEach()` is to avoid the transpilation cost of `for...of` comparisons, and
224
- // the inability to control the performance of the resulting code. It also avoids excessive
225
- // iteration compared to doing comparisons of `keys()` and `values()`. As a result, though,
226
- // we cannot short-circuit the iterations; bookkeeping must be done to short-circuit the
227
- // equality checks themselves.
228
- var matchedIndices = {};
229
- var indexA = 0;
230
- a.forEach(function (aValue, aKey) {
231
- if (!isValueEqual) {
232
- return;
233
- }
234
- var hasMatch = false;
235
- var matchIndexB = 0;
236
- b.forEach(function (bValue, bKey) {
237
- if (!hasMatch &&
238
- !matchedIndices[matchIndexB] &&
239
- (hasMatch =
240
- isEqual(aKey, bKey, indexA, matchIndexB, a, b, meta) &&
241
- isEqual(aValue, bValue, aKey, bKey, a, b, meta))) {
242
- matchedIndices[matchIndexB] = true;
243
- }
244
- matchIndexB++;
245
- });
246
- indexA++;
247
- isValueEqual = hasMatch;
248
- });
249
- return isValueEqual;
250
- }
251
- /**
252
- * Whether the `Map`s are equal in value, including circular references.
253
- */
254
- var areMapsEqualCircular = createIsCircular(areMapsEqual);
255
-
256
- var OWNER = '_owner';
257
- var hasOwnProperty = Object.prototype.hasOwnProperty;
258
- var getProperties = Object.keys;
259
- /**
260
- * Whether the objects are equal in value.
261
- */
262
- function areObjectsEqual(a, b, isEqual, meta) {
263
- var keysA = getProperties(a);
264
- var index = keysA.length;
265
- if (getProperties(b).length !== index) {
266
- return false;
267
- }
268
- var key;
269
- // Decrementing `while` showed faster results than either incrementing or
270
- // decrementing `for` loop and than an incrementing `while` loop. Declarative
271
- // methods like `some` / `every` were not used to avoid incurring the garbage
272
- // cost of anonymous callbacks.
273
- while (index-- > 0) {
274
- key = keysA[index];
275
- if (key === OWNER) {
276
- var reactElementA = !!a.$$typeof;
277
- var reactElementB = !!b.$$typeof;
278
- if ((reactElementA || reactElementB) && reactElementA !== reactElementB) {
279
- return false;
280
- }
281
- }
282
- if (!hasOwnProperty.call(b, key) ||
283
- !isEqual(a[key], b[key], key, key, a, b, meta)) {
284
- return false;
285
- }
286
- }
287
- return true;
288
- }
289
- /**
290
- * Whether the objects are equal in value, including circular references.
291
- */
292
- var areObjectsEqualCircular = createIsCircular(areObjectsEqual);
293
-
294
- /**
295
- * Whether the regexps passed are equal in value.
296
- *
297
- * @NOTE
298
- * This is a standalone function instead of done inline in the comparator
299
- * to allow for overrides. An example of this would be supporting a
300
- * pre-ES2015 environment where the `flags` property is not available.
301
- */
302
- function areRegExpsEqual(a, b) {
303
- return a.source === b.source && a.flags === b.flags;
304
- }
305
-
306
- /**
307
- * Whether the `Set`s are equal in value.
308
- */
309
- function areSetsEqual(a, b, isEqual, meta) {
310
- var isValueEqual = a.size === b.size;
311
- if (!isValueEqual) {
312
- return false;
313
- }
314
- if (!a.size) {
315
- return true;
316
- }
317
- // The use of `forEach()` is to avoid the transpilation cost of `for...of` comparisons, and
318
- // the inability to control the performance of the resulting code. It also avoids excessive
319
- // iteration compared to doing comparisons of `keys()` and `values()`. As a result, though,
320
- // we cannot short-circuit the iterations; bookkeeping must be done to short-circuit the
321
- // equality checks themselves.
322
- var matchedIndices = {};
323
- a.forEach(function (aValue, aKey) {
324
- if (!isValueEqual) {
325
- return;
326
- }
327
- var hasMatch = false;
328
- var matchIndex = 0;
329
- b.forEach(function (bValue, bKey) {
330
- if (!hasMatch &&
331
- !matchedIndices[matchIndex] &&
332
- (hasMatch = isEqual(aValue, bValue, aKey, bKey, a, b, meta))) {
333
- matchedIndices[matchIndex] = true;
334
- }
335
- matchIndex++;
336
- });
337
- isValueEqual = hasMatch;
338
- });
339
- return isValueEqual;
340
- }
341
- /**
342
- * Whether the `Set`s are equal in value, including circular references.
343
- */
344
- var areSetsEqualCircular = createIsCircular(areSetsEqual);
345
-
346
- var DEFAULT_CONFIG = Object.freeze({
347
- areArraysEqual: areArraysEqual,
348
- areDatesEqual: areDatesEqual,
349
- areMapsEqual: areMapsEqual,
350
- areObjectsEqual: areObjectsEqual,
351
- areRegExpsEqual: areRegExpsEqual,
352
- areSetsEqual: areSetsEqual,
353
- createIsNestedEqual: createDefaultIsNestedEqual,
354
- });
355
- var DEFAULT_CIRCULAR_CONFIG = Object.freeze({
356
- areArraysEqual: areArraysEqualCircular,
357
- areDatesEqual: areDatesEqual,
358
- areMapsEqual: areMapsEqualCircular,
359
- areObjectsEqual: areObjectsEqualCircular,
360
- areRegExpsEqual: areRegExpsEqual,
361
- areSetsEqual: areSetsEqualCircular,
362
- createIsNestedEqual: createDefaultIsNestedEqual,
363
- });
364
- var isDeepEqual = createComparator(DEFAULT_CONFIG);
365
- /**
366
- * Whether the items passed are deeply-equal in value.
367
- */
368
- function deepEqual(a, b) {
369
- return isDeepEqual(a, b, undefined);
370
- }
371
- var isShallowEqual = createComparator(merge(DEFAULT_CONFIG, { createIsNestedEqual: function () { return sameValueZeroEqual; } }));
372
- /**
373
- * Whether the items passed are shallowly-equal in value.
374
- */
375
- function shallowEqual(a, b) {
376
- return isShallowEqual(a, b, undefined);
377
- }
378
- var isCircularDeepEqual = createComparator(DEFAULT_CIRCULAR_CONFIG);
379
- /**
380
- * Whether the items passed are deeply-equal in value, including circular references.
381
- */
382
- function circularDeepEqual(a, b) {
383
- return isCircularDeepEqual(a, b, new WeakMap());
384
- }
385
- var isCircularShallowEqual = createComparator(merge(DEFAULT_CIRCULAR_CONFIG, {
386
- createIsNestedEqual: function () { return sameValueZeroEqual; },
387
- }));
388
- /**
389
- * Whether the items passed are shallowly-equal in value, including circular references.
390
- */
391
- function circularShallowEqual(a, b) {
392
- return isCircularShallowEqual(a, b, new WeakMap());
393
- }
394
- /**
395
- * Create a custom equality comparison method.
396
- *
397
- * This can be done to create very targeted comparisons in extreme hot-path scenarios
398
- * where the standard methods are not performant enough, but can also be used to provide
399
- * support for legacy environments that do not support expected features like
400
- * `RegExp.prototype.flags` out of the box.
401
- */
402
- function createCustomEqual(getComparatorOptions) {
403
- return createComparator(merge(DEFAULT_CONFIG, getComparatorOptions(DEFAULT_CONFIG)));
404
- }
405
- /**
406
- * Create a custom equality comparison method that handles circular references. This is very
407
- * similar to `createCustomEqual`, with the only difference being that `meta` expects to be
408
- * populated with a `WeakMap`-like contract.
409
- *
410
- * This can be done to create very targeted comparisons in extreme hot-path scenarios
411
- * where the standard methods are not performant enough, but can also be used to provide
412
- * support for legacy environments that do not support expected features like
413
- * `WeakMap` out of the box.
414
- */
415
- function createCustomCircularEqual(getComparatorOptions) {
416
- var comparator = createComparator(merge(DEFAULT_CIRCULAR_CONFIG, getComparatorOptions(DEFAULT_CIRCULAR_CONFIG)));
417
- return (function (a, b, meta) {
418
- if (meta === void 0) { meta = new WeakMap(); }
419
- return comparator(a, b, meta);
420
- });
421
- }
422
-
423
- export { circularDeepEqual, circularShallowEqual, createCustomCircularEqual, createCustomEqual, deepEqual, sameValueZeroEqual, shallowEqual };
424
- //# sourceMappingURL=fast-equals.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fast-equals.mjs","sources":["../src/utils.ts","../src/comparator.ts","../src/arrays.ts","../src/dates.ts","../src/maps.ts","../src/objects.ts","../src/regexps.ts","../src/sets.ts","../src/index.ts"],"sourcesContent":["import {\n EqualityComparator,\n InternalEqualityComparator,\n TypeEqualityComparator,\n} from '../index.d';\n\n/**\n * Default equality comparator pass-through, used as the standard `isEqual` creator for\n * use inside the built comparator.\n */\nexport function createDefaultIsNestedEqual<Meta>(\n comparator: EqualityComparator<Meta>,\n): InternalEqualityComparator<Meta> {\n return function isEqual<A, B>(\n a: A,\n b: B,\n _indexOrKeyA: any,\n _indexOrKeyB: any,\n _parentA: any,\n _parentB: any,\n meta: Meta,\n ) {\n return comparator(a, b, meta);\n };\n}\n\n/**\n * Wrap the provided `areItemsEqual` method to manage the circular cache, allowing\n * for circular references to be safely included in the comparison without creating\n * stack overflows.\n */\nexport function createIsCircular<\n AreItemsEqual extends TypeEqualityComparator<any, any>,\n>(areItemsEqual: AreItemsEqual): AreItemsEqual {\n return function isCircular(\n a: any,\n b: any,\n isEqual: InternalEqualityComparator<WeakMap<any, any>>,\n cache: WeakMap<any, any>,\n ) {\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return areItemsEqual(a, b, isEqual, cache);\n }\n\n const cachedA = cache.get(a);\n const cachedB = cache.get(b);\n\n if (cachedA && cachedB) {\n return cachedA === b && cachedB === a;\n }\n\n cache.set(a, b);\n cache.set(b, a);\n\n const result = areItemsEqual(a, b, isEqual, cache);\n\n cache.delete(a);\n cache.delete(b);\n\n return result;\n } as AreItemsEqual;\n}\n\n/**\n * Targeted shallow merge of two objects.\n *\n * @NOTE\n * This exists as a tinier compiled version of the `__assign` helper that\n * `tsc` injects in case of `Object.assign` not being present.\n */\nexport function merge<A extends object, B extends object>(a: A, b: B): A & B {\n const merged: Record<string, any> = {};\n\n for (const key in a) {\n merged[key] = a[key];\n }\n\n for (const key in b) {\n merged[key] = b[key];\n }\n\n return merged as A & B;\n}\n\n/**\n * Whether the value is a plain object.\n *\n * @NOTE\n * This is a same-realm compariosn only.\n */\nexport function isPlainObject(value: any): boolean {\n return value.constructor === Object || value.constructor == null;\n}\n\n/**\n * When the value is `Promise`-like, aka \"then-able\".\n */\nexport function isPromiseLike(value: any): boolean {\n return typeof value.then === 'function';\n}\n\n/**\n * Whether the values passed are strictly equal or both NaN.\n */\nexport const sameValueZeroEqual =\n Object.is ||\n function sameValueZeroEqual(a: any, b: any): boolean {\n return a === b || (a !== a && b !== b);\n };\n","import { isPlainObject, isPromiseLike, sameValueZeroEqual } from './utils';\n\nimport type {\n CreateComparatorCreatorOptions,\n EqualityComparator,\n} from '../index.d';\n\nconst ARGUMENTS_TAG = '[object Arguments]';\nconst BOOLEAN_TAG = '[object Boolean]';\nconst DATE_TAG = '[object Date]';\nconst REG_EXP_TAG = '[object RegExp]';\nconst MAP_TAG = '[object Map]';\nconst NUMBER_TAG = '[object Number]';\nconst OBJECT_TAG = '[object Object]';\nconst SET_TAG = '[object Set]';\nconst STRING_TAG = '[object String]';\n\nconst { toString } = Object.prototype;\n\nexport function createComparator<Meta>({\n areArraysEqual,\n areDatesEqual,\n areMapsEqual,\n areObjectsEqual,\n areRegExpsEqual,\n areSetsEqual,\n createIsNestedEqual,\n}: CreateComparatorCreatorOptions<Meta>): EqualityComparator<Meta> {\n const isEqual = createIsNestedEqual(comparator as EqualityComparator<Meta>);\n\n /**\n * compare the value of the two objects and return true if they are equivalent in values\n */\n function comparator(a: any, b: any, meta: Meta): boolean {\n // If the items are strictly equal, no need to do a value comparison.\n if (a === b) {\n return true;\n }\n\n // If the items are not non-nullish objects, then the only possibility\n // of them being equal but not strictly is if they are both `NaN`. Since\n // `NaN` is uniquely not equal to itself, we can use self-comparison of\n // both objects, which is faster than `isNaN()`.\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {\n return a !== a && b !== b;\n }\n\n // Checks are listed in order of commonality of use-case:\n // 1. Common complex object types (plain object, array)\n // 2. Common data values (date, regexp)\n // 3. Less-common complex object types (map, set)\n // 4. Less-common data values (promise, primitive wrappers)\n // Inherently this is both subjective and assumptive, however\n // when reviewing comparable libraries in the wild this order\n // appears to be generally consistent.\n\n // `isPlainObject` only checks against the object's own realm. Cross-realm\n // comparisons are rare, and will be handled in the ultimate fallback, so\n // we can avoid the `toString.call()` cost unless necessary.\n if (isPlainObject(a) && isPlainObject(b)) {\n return areObjectsEqual(a, b, isEqual, meta);\n }\n\n // `isArray()` works on subclasses and is cross-realm, so we can again avoid\n // the `toString.call()` cost unless necessary by just checking if either\n // and then both are arrays.\n const aArray = Array.isArray(a);\n const bArray = Array.isArray(b);\n\n if (aArray || bArray) {\n return aArray === bArray && areArraysEqual(a, b, isEqual, meta);\n }\n\n // Since this is a custom object, use the classic `toString.call()` to get its\n // type. This is reasonably performant in modern environments like v8 and\n // SpiderMonkey, and allows for cross-realm comparison when other checks like\n // `instanceof` do not.\n const aTag = toString.call(a);\n\n if (aTag !== toString.call(b)) {\n return false;\n }\n\n if (aTag === DATE_TAG) {\n // `getTime()` showed better results compared to alternatives like `valueOf()`\n // or the unary `+` operator.\n return areDatesEqual(a, b, isEqual, meta);\n }\n\n if (aTag === REG_EXP_TAG) {\n return areRegExpsEqual(a, b, isEqual, meta);\n }\n\n if (aTag === MAP_TAG) {\n return areMapsEqual(a, b, isEqual, meta);\n }\n\n if (aTag === SET_TAG) {\n return areSetsEqual(a, b, isEqual, meta);\n }\n\n // If a simple object tag, then we can prioritize a simple object comparison because\n // it is likely a custom class. If an arguments tag, it should be treated as a standard\n // object.\n if (aTag === OBJECT_TAG || aTag === ARGUMENTS_TAG) {\n // The exception for value comparison is `Promise`-like contracts. These should be\n // treated the same as standard `Promise` objects, which means strict equality.\n return isPromiseLike(a) || isPromiseLike(b)\n ? a === b\n : areObjectsEqual(a, b, isEqual, meta);\n }\n\n // As the penultimate fallback, check if the values passed are primitive wrappers. This\n // is very rare in modern JS, which is why it is deprioritized compared to all other object\n // types.\n if (aTag === BOOLEAN_TAG || aTag === NUMBER_TAG || aTag === STRING_TAG) {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n }\n\n // If not matching any tags that require a specific type of comparison, then use strict\n // equality. This is for a few reasons:\n // - For types that cannot be introspected (`Promise`, `WeakMap`, etc.), this is the only\n // comparison that can be made.\n // - For types that can be introspected, but rarely have requirements to be compared\n // (`ArrayBuffer`, `DataView`, etc.), the cost is avoided to prioritize the common\n // use-cases.\n // - For types that can be introspected, but do not have an objective definition of what\n // equality is (`Error`, etc.), the subjective decision was to be conservative.\n // In all cases, these decisions should be reevaluated based on changes to the language and\n // common development practices.\n return a === b;\n }\n\n return comparator as EqualityComparator<Meta>;\n}\n","import { createIsCircular } from './utils';\n\nimport type { InternalEqualityComparator } from '../index.d';\n\n/**\n * Whether the arrays are equal in value.\n */\nexport function areArraysEqual(\n a: any[],\n b: any[],\n isEqual: InternalEqualityComparator<any>,\n meta: any,\n): boolean {\n let index = a.length;\n\n if (b.length !== index) {\n return false;\n }\n\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n if (!isEqual(a[index], b[index], index, index, a, b, meta)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether the arrays are equal in value, including circular references.\n */\nexport const areArraysEqualCircular = createIsCircular(areArraysEqual);\n","import { sameValueZeroEqual } from './utils';\n\n/**\n * Whether the dates passed are equal in value.\n *\n * @NOTE\n * This is a standalone function instead of done inline in the comparator\n * to allow for overrides.\n */\nexport function areDatesEqual(a: Date, b: Date): boolean {\n return sameValueZeroEqual(a.valueOf(), b.valueOf());\n}\n","import { createIsCircular } from './utils';\n\nimport type { InternalEqualityComparator } from '../index.d';\n\n/**\n * Whether the `Map`s are equal in value.\n */\nexport function areMapsEqual(\n a: Map<any, any>,\n b: Map<any, any>,\n isEqual: InternalEqualityComparator<any>,\n meta: any,\n): boolean {\n let isValueEqual = a.size === b.size;\n\n if (!isValueEqual) {\n return false;\n }\n\n if (!a.size) {\n return true;\n }\n\n // The use of `forEach()` is to avoid the transpilation cost of `for...of` comparisons, and\n // the inability to control the performance of the resulting code. It also avoids excessive\n // iteration compared to doing comparisons of `keys()` and `values()`. As a result, though,\n // we cannot short-circuit the iterations; bookkeeping must be done to short-circuit the\n // equality checks themselves.\n\n const matchedIndices: Record<number, true> = {};\n\n let indexA = 0;\n\n a.forEach((aValue, aKey) => {\n if (!isValueEqual) {\n return;\n }\n\n let hasMatch = false;\n let matchIndexB = 0;\n\n b.forEach((bValue, bKey) => {\n if (\n !hasMatch &&\n !matchedIndices[matchIndexB] &&\n (hasMatch =\n isEqual(aKey, bKey, indexA, matchIndexB, a, b, meta) &&\n isEqual(aValue, bValue, aKey, bKey, a, b, meta))\n ) {\n matchedIndices[matchIndexB] = true;\n }\n\n matchIndexB++;\n });\n\n indexA++;\n isValueEqual = hasMatch;\n });\n\n return isValueEqual;\n}\n\n/**\n * Whether the `Map`s are equal in value, including circular references.\n */\nexport const areMapsEqualCircular = createIsCircular(areMapsEqual);\n","import { createIsCircular } from './utils';\n\nimport type { InternalEqualityComparator } from '../index.d';\n\ninterface Dictionary<Value> {\n [key: string]: Value;\n $$typeof?: any;\n}\n\nconst OWNER = '_owner';\nconst { hasOwnProperty } = Object.prototype;\nconst getProperties = Object.keys;\n\n/**\n * Whether the objects are equal in value.\n */\nexport function areObjectsEqual(\n a: Dictionary<any>,\n b: Dictionary<any>,\n isEqual: InternalEqualityComparator<any>,\n meta: any,\n): boolean {\n const keysA = getProperties(a);\n\n let index = keysA.length;\n\n if (getProperties(b).length !== index) {\n return false;\n }\n\n let key: string;\n\n // Decrementing `while` showed faster results than either incrementing or\n // decrementing `for` loop and than an incrementing `while` loop. Declarative\n // methods like `some` / `every` were not used to avoid incurring the garbage\n // cost of anonymous callbacks.\n while (index-- > 0) {\n key = keysA[index];\n\n if (key === OWNER) {\n const reactElementA = !!a.$$typeof;\n const reactElementB = !!b.$$typeof;\n\n if ((reactElementA || reactElementB) && reactElementA !== reactElementB) {\n return false;\n }\n }\n\n if (\n !hasOwnProperty.call(b, key) ||\n !isEqual(a[key], b[key], key, key, a, b, meta)\n ) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether the objects are equal in value, including circular references.\n */\nexport const areObjectsEqualCircular = createIsCircular(areObjectsEqual);\n","/**\n * Whether the regexps passed are equal in value.\n *\n * @NOTE\n * This is a standalone function instead of done inline in the comparator\n * to allow for overrides. An example of this would be supporting a\n * pre-ES2015 environment where the `flags` property is not available.\n */\nexport function areRegExpsEqual(a: RegExp, b: RegExp): boolean {\n return a.source === b.source && a.flags === b.flags;\n}\n","import { createIsCircular } from './utils';\n\nimport type { InternalEqualityComparator } from '../index.d';\n\n/**\n * Whether the `Set`s are equal in value.\n */\nexport function areSetsEqual(\n a: Set<any>,\n b: Set<any>,\n isEqual: InternalEqualityComparator<any>,\n meta: any,\n): boolean {\n let isValueEqual = a.size === b.size;\n\n if (!isValueEqual) {\n return false;\n }\n\n if (!a.size) {\n return true;\n }\n\n // The use of `forEach()` is to avoid the transpilation cost of `for...of` comparisons, and\n // the inability to control the performance of the resulting code. It also avoids excessive\n // iteration compared to doing comparisons of `keys()` and `values()`. As a result, though,\n // we cannot short-circuit the iterations; bookkeeping must be done to short-circuit the\n // equality checks themselves.\n\n const matchedIndices: Record<number, true> = {};\n\n a.forEach((aValue, aKey) => {\n if (!isValueEqual) {\n return;\n }\n\n let hasMatch = false;\n let matchIndex = 0;\n\n b.forEach((bValue, bKey) => {\n if (\n !hasMatch &&\n !matchedIndices[matchIndex] &&\n (hasMatch = isEqual(aValue, bValue, aKey, bKey, a, b, meta))\n ) {\n matchedIndices[matchIndex] = true;\n }\n\n matchIndex++;\n });\n\n isValueEqual = hasMatch;\n });\n\n return isValueEqual;\n}\n\n/**\n * Whether the `Set`s are equal in value, including circular references.\n */\nexport const areSetsEqualCircular = createIsCircular(areSetsEqual);\n","import { createComparator } from './comparator';\nimport { areArraysEqual, areArraysEqualCircular } from './arrays';\nimport { areDatesEqual } from './dates';\nimport { areMapsEqual, areMapsEqualCircular } from './maps';\nimport { areObjectsEqual, areObjectsEqualCircular } from './objects';\nimport { areRegExpsEqual } from './regexps';\nimport { areSetsEqual, areSetsEqualCircular } from './sets';\nimport { createDefaultIsNestedEqual, merge, sameValueZeroEqual } from './utils';\n\nimport type {\n BaseCircularMeta,\n CreateComparatorCreatorOptions,\n EqualityComparator,\n GetComparatorOptions,\n} from '../index.d';\n\nexport { sameValueZeroEqual };\n\nconst DEFAULT_CONFIG: CreateComparatorCreatorOptions<undefined> = Object.freeze(\n {\n areArraysEqual,\n areDatesEqual,\n areMapsEqual,\n areObjectsEqual,\n areRegExpsEqual,\n areSetsEqual,\n createIsNestedEqual: createDefaultIsNestedEqual,\n },\n);\nconst DEFAULT_CIRCULAR_CONFIG: CreateComparatorCreatorOptions<BaseCircularMeta> =\n Object.freeze({\n areArraysEqual: areArraysEqualCircular,\n areDatesEqual,\n areMapsEqual: areMapsEqualCircular,\n areObjectsEqual: areObjectsEqualCircular,\n areRegExpsEqual,\n areSetsEqual: areSetsEqualCircular,\n createIsNestedEqual: createDefaultIsNestedEqual,\n });\n\nconst isDeepEqual = createComparator(DEFAULT_CONFIG);\n\n/**\n * Whether the items passed are deeply-equal in value.\n */\nexport function deepEqual<A, B>(a: A, b: B): boolean {\n return isDeepEqual(a, b, undefined);\n}\n\nconst isShallowEqual = createComparator(\n merge(DEFAULT_CONFIG, { createIsNestedEqual: () => sameValueZeroEqual }),\n);\n\n/**\n * Whether the items passed are shallowly-equal in value.\n */\nexport function shallowEqual<A, B>(a: A, b: B): boolean {\n return isShallowEqual(a, b, undefined);\n}\n\nconst isCircularDeepEqual = createComparator(DEFAULT_CIRCULAR_CONFIG);\n\n/**\n * Whether the items passed are deeply-equal in value, including circular references.\n */\nexport function circularDeepEqual<A, B>(a: A, b: B): boolean {\n return isCircularDeepEqual(a, b, new WeakMap());\n}\n\nconst isCircularShallowEqual = createComparator(\n merge(DEFAULT_CIRCULAR_CONFIG, {\n createIsNestedEqual: () => sameValueZeroEqual,\n }),\n);\n\n/**\n * Whether the items passed are shallowly-equal in value, including circular references.\n */\nexport function circularShallowEqual<A, B>(a: A, b: B): boolean {\n return isCircularShallowEqual(a, b, new WeakMap());\n}\n\n/**\n * Create a custom equality comparison method.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `RegExp.prototype.flags` out of the box.\n */\nexport function createCustomEqual<Meta = undefined>(\n getComparatorOptions: GetComparatorOptions<Meta>,\n): EqualityComparator<Meta> {\n return createComparator<Meta>(\n merge(DEFAULT_CONFIG, getComparatorOptions(DEFAULT_CONFIG as any)),\n );\n}\n\n/**\n * Create a custom equality comparison method that handles circular references. This is very\n * similar to `createCustomEqual`, with the only difference being that `meta` expects to be\n * populated with a `WeakMap`-like contract.\n *\n * This can be done to create very targeted comparisons in extreme hot-path scenarios\n * where the standard methods are not performant enough, but can also be used to provide\n * support for legacy environments that do not support expected features like\n * `WeakMap` out of the box.\n */\nexport function createCustomCircularEqual<\n Meta extends BaseCircularMeta = WeakMap<any, any>,\n>(getComparatorOptions: GetComparatorOptions<Meta>): EqualityComparator<Meta> {\n const comparator = createComparator<Meta>(\n merge(\n DEFAULT_CIRCULAR_CONFIG,\n getComparatorOptions(DEFAULT_CIRCULAR_CONFIG as any),\n ),\n );\n\n return ((a: any, b: any, meta: any = new WeakMap()) =>\n comparator(a, b, meta)) as EqualityComparator<Meta>;\n}\n"],"names":[],"mappings":"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"}
package/index.d.ts DELETED
@@ -1,58 +0,0 @@
1
- export interface BaseCircularMeta
2
- extends Pick<WeakMap<any, any>, 'delete' | 'get'> {
3
- set(key: object, value: any): any;
4
- }
5
-
6
- export interface CreateComparatorCreatorOptions<Meta> {
7
- areArraysEqual: TypeEqualityComparator<any, Meta>;
8
- areDatesEqual: TypeEqualityComparator<any, Meta>;
9
- areMapsEqual: TypeEqualityComparator<any, Meta>;
10
- areObjectsEqual: TypeEqualityComparator<any, Meta>;
11
- areRegExpsEqual: TypeEqualityComparator<any, Meta>;
12
- areSetsEqual: TypeEqualityComparator<any, Meta>;
13
- createIsNestedEqual: EqualityComparatorCreator<Meta>;
14
- }
15
-
16
- export type GetComparatorOptions<Meta> = (
17
- defaultOptions: CreateComparatorCreatorOptions<Meta>,
18
- ) => Partial<CreateComparatorCreatorOptions<Meta>>;
19
-
20
- export type InternalEqualityComparator<Meta> = (
21
- a: any,
22
- b: any,
23
- indexOrKeyA: any,
24
- indexOrKeyB: any,
25
- parentA: any,
26
- parentB: any,
27
- meta: Meta,
28
- ) => boolean;
29
-
30
- export type EqualityComparator<Meta> = Meta extends undefined
31
- ? <A, B>(a: A, b: B, meta?: Meta) => boolean
32
- : <A, B>(a: A, b: B, meta: Meta) => boolean;
33
-
34
- export type EqualityComparatorCreator<Meta> = (
35
- fn: EqualityComparator<Meta>,
36
- ) => InternalEqualityComparator<Meta>;
37
-
38
- export type NativeEqualityComparator = <A, B>(a: A, b: B) => boolean;
39
-
40
- export type TypeEqualityComparator<Type, Meta> = (
41
- a: Type,
42
- b: Type,
43
- isEqual: InternalEqualityComparator<Meta>,
44
- meta: Meta,
45
- ) => boolean;
46
-
47
- export function circularDeepEqual<A, B>(a: A, b: B): boolean;
48
- export function circularShallowEqual<A, B>(a: A, b: B): boolean;
49
- export function deepEqual<A, B>(a: A, b: B): boolean;
50
- export function shallowEqual<A, B>(a: A, b: B): boolean;
51
- export function sameValueZeroEqual<A, B>(a: A, b: B): boolean;
52
-
53
- export function createCustomEqual<Meta = undefined>(
54
- getComparatorOptions: GetComparatorOptions<Meta>,
55
- ): EqualityComparator<Meta>;
56
- export function createCustomCircularEqual<Meta = WeakMap<any, any>>(
57
- getComparatorOptions: GetComparatorOptions<Meta>,
58
- ): EqualityComparator<Meta>;
@@ -1,42 +0,0 @@
1
- # Non-standard properties
2
-
3
- The equality check done for objects prioritizes the common use-case, which is to only check an object's own keys. However, it is possible that the objects being compared require a stricter comparison of property descriptors.
4
-
5
- ```ts
6
- import { createCustomEqual } from 'fast-equals';
7
- import type { TypeEqualityComparator } from 'fast-equals';
8
-
9
- const areObjectsEqual: TypeEqualityComparator<Record<any, any>, undefined> = (
10
- a,
11
- b,
12
- ) => {
13
- const propertiesA = [
14
- ...Object.getOwnPropertyNames(a),
15
- ...Object.getOwnPropertySymbols(a),
16
- ];
17
- const propertiesB = [
18
- ...Object.getOwnPropertyNames(b),
19
- ...Object.getOwnPropertySymbols(b),
20
- ];
21
-
22
- if (propertiesA.length !== propertiesB.length) {
23
- return false;
24
- }
25
-
26
- return propertiesA.every((property) => {
27
- const descriptorA = Object.getOwnPropertyDescriptor(a, property);
28
- const descriptorB = Object.getOwnPropertyDescriptor(b, property);
29
-
30
- return (
31
- descriptorA &&
32
- descriptorB &&
33
- descriptorA.configurable === descriptorB.configurable &&
34
- descriptorA.enumerable === descriptorB.enumerable &&
35
- descriptorA.value === descriptorB.value &&
36
- descriptorA.writable === descriptorB.writable
37
- );
38
- });
39
- };
40
-
41
- const deepEqual = createCustomEqual(() => ({ areObjectsEqual }));
42
- ```
package/src/arrays.ts DELETED
@@ -1,36 +0,0 @@
1
- import { createIsCircular } from './utils';
2
-
3
- import type { InternalEqualityComparator } from '../index.d';
4
-
5
- /**
6
- * Whether the arrays are equal in value.
7
- */
8
- export function areArraysEqual(
9
- a: any[],
10
- b: any[],
11
- isEqual: InternalEqualityComparator<any>,
12
- meta: any,
13
- ): boolean {
14
- let index = a.length;
15
-
16
- if (b.length !== index) {
17
- return false;
18
- }
19
-
20
- // Decrementing `while` showed faster results than either incrementing or
21
- // decrementing `for` loop and than an incrementing `while` loop. Declarative
22
- // methods like `some` / `every` were not used to avoid incurring the garbage
23
- // cost of anonymous callbacks.
24
- while (index-- > 0) {
25
- if (!isEqual(a[index], b[index], index, index, a, b, meta)) {
26
- return false;
27
- }
28
- }
29
-
30
- return true;
31
- }
32
-
33
- /**
34
- * Whether the arrays are equal in value, including circular references.
35
- */
36
- export const areArraysEqualCircular = createIsCircular(areArraysEqual);
package/src/dates.ts DELETED
@@ -1,12 +0,0 @@
1
- import { sameValueZeroEqual } from './utils';
2
-
3
- /**
4
- * Whether the dates passed are equal in value.
5
- *
6
- * @NOTE
7
- * This is a standalone function instead of done inline in the comparator
8
- * to allow for overrides.
9
- */
10
- export function areDatesEqual(a: Date, b: Date): boolean {
11
- return sameValueZeroEqual(a.valueOf(), b.valueOf());
12
- }