1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, '__esModule', {
|
4 | value: true
|
5 | });
|
6 | exports.equals = equals;
|
7 | exports.fnNameFor = fnNameFor;
|
8 | exports.hasProperty = hasProperty;
|
9 | exports.isA = isA;
|
10 | exports.isImmutableUnorderedKeyed = isImmutableUnorderedKeyed;
|
11 | exports.isImmutableUnorderedSet = isImmutableUnorderedSet;
|
12 | exports.isUndefined = isUndefined;
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | function equals(a, b, customTesters, strictCheck) {
|
41 | customTesters = customTesters || [];
|
42 | return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey);
|
43 | }
|
44 |
|
45 | const functionToString = Function.prototype.toString;
|
46 |
|
47 | function isAsymmetric(obj) {
|
48 | return !!obj && isA('Function', obj.asymmetricMatch);
|
49 | }
|
50 |
|
51 | function asymmetricMatch(a, b) {
|
52 | var asymmetricA = isAsymmetric(a),
|
53 | asymmetricB = isAsymmetric(b);
|
54 |
|
55 | if (asymmetricA && asymmetricB) {
|
56 | return undefined;
|
57 | }
|
58 |
|
59 | if (asymmetricA) {
|
60 | return a.asymmetricMatch(b);
|
61 | }
|
62 |
|
63 | if (asymmetricB) {
|
64 | return b.asymmetricMatch(a);
|
65 | }
|
66 | }
|
67 |
|
68 |
|
69 | function eq(a, b, aStack, bStack, customTesters, hasKey) {
|
70 | var result = true;
|
71 | var asymmetricResult = asymmetricMatch(a, b);
|
72 |
|
73 | if (asymmetricResult !== undefined) {
|
74 | return asymmetricResult;
|
75 | }
|
76 |
|
77 | for (var i = 0; i < customTesters.length; i++) {
|
78 | var customTesterResult = customTesters[i](a, b);
|
79 |
|
80 | if (customTesterResult !== undefined) {
|
81 | return customTesterResult;
|
82 | }
|
83 | }
|
84 |
|
85 | if (a instanceof Error && b instanceof Error) {
|
86 | return a.message == b.message;
|
87 | }
|
88 |
|
89 | if (Object.is(a, b)) {
|
90 | return true;
|
91 | }
|
92 |
|
93 | if (a === null || b === null) {
|
94 | return a === b;
|
95 | }
|
96 |
|
97 | var className = Object.prototype.toString.call(a);
|
98 |
|
99 | if (className != Object.prototype.toString.call(b)) {
|
100 | return false;
|
101 | }
|
102 |
|
103 | switch (className) {
|
104 | case '[object Boolean]':
|
105 | case '[object String]':
|
106 | case '[object Number]':
|
107 | if (typeof a !== typeof b) {
|
108 |
|
109 | return false;
|
110 | } else if (typeof a !== 'object' && typeof b !== 'object') {
|
111 |
|
112 | return Object.is(a, b);
|
113 | } else {
|
114 |
|
115 | return Object.is(a.valueOf(), b.valueOf());
|
116 | }
|
117 |
|
118 | case '[object Date]':
|
119 |
|
120 |
|
121 |
|
122 | return +a == +b;
|
123 |
|
124 |
|
125 | case '[object RegExp]':
|
126 | return a.source === b.source && a.flags === b.flags;
|
127 | }
|
128 |
|
129 | if (typeof a !== 'object' || typeof b !== 'object') {
|
130 | return false;
|
131 | }
|
132 |
|
133 | if (isDomNode(a) && isDomNode(b)) {
|
134 | return a.isEqualNode(b);
|
135 | }
|
136 |
|
137 | var length = aStack.length;
|
138 |
|
139 | while (length--) {
|
140 |
|
141 |
|
142 |
|
143 |
|
144 | if (aStack[length] === a) {
|
145 | return bStack[length] === b;
|
146 | } else if (bStack[length] === b) {
|
147 | return false;
|
148 | }
|
149 | }
|
150 |
|
151 | aStack.push(a);
|
152 | bStack.push(b);
|
153 |
|
154 |
|
155 | if (className == '[object Array]' && a.length !== b.length) {
|
156 | return false;
|
157 | }
|
158 |
|
159 | var aKeys = keys(a, hasKey),
|
160 | key;
|
161 | var size = aKeys.length;
|
162 |
|
163 | if (keys(b, hasKey).length !== size) {
|
164 | return false;
|
165 | }
|
166 |
|
167 | while (size--) {
|
168 | key = aKeys[size];
|
169 |
|
170 | result =
|
171 | hasKey(b, key) &&
|
172 | eq(a[key], b[key], aStack, bStack, customTesters, hasKey);
|
173 |
|
174 | if (!result) {
|
175 | return false;
|
176 | }
|
177 | }
|
178 |
|
179 | aStack.pop();
|
180 | bStack.pop();
|
181 | return result;
|
182 | }
|
183 |
|
184 | function keys(obj, hasKey) {
|
185 | var keys = [];
|
186 |
|
187 | for (var key in obj) {
|
188 | if (hasKey(obj, key)) {
|
189 | keys.push(key);
|
190 | }
|
191 | }
|
192 |
|
193 | return keys.concat(
|
194 | Object.getOwnPropertySymbols(obj).filter(
|
195 | symbol => Object.getOwnPropertyDescriptor(obj, symbol).enumerable
|
196 | )
|
197 | );
|
198 | }
|
199 |
|
200 | function hasDefinedKey(obj, key) {
|
201 | return hasKey(obj, key) && obj[key] !== undefined;
|
202 | }
|
203 |
|
204 | function hasKey(obj, key) {
|
205 | return Object.prototype.hasOwnProperty.call(obj, key);
|
206 | }
|
207 |
|
208 | function isA(typeName, value) {
|
209 | return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
|
210 | }
|
211 |
|
212 | function isDomNode(obj) {
|
213 | return (
|
214 | obj !== null &&
|
215 | typeof obj === 'object' &&
|
216 | typeof obj.nodeType === 'number' &&
|
217 | typeof obj.nodeName === 'string' &&
|
218 | typeof obj.isEqualNode === 'function'
|
219 | );
|
220 | }
|
221 |
|
222 | function fnNameFor(func) {
|
223 | if (func.name) {
|
224 | return func.name;
|
225 | }
|
226 |
|
227 | const matches = functionToString
|
228 | .call(func)
|
229 | .match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/);
|
230 | return matches ? matches[1] : '<anonymous>';
|
231 | }
|
232 |
|
233 | function isUndefined(obj) {
|
234 | return obj === void 0;
|
235 | }
|
236 |
|
237 | function getPrototype(obj) {
|
238 | if (Object.getPrototypeOf) {
|
239 | return Object.getPrototypeOf(obj);
|
240 | }
|
241 |
|
242 | if (obj.constructor.prototype == obj) {
|
243 | return null;
|
244 | }
|
245 |
|
246 | return obj.constructor.prototype;
|
247 | }
|
248 |
|
249 | function hasProperty(obj, property) {
|
250 | if (!obj) {
|
251 | return false;
|
252 | }
|
253 |
|
254 | if (Object.prototype.hasOwnProperty.call(obj, property)) {
|
255 | return true;
|
256 | }
|
257 |
|
258 | return hasProperty(getPrototype(obj), property);
|
259 | }
|
260 |
|
261 | const IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
|
262 | const IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';
|
263 | const IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
|
264 |
|
265 | function isImmutableUnorderedKeyed(maybeKeyed) {
|
266 | return !!(
|
267 | maybeKeyed &&
|
268 | maybeKeyed[IS_KEYED_SENTINEL] &&
|
269 | !maybeKeyed[IS_ORDERED_SENTINEL]
|
270 | );
|
271 | }
|
272 |
|
273 | function isImmutableUnorderedSet(maybeSet) {
|
274 | return !!(
|
275 | maybeSet &&
|
276 | maybeSet[IS_SET_SENTINEL] &&
|
277 | !maybeSet[IS_ORDERED_SENTINEL]
|
278 | );
|
279 | }
|