@gjsify/assert 0.3.13 → 0.3.15
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/lib/esm/assertion-error.js +56 -66
- package/lib/esm/deep-equal.js +434 -450
- package/lib/esm/index.js +384 -417
- package/lib/esm/inspect-fallback.js +69 -67
- package/lib/esm/strict/index.js +4 -43
- package/package.json +3 -3
package/lib/esm/deep-equal.js
CHANGED
|
@@ -1,525 +1,509 @@
|
|
|
1
|
-
|
|
2
|
-
ValueType2[ValueType2["noIterator"] = 0] = "noIterator";
|
|
3
|
-
ValueType2[ValueType2["isArray"] = 1] = "isArray";
|
|
4
|
-
ValueType2[ValueType2["isSet"] = 2] = "isSet";
|
|
5
|
-
ValueType2[ValueType2["isMap"] = 3] = "isMap";
|
|
6
|
-
return ValueType2;
|
|
7
|
-
})(ValueType || {});
|
|
1
|
+
//#region src/deep-equal.ts
|
|
8
2
|
const kStrict = 1;
|
|
9
3
|
const kLoose = 0;
|
|
10
4
|
function isDate(v) {
|
|
11
|
-
|
|
5
|
+
return v instanceof Date;
|
|
12
6
|
}
|
|
13
7
|
function isRegExp(v) {
|
|
14
|
-
|
|
8
|
+
return v instanceof RegExp;
|
|
15
9
|
}
|
|
16
10
|
function isMap(v) {
|
|
17
|
-
|
|
11
|
+
return v instanceof Map;
|
|
18
12
|
}
|
|
19
13
|
function isSet(v) {
|
|
20
|
-
|
|
14
|
+
return v instanceof Set;
|
|
21
15
|
}
|
|
22
16
|
function isError(v) {
|
|
23
|
-
|
|
17
|
+
return v instanceof Error;
|
|
24
18
|
}
|
|
25
19
|
function isAnyArrayBuffer(v) {
|
|
26
|
-
|
|
20
|
+
return v instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && v instanceof SharedArrayBuffer;
|
|
27
21
|
}
|
|
28
22
|
function isArrayBufferView(v) {
|
|
29
|
-
|
|
23
|
+
return ArrayBuffer.isView(v);
|
|
30
24
|
}
|
|
31
25
|
function isBoxedPrimitive(v) {
|
|
32
|
-
|
|
26
|
+
return v instanceof Number || v instanceof String || v instanceof Boolean || v instanceof BigInt || v instanceof Symbol;
|
|
33
27
|
}
|
|
34
28
|
function isNumberObject(v) {
|
|
35
|
-
|
|
29
|
+
return v instanceof Number;
|
|
36
30
|
}
|
|
37
31
|
function isStringObject(v) {
|
|
38
|
-
|
|
32
|
+
return v instanceof String;
|
|
39
33
|
}
|
|
40
34
|
function isBooleanObject(v) {
|
|
41
|
-
|
|
35
|
+
return v instanceof Boolean;
|
|
42
36
|
}
|
|
43
37
|
function isBigIntObject(v) {
|
|
44
|
-
|
|
38
|
+
return typeof BigInt !== "undefined" && v instanceof Object && Object.prototype.toString.call(v) === "[object BigInt]";
|
|
45
39
|
}
|
|
46
40
|
function isSymbolObject(v) {
|
|
47
|
-
|
|
41
|
+
return v instanceof Object && Object.prototype.toString.call(v) === "[object Symbol]";
|
|
48
42
|
}
|
|
49
43
|
function isFloatTypedArray(v) {
|
|
50
|
-
|
|
44
|
+
return v instanceof Float32Array || v instanceof Float64Array;
|
|
51
45
|
}
|
|
52
46
|
const hasOwn = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
53
47
|
const hasEnumerable = (obj, prop) => Object.prototype.propertyIsEnumerable.call(obj, prop);
|
|
54
|
-
const wellKnownConstructors =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
48
|
+
const wellKnownConstructors = new Set([
|
|
49
|
+
Array,
|
|
50
|
+
ArrayBuffer,
|
|
51
|
+
Boolean,
|
|
52
|
+
DataView,
|
|
53
|
+
Date,
|
|
54
|
+
Error,
|
|
55
|
+
Float32Array,
|
|
56
|
+
Float64Array,
|
|
57
|
+
Function,
|
|
58
|
+
Int8Array,
|
|
59
|
+
Int16Array,
|
|
60
|
+
Int32Array,
|
|
61
|
+
Map,
|
|
62
|
+
Number,
|
|
63
|
+
Object,
|
|
64
|
+
Promise,
|
|
65
|
+
RegExp,
|
|
66
|
+
Set,
|
|
67
|
+
String,
|
|
68
|
+
Symbol,
|
|
69
|
+
Uint8Array,
|
|
70
|
+
Uint16Array,
|
|
71
|
+
Uint32Array,
|
|
72
|
+
Uint8ClampedArray,
|
|
73
|
+
BigInt64Array,
|
|
74
|
+
BigUint64Array,
|
|
75
|
+
WeakMap,
|
|
76
|
+
WeakSet
|
|
83
77
|
]);
|
|
78
|
+
/**
|
|
79
|
+
* Get own non-index properties of an object.
|
|
80
|
+
* JS approximation of the C++ binding used in Node/Deno.
|
|
81
|
+
*/
|
|
84
82
|
function getOwnNonIndexProperties(obj, skipSymbols) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
83
|
+
const keys = Object.getOwnPropertyNames(obj);
|
|
84
|
+
const result = [];
|
|
85
|
+
for (const key of keys) {
|
|
86
|
+
const num = Number(key);
|
|
87
|
+
if (Number.isInteger(num) && num >= 0 && num < 2 ** 32 - 1 && String(num) === key) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!hasEnumerable(obj, key)) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
result.push(key);
|
|
94
|
+
}
|
|
95
|
+
if (!skipSymbols) {
|
|
96
|
+
const symbols = Object.getOwnPropertySymbols(obj);
|
|
97
|
+
for (const sym of symbols) {
|
|
98
|
+
if (hasEnumerable(obj, sym)) {
|
|
99
|
+
result.push(sym);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
106
104
|
}
|
|
107
105
|
function areSimilarRegExps(a, b) {
|
|
108
|
-
|
|
106
|
+
return a.source === b.source && a.flags === b.flags && a.lastIndex === b.lastIndex;
|
|
109
107
|
}
|
|
110
108
|
function areSimilarFloatArrays(a, b) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
110
|
+
const viewA = a;
|
|
111
|
+
const viewB = b;
|
|
112
|
+
for (let i = 0; i < viewA.length; i++) {
|
|
113
|
+
if (viewA[i] !== viewB[i]) return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
118
116
|
}
|
|
119
117
|
function areSimilarTypedArrays(a, b) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
119
|
+
const viewA = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
|
|
120
|
+
const viewB = new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
|
|
121
|
+
for (let i = 0; i < viewA.length; i++) {
|
|
122
|
+
if (viewA[i] !== viewB[i]) return false;
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
127
125
|
}
|
|
128
126
|
function areEqualArrayBuffers(buf1, buf2) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
if (buf1.byteLength !== buf2.byteLength) return false;
|
|
128
|
+
const a = new Uint8Array(buf1);
|
|
129
|
+
const b = new Uint8Array(buf2);
|
|
130
|
+
for (let i = 0; i < a.length; i++) {
|
|
131
|
+
if (a[i] !== b[i]) return false;
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
136
134
|
}
|
|
137
135
|
function isEqualBoxedPrimitive(val1, val2) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
136
|
+
if (isNumberObject(val1)) {
|
|
137
|
+
return isNumberObject(val2) && Object.is(val1.valueOf(), val2.valueOf());
|
|
138
|
+
}
|
|
139
|
+
if (isStringObject(val1)) {
|
|
140
|
+
return isStringObject(val2) && val1.valueOf() === val2.valueOf();
|
|
141
|
+
}
|
|
142
|
+
if (isBooleanObject(val1)) {
|
|
143
|
+
return isBooleanObject(val2) && val1.valueOf() === val2.valueOf();
|
|
144
|
+
}
|
|
145
|
+
if (isBigIntObject(val1)) {
|
|
146
|
+
return isBigIntObject(val2) && val1[Symbol.toPrimitive]("number") === val2[Symbol.toPrimitive]("number");
|
|
147
|
+
}
|
|
148
|
+
if (isSymbolObject(val1)) {
|
|
149
|
+
return isSymbolObject(val2) && Symbol.prototype.valueOf.call(val1) === Symbol.prototype.valueOf.call(val2);
|
|
150
|
+
}
|
|
151
|
+
return false;
|
|
154
152
|
}
|
|
155
153
|
function getTypedArrayTag(val) {
|
|
156
|
-
|
|
154
|
+
return Object.prototype.toString.call(val).slice(8, -1);
|
|
157
155
|
}
|
|
158
156
|
function innerDeepEqual(val1, val2, mode, memos) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return objectComparisonStart(val1, val2, mode, memos);
|
|
157
|
+
if (val1 === val2) {
|
|
158
|
+
return val1 !== 0 || Object.is(val1, val2) || mode === kLoose;
|
|
159
|
+
}
|
|
160
|
+
if (mode !== kLoose) {
|
|
161
|
+
if (typeof val1 === "number") {
|
|
162
|
+
return val1 !== val1 && val2 !== val2;
|
|
163
|
+
}
|
|
164
|
+
if (typeof val2 !== "object" || typeof val1 !== "object" || val1 === null || val2 === null) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
} else {
|
|
168
|
+
if (val1 === null || typeof val1 !== "object") {
|
|
169
|
+
return (val2 === null || typeof val2 !== "object") && (val1 == val2 || val1 !== val1 && val2 !== val2);
|
|
170
|
+
}
|
|
171
|
+
if (val2 === null || typeof val2 !== "object") {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return objectComparisonStart(val1, val2, mode, memos);
|
|
179
176
|
}
|
|
180
177
|
function objectComparisonStart(val1, val2, mode, memos) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
178
|
+
if (mode === kStrict) {
|
|
179
|
+
if (wellKnownConstructors.has(val1.constructor) || val1.constructor !== undefined && !hasOwn(val1, "constructor")) {
|
|
180
|
+
if (val1.constructor !== val2.constructor) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
} else if (Object.getPrototypeOf(val1) !== Object.getPrototypeOf(val2)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const val1Tag = Object.prototype.toString.call(val1);
|
|
188
|
+
const val2Tag = Object.prototype.toString.call(val2);
|
|
189
|
+
if (val1Tag !== val2Tag) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (Array.isArray(val1)) {
|
|
193
|
+
if (!Array.isArray(val2) || val1.length !== val2.length) {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const keys2 = getOwnNonIndexProperties(val2, mode === kLoose);
|
|
197
|
+
if (keys2.length !== getOwnNonIndexProperties(val1, mode === kLoose).length) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
return keyCheck(val1, val2, mode, memos, 1, keys2);
|
|
201
|
+
} else if (val1Tag === "[object Object]") {
|
|
202
|
+
return keyCheck(val1, val2, mode, memos, 0);
|
|
203
|
+
} else if (isDate(val1)) {
|
|
204
|
+
if (!isDate(val2)) return false;
|
|
205
|
+
const time1 = val1.getTime();
|
|
206
|
+
const time2 = val2.getTime();
|
|
207
|
+
if (time1 !== time2 && !(Number.isNaN(time1) && Number.isNaN(time2))) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
} else if (isRegExp(val1)) {
|
|
211
|
+
if (!isRegExp(val2) || !areSimilarRegExps(val1, val2)) {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
} else if (isArrayBufferView(val1)) {
|
|
215
|
+
if (getTypedArrayTag(val1) !== getTypedArrayTag(val2)) {
|
|
216
|
+
return false;
|
|
217
|
+
}
|
|
218
|
+
if (mode === kLoose && isFloatTypedArray(val1)) {
|
|
219
|
+
if (!areSimilarFloatArrays(val1, val2)) {
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
} else if (!areSimilarTypedArrays(val1, val2)) {
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
const keys2 = getOwnNonIndexProperties(val2, mode === kLoose);
|
|
226
|
+
if (keys2.length !== getOwnNonIndexProperties(val1, mode === kLoose).length) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
return keyCheck(val1, val2, mode, memos, 0, keys2);
|
|
230
|
+
} else if (isSet(val1)) {
|
|
231
|
+
if (!isSet(val2) || val1.size !== val2.size) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
return keyCheck(val1, val2, mode, memos, 2);
|
|
235
|
+
} else if (isMap(val1)) {
|
|
236
|
+
if (!isMap(val2) || val1.size !== val2.size) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
return keyCheck(val1, val2, mode, memos, 3);
|
|
240
|
+
} else if (isAnyArrayBuffer(val1)) {
|
|
241
|
+
if (!isAnyArrayBuffer(val2) || !areEqualArrayBuffers(val1, val2)) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
} else if (isError(val1)) {
|
|
245
|
+
if (!isError(val2) || val1.message !== val2.message || val1.name !== val2.name) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
if (hasOwn(val1, "cause") !== hasOwn(val2, "cause")) {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
if (hasOwn(val1, "cause") && !innerDeepEqual(val1.cause, val2.cause, mode, memos)) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
} else if (isBoxedPrimitive(val1)) {
|
|
255
|
+
if (!isEqualBoxedPrimitive(val1, val2)) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
} else if (Array.isArray(val2) || isArrayBufferView(val2) || isSet(val2) || isMap(val2) || isDate(val2) || isRegExp(val2) || isAnyArrayBuffer(val2) || isBoxedPrimitive(val2) || isError(val2)) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
return keyCheck(val1, val2, mode, memos, 0);
|
|
265
262
|
}
|
|
266
263
|
function getEnumerables(val, keys) {
|
|
267
|
-
|
|
264
|
+
return keys.filter((key) => hasEnumerable(val, key));
|
|
268
265
|
}
|
|
269
266
|
function keyCheck(val1, val2, mode, memos, iterationType, keys2) {
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
267
|
+
const isArrayLikeObject = keys2 !== undefined;
|
|
268
|
+
if (keys2 === undefined) {
|
|
269
|
+
keys2 = Object.keys(val2);
|
|
270
|
+
}
|
|
271
|
+
let keys1;
|
|
272
|
+
if (!isArrayLikeObject) {
|
|
273
|
+
if (keys2.length !== (keys1 = Object.keys(val1)).length) {
|
|
274
|
+
return false;
|
|
275
|
+
} else if (mode === kStrict) {
|
|
276
|
+
const symbolKeysA = Object.getOwnPropertySymbols(val1);
|
|
277
|
+
if (symbolKeysA.length !== 0) {
|
|
278
|
+
let count = 0;
|
|
279
|
+
for (const key of symbolKeysA) {
|
|
280
|
+
if (hasEnumerable(val1, key)) {
|
|
281
|
+
if (!hasEnumerable(val2, key)) return false;
|
|
282
|
+
keys2.push(key);
|
|
283
|
+
count++;
|
|
284
|
+
} else if (hasEnumerable(val2, key)) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const symbolKeysB = Object.getOwnPropertySymbols(val2);
|
|
289
|
+
if (symbolKeysA.length !== symbolKeysB.length && getEnumerables(val2, symbolKeysB).length !== count) {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
} else {
|
|
293
|
+
const symbolKeysB = Object.getOwnPropertySymbols(val2);
|
|
294
|
+
if (symbolKeysB.length !== 0 && getEnumerables(val2, symbolKeysB).length !== 0) {
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
if (keys2.length === 0 && (iterationType === 0 || iterationType === 1 && val2.length === 0 || val2.size === 0)) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
if (memos === null) {
|
|
304
|
+
return objEquiv(val1, val2, mode, keys1, keys2, memos, iterationType);
|
|
305
|
+
}
|
|
306
|
+
return handleCycles(val1, val2, mode, keys1, keys2, memos, iterationType);
|
|
310
307
|
}
|
|
311
308
|
function handleCycles(val1, val2, mode, keys1, keys2, memos, iterationType) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
309
|
+
if (memos === undefined) {
|
|
310
|
+
memos = {
|
|
311
|
+
set: undefined,
|
|
312
|
+
a: val1,
|
|
313
|
+
b: val2,
|
|
314
|
+
c: undefined,
|
|
315
|
+
d: undefined,
|
|
316
|
+
deep: false
|
|
317
|
+
};
|
|
318
|
+
return objEquiv(val1, val2, mode, keys1, keys2, memos, iterationType);
|
|
319
|
+
}
|
|
320
|
+
if (memos.set === undefined) {
|
|
321
|
+
if (memos.deep === false) {
|
|
322
|
+
if (memos.a === val1) return memos.b === val2;
|
|
323
|
+
if (memos.b === val2) return false;
|
|
324
|
+
memos.c = val1;
|
|
325
|
+
memos.d = val2;
|
|
326
|
+
memos.deep = true;
|
|
327
|
+
const result = objEquiv(val1, val2, mode, keys1, keys2, memos, iterationType);
|
|
328
|
+
memos.deep = false;
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
memos.set = new Set();
|
|
332
|
+
memos.set.add(memos.a);
|
|
333
|
+
memos.set.add(memos.b);
|
|
334
|
+
memos.set.add(memos.c);
|
|
335
|
+
memos.set.add(memos.d);
|
|
336
|
+
}
|
|
337
|
+
const { set } = memos;
|
|
338
|
+
const originalSize = set.size;
|
|
339
|
+
set.add(val1);
|
|
340
|
+
set.add(val2);
|
|
341
|
+
if (originalSize !== set.size - 2) {
|
|
342
|
+
return originalSize === set.size;
|
|
343
|
+
}
|
|
344
|
+
const areEq = objEquiv(val1, val2, mode, keys1, keys2, memos, iterationType);
|
|
345
|
+
set.delete(val1);
|
|
346
|
+
set.delete(val2);
|
|
347
|
+
return areEq;
|
|
351
348
|
}
|
|
352
349
|
function findLooseMatchingPrimitives(prim) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
prim = +prim;
|
|
362
|
-
// falls through
|
|
363
|
-
case "number":
|
|
364
|
-
if (prim !== prim) return false;
|
|
365
|
-
}
|
|
366
|
-
return true;
|
|
350
|
+
switch (typeof prim) {
|
|
351
|
+
case "undefined": return null;
|
|
352
|
+
case "object": return undefined;
|
|
353
|
+
case "symbol": return false;
|
|
354
|
+
case "string": prim = +prim;
|
|
355
|
+
case "number": if (prim !== prim) return false;
|
|
356
|
+
}
|
|
357
|
+
return true;
|
|
367
358
|
}
|
|
368
359
|
function setMightHaveLoosePrim(a, b, prim) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
360
|
+
const altValue = findLooseMatchingPrimitives(prim);
|
|
361
|
+
if (altValue != null) return altValue;
|
|
362
|
+
return !b.has(altValue) && a.has(altValue);
|
|
372
363
|
}
|
|
373
364
|
function mapMightHaveLoosePrim(a, b, prim, item2, memo) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
365
|
+
const altValue = findLooseMatchingPrimitives(prim);
|
|
366
|
+
if (altValue != null) return altValue;
|
|
367
|
+
const item1 = a.get(altValue);
|
|
368
|
+
if (item1 === undefined && !a.has(altValue) || !innerDeepEqual(item1, item2, kLoose, memo)) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return !b.has(altValue) && innerDeepEqual(item1, item2, kLoose, memo);
|
|
381
372
|
}
|
|
382
373
|
function setEquiv(a, b, mode, memo) {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
374
|
+
let array;
|
|
375
|
+
for (const val of b) {
|
|
376
|
+
if (!a.has(val)) {
|
|
377
|
+
if ((typeof val !== "object" || val === null) && (mode !== kLoose || !setMightHaveLoosePrim(a, b, val))) {
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
if (array === undefined) array = [];
|
|
381
|
+
array.push(val);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (array === undefined) return true;
|
|
385
|
+
for (const val1 of a) {
|
|
386
|
+
if (typeof val1 === "object" && val1 !== null) {
|
|
387
|
+
if (!b.has(val1)) {
|
|
388
|
+
let found = false;
|
|
389
|
+
for (let i = 0; i < array.length; i++) {
|
|
390
|
+
if (innerDeepEqual(val1, array[i], mode, memo)) {
|
|
391
|
+
array.splice(i, 1);
|
|
392
|
+
found = true;
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
if (!found) return false;
|
|
397
|
+
}
|
|
398
|
+
} else if (!b.has(val1) && (mode !== kLoose || !setMightHaveLoosePrim(b, a, val1))) {
|
|
399
|
+
let found = false;
|
|
400
|
+
for (let i = 0; i < array.length; i++) {
|
|
401
|
+
if (innerDeepEqual(val1, array[i], mode, memo)) {
|
|
402
|
+
array.splice(i, 1);
|
|
403
|
+
found = true;
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (!found) return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return array.length === 0;
|
|
420
411
|
}
|
|
421
412
|
function mapEquiv(a, b, mode, memo) {
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
return array.length === 0;
|
|
413
|
+
let array;
|
|
414
|
+
for (const [key2, item2] of b) {
|
|
415
|
+
if (typeof key2 === "object" && key2 !== null) {
|
|
416
|
+
if (array === undefined) {
|
|
417
|
+
if (a.size === 1) {
|
|
418
|
+
const [key1, item1] = a.entries().next().value;
|
|
419
|
+
return innerDeepEqual(key1, key2, mode, memo) && innerDeepEqual(item1, item2, mode, memo);
|
|
420
|
+
}
|
|
421
|
+
array = [];
|
|
422
|
+
}
|
|
423
|
+
array.push(key2);
|
|
424
|
+
} else {
|
|
425
|
+
const item1 = a.get(key2);
|
|
426
|
+
if (item1 === undefined && !a.has(key2) || !innerDeepEqual(item1, item2, mode, memo)) {
|
|
427
|
+
if (mode !== kLoose) return false;
|
|
428
|
+
if (!mapMightHaveLoosePrim(a, b, key2, item2, memo)) return false;
|
|
429
|
+
if (array === undefined) array = [];
|
|
430
|
+
array.push(key2);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (array === undefined) return true;
|
|
435
|
+
for (const [key1, item1] of a) {
|
|
436
|
+
if (typeof key1 === "object" && key1 !== null) {
|
|
437
|
+
if (!b.has(key1)) {
|
|
438
|
+
let found = false;
|
|
439
|
+
for (let i = 0; i < array.length; i++) {
|
|
440
|
+
const key2 = array[i];
|
|
441
|
+
if (innerDeepEqual(key1, key2, mode, memo) && innerDeepEqual(item1, b.get(key2), mode, memo)) {
|
|
442
|
+
array.splice(i, 1);
|
|
443
|
+
found = true;
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (!found) return false;
|
|
448
|
+
}
|
|
449
|
+
} else if (mode === kLoose && typeof key1 !== "object" && (!a.has(key1) || !innerDeepEqual(item1, a.get(key1), mode, memo))) {}
|
|
450
|
+
}
|
|
451
|
+
return array.length === 0;
|
|
462
452
|
}
|
|
463
453
|
function objEquiv(a, b, mode, keys1, keys2, memos, iterationType) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (!setEquiv(a, b, mode, memos)) return false;
|
|
503
|
-
} else if (iterationType === 3 /* isMap */) {
|
|
504
|
-
if (!mapEquiv(a, b, mode, memos)) return false;
|
|
505
|
-
}
|
|
506
|
-
return true;
|
|
454
|
+
if (keys2.length > 0) {
|
|
455
|
+
const aRec = a;
|
|
456
|
+
const bRec = b;
|
|
457
|
+
let i = 0;
|
|
458
|
+
if (keys1 !== undefined) {
|
|
459
|
+
for (; i < keys2.length; i++) {
|
|
460
|
+
const key = keys2[i];
|
|
461
|
+
if (keys1[i] !== key) break;
|
|
462
|
+
if (!innerDeepEqual(aRec[key], bRec[key], mode, memos)) return false;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
for (; i < keys2.length; i++) {
|
|
466
|
+
const key = keys2[i];
|
|
467
|
+
const descriptor = Object.getOwnPropertyDescriptor(a, key);
|
|
468
|
+
if (!descriptor?.enumerable || !innerDeepEqual(descriptor.value !== undefined ? descriptor.value : aRec[key], bRec[key], mode, memos)) {
|
|
469
|
+
return false;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (iterationType === 1) {
|
|
474
|
+
const aArr = a;
|
|
475
|
+
const bArr = b;
|
|
476
|
+
for (let i = 0; i < aArr.length; i++) {
|
|
477
|
+
if (bArr[i] === undefined && !hasOwn(b, i)) {
|
|
478
|
+
if (aArr[i] !== undefined || hasOwn(a, i)) return false;
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
if (mode !== kLoose && aArr[i] === undefined && !hasOwn(a, i)) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
if (!innerDeepEqual(aArr[i], bArr[i], mode, memos)) return false;
|
|
485
|
+
}
|
|
486
|
+
} else if (iterationType === 2) {
|
|
487
|
+
if (!setEquiv(a, b, mode, memos)) return false;
|
|
488
|
+
} else if (iterationType === 3) {
|
|
489
|
+
if (!mapEquiv(a, b, mode, memos)) return false;
|
|
490
|
+
}
|
|
491
|
+
return true;
|
|
507
492
|
}
|
|
508
493
|
let detectCycles = function(val1, val2, mode) {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
494
|
+
try {
|
|
495
|
+
return innerDeepEqual(val1, val2, mode, null);
|
|
496
|
+
} catch {
|
|
497
|
+
detectCycles = (v1, v2, m) => innerDeepEqual(v1, v2, m, undefined);
|
|
498
|
+
return innerDeepEqual(val1, val2, mode, undefined);
|
|
499
|
+
}
|
|
515
500
|
};
|
|
516
501
|
function isDeepEqual(val1, val2) {
|
|
517
|
-
|
|
502
|
+
return detectCycles(val1, val2, kLoose);
|
|
518
503
|
}
|
|
519
504
|
function isDeepStrictEqual(val1, val2) {
|
|
520
|
-
|
|
505
|
+
return detectCycles(val1, val2, kStrict);
|
|
521
506
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
};
|
|
507
|
+
|
|
508
|
+
//#endregion
|
|
509
|
+
export { isDeepEqual, isDeepStrictEqual };
|