source: node_modules/es-toolkit/dist/predicate/isEqualWith.js

Last change on this file was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 6.6 KB
Line 
1'use strict';
2
3Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
5const isPlainObject = require('./isPlainObject.js');
6const getSymbols = require('../compat/_internal/getSymbols.js');
7const getTag = require('../compat/_internal/getTag.js');
8const tags = require('../compat/_internal/tags.js');
9const isEqualsSameValueZero = require('../_internal/isEqualsSameValueZero.js');
10
11function isEqualWith(a, b, areValuesEqual) {
12 return isEqualWithImpl(a, b, undefined, undefined, undefined, undefined, areValuesEqual);
13}
14function isEqualWithImpl(a, b, property, aParent, bParent, stack, areValuesEqual) {
15 const result = areValuesEqual(a, b, property, aParent, bParent, stack);
16 if (result !== undefined) {
17 return result;
18 }
19 if (typeof a === typeof b) {
20 switch (typeof a) {
21 case 'bigint':
22 case 'string':
23 case 'boolean':
24 case 'symbol':
25 case 'undefined': {
26 return a === b;
27 }
28 case 'number': {
29 return a === b || Object.is(a, b);
30 }
31 case 'function': {
32 return a === b;
33 }
34 case 'object': {
35 return areObjectsEqual(a, b, stack, areValuesEqual);
36 }
37 }
38 }
39 return areObjectsEqual(a, b, stack, areValuesEqual);
40}
41function areObjectsEqual(a, b, stack, areValuesEqual) {
42 if (Object.is(a, b)) {
43 return true;
44 }
45 let aTag = getTag.getTag(a);
46 let bTag = getTag.getTag(b);
47 if (aTag === tags.argumentsTag) {
48 aTag = tags.objectTag;
49 }
50 if (bTag === tags.argumentsTag) {
51 bTag = tags.objectTag;
52 }
53 if (aTag !== bTag) {
54 return false;
55 }
56 switch (aTag) {
57 case tags.stringTag:
58 return a.toString() === b.toString();
59 case tags.numberTag: {
60 const x = a.valueOf();
61 const y = b.valueOf();
62 return isEqualsSameValueZero.isEqualsSameValueZero(x, y);
63 }
64 case tags.booleanTag:
65 case tags.dateTag:
66 case tags.symbolTag:
67 return Object.is(a.valueOf(), b.valueOf());
68 case tags.regexpTag: {
69 return a.source === b.source && a.flags === b.flags;
70 }
71 case tags.functionTag: {
72 return a === b;
73 }
74 }
75 stack = stack ?? new Map();
76 const aStack = stack.get(a);
77 const bStack = stack.get(b);
78 if (aStack != null && bStack != null) {
79 return aStack === b;
80 }
81 stack.set(a, b);
82 stack.set(b, a);
83 try {
84 switch (aTag) {
85 case tags.mapTag: {
86 if (a.size !== b.size) {
87 return false;
88 }
89 for (const [key, value] of a.entries()) {
90 if (!b.has(key) || !isEqualWithImpl(value, b.get(key), key, a, b, stack, areValuesEqual)) {
91 return false;
92 }
93 }
94 return true;
95 }
96 case tags.setTag: {
97 if (a.size !== b.size) {
98 return false;
99 }
100 const aValues = Array.from(a.values());
101 const bValues = Array.from(b.values());
102 for (let i = 0; i < aValues.length; i++) {
103 const aValue = aValues[i];
104 const index = bValues.findIndex(bValue => {
105 return isEqualWithImpl(aValue, bValue, undefined, a, b, stack, areValuesEqual);
106 });
107 if (index === -1) {
108 return false;
109 }
110 bValues.splice(index, 1);
111 }
112 return true;
113 }
114 case tags.arrayTag:
115 case tags.uint8ArrayTag:
116 case tags.uint8ClampedArrayTag:
117 case tags.uint16ArrayTag:
118 case tags.uint32ArrayTag:
119 case tags.bigUint64ArrayTag:
120 case tags.int8ArrayTag:
121 case tags.int16ArrayTag:
122 case tags.int32ArrayTag:
123 case tags.bigInt64ArrayTag:
124 case tags.float32ArrayTag:
125 case tags.float64ArrayTag: {
126 if (typeof Buffer !== 'undefined' && Buffer.isBuffer(a) !== Buffer.isBuffer(b)) {
127 return false;
128 }
129 if (a.length !== b.length) {
130 return false;
131 }
132 for (let i = 0; i < a.length; i++) {
133 if (!isEqualWithImpl(a[i], b[i], i, a, b, stack, areValuesEqual)) {
134 return false;
135 }
136 }
137 return true;
138 }
139 case tags.arrayBufferTag: {
140 if (a.byteLength !== b.byteLength) {
141 return false;
142 }
143 return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
144 }
145 case tags.dataViewTag: {
146 if (a.byteLength !== b.byteLength || a.byteOffset !== b.byteOffset) {
147 return false;
148 }
149 return areObjectsEqual(new Uint8Array(a), new Uint8Array(b), stack, areValuesEqual);
150 }
151 case tags.errorTag: {
152 return a.name === b.name && a.message === b.message;
153 }
154 case tags.objectTag: {
155 const areEqualInstances = areObjectsEqual(a.constructor, b.constructor, stack, areValuesEqual) ||
156 (isPlainObject.isPlainObject(a) && isPlainObject.isPlainObject(b));
157 if (!areEqualInstances) {
158 return false;
159 }
160 const aKeys = [...Object.keys(a), ...getSymbols.getSymbols(a)];
161 const bKeys = [...Object.keys(b), ...getSymbols.getSymbols(b)];
162 if (aKeys.length !== bKeys.length) {
163 return false;
164 }
165 for (let i = 0; i < aKeys.length; i++) {
166 const propKey = aKeys[i];
167 const aProp = a[propKey];
168 if (!Object.hasOwn(b, propKey)) {
169 return false;
170 }
171 const bProp = b[propKey];
172 if (!isEqualWithImpl(aProp, bProp, propKey, a, b, stack, areValuesEqual)) {
173 return false;
174 }
175 }
176 return true;
177 }
178 default: {
179 return false;
180 }
181 }
182 }
183 finally {
184 stack.delete(a);
185 stack.delete(b);
186 }
187}
188
189exports.isEqualWith = isEqualWith;
Note: See TracBrowser for help on using the repository browser.