123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- 'use strict';
- var assign = require('object.assign');
- var callBound = require('call-bind/callBound');
- var flags = require('regexp.prototype.flags');
- var GetIntrinsic = require('get-intrinsic');
- var getIterator = require('es-get-iterator');
- var getSideChannel = require('side-channel');
- var is = require('object-is');
- var isArguments = require('is-arguments');
- var isArray = require('isarray');
- var isArrayBuffer = require('is-array-buffer');
- var isDate = require('is-date-object');
- var isRegex = require('is-regex');
- var isSharedArrayBuffer = require('is-shared-array-buffer');
- var objectKeys = require('object-keys');
- var whichBoxedPrimitive = require('which-boxed-primitive');
- var whichCollection = require('which-collection');
- var whichTypedArray = require('which-typed-array');
- var byteLength = require('array-buffer-byte-length');
- var sabByteLength = callBound('SharedArrayBuffer.prototype.byteLength', true);
- var $getTime = callBound('Date.prototype.getTime');
- var gPO = Object.getPrototypeOf;
- var $objToString = callBound('Object.prototype.toString');
- var $Set = GetIntrinsic('%Set%', true);
- var $mapHas = callBound('Map.prototype.has', true);
- var $mapGet = callBound('Map.prototype.get', true);
- var $mapSize = callBound('Map.prototype.size', true);
- var $setAdd = callBound('Set.prototype.add', true);
- var $setDelete = callBound('Set.prototype.delete', true);
- var $setHas = callBound('Set.prototype.has', true);
- var $setSize = callBound('Set.prototype.size', true);
- function setHasEqualElement(set, val1, opts, channel) {
- var i = getIterator(set);
- var result;
- while ((result = i.next()) && !result.done) {
- if (internalDeepEqual(val1, result.value, opts, channel)) {
-
- $setDelete(set, result.value);
- return true;
- }
- }
- return false;
- }
- function findLooseMatchingPrimitives(prim) {
- if (typeof prim === 'undefined') {
- return null;
- }
- if (typeof prim === 'object') {
- return void 0;
- }
- if (typeof prim === 'symbol') {
- return false;
- }
- if (typeof prim === 'string' || typeof prim === 'number') {
-
- return +prim === +prim;
- }
- return true;
- }
- function mapMightHaveLoosePrim(a, b, prim, item, opts, channel) {
- var altValue = findLooseMatchingPrimitives(prim);
- if (altValue != null) {
- return altValue;
- }
- var curB = $mapGet(b, altValue);
- var looseOpts = assign({}, opts, { strict: false });
- if (
- (typeof curB === 'undefined' && !$mapHas(b, altValue))
-
- || !internalDeepEqual(item, curB, looseOpts, channel)
- ) {
- return false;
- }
-
- return !$mapHas(a, altValue) && internalDeepEqual(item, curB, looseOpts, channel);
- }
- function setMightHaveLoosePrim(a, b, prim) {
- var altValue = findLooseMatchingPrimitives(prim);
- if (altValue != null) {
- return altValue;
- }
- return $setHas(b, altValue) && !$setHas(a, altValue);
- }
- function mapHasEqualEntry(set, map, key1, item1, opts, channel) {
- var i = getIterator(set);
- var result;
- var key2;
- while ((result = i.next()) && !result.done) {
- key2 = result.value;
- if (
-
- internalDeepEqual(key1, key2, opts, channel)
-
- && internalDeepEqual(item1, $mapGet(map, key2), opts, channel)
- ) {
- $setDelete(set, key2);
- return true;
- }
- }
- return false;
- }
- function internalDeepEqual(actual, expected, options, channel) {
- var opts = options || {};
-
- if (opts.strict ? is(actual, expected) : actual === expected) {
- return true;
- }
- var actualBoxed = whichBoxedPrimitive(actual);
- var expectedBoxed = whichBoxedPrimitive(expected);
- if (actualBoxed !== expectedBoxed) {
- return false;
- }
-
- if (!actual || !expected || (typeof actual !== 'object' && typeof expected !== 'object')) {
- return opts.strict ? is(actual, expected) : actual == expected;
- }
-
-
- var hasActual = channel.has(actual);
- var hasExpected = channel.has(expected);
- var sentinel;
- if (hasActual && hasExpected) {
- if (channel.get(actual) === channel.get(expected)) {
- return true;
- }
- } else {
- sentinel = {};
- }
- if (!hasActual) { channel.set(actual, sentinel); }
- if (!hasExpected) { channel.set(expected, sentinel); }
-
- return objEquiv(actual, expected, opts, channel);
- }
- function isBuffer(x) {
- if (!x || typeof x !== 'object' || typeof x.length !== 'number') {
- return false;
- }
- if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
- return false;
- }
- if (x.length > 0 && typeof x[0] !== 'number') {
- return false;
- }
- return !!(x.constructor && x.constructor.isBuffer && x.constructor.isBuffer(x));
- }
- function setEquiv(a, b, opts, channel) {
- if ($setSize(a) !== $setSize(b)) {
- return false;
- }
- var iA = getIterator(a);
- var iB = getIterator(b);
- var resultA;
- var resultB;
- var set;
- while ((resultA = iA.next()) && !resultA.done) {
- if (resultA.value && typeof resultA.value === 'object') {
- if (!set) { set = new $Set(); }
- $setAdd(set, resultA.value);
- } else if (!$setHas(b, resultA.value)) {
- if (opts.strict) { return false; }
- if (!setMightHaveLoosePrim(a, b, resultA.value)) {
- return false;
- }
- if (!set) { set = new $Set(); }
- $setAdd(set, resultA.value);
- }
- }
- if (set) {
- while ((resultB = iB.next()) && !resultB.done) {
-
- if (resultB.value && typeof resultB.value === 'object') {
- if (!setHasEqualElement(set, resultB.value, opts.strict, channel)) {
- return false;
- }
- } else if (
- !opts.strict
- && !$setHas(a, resultB.value)
- && !setHasEqualElement(set, resultB.value, opts.strict, channel)
- ) {
- return false;
- }
- }
- return $setSize(set) === 0;
- }
- return true;
- }
- function mapEquiv(a, b, opts, channel) {
- if ($mapSize(a) !== $mapSize(b)) {
- return false;
- }
- var iA = getIterator(a);
- var iB = getIterator(b);
- var resultA;
- var resultB;
- var set;
- var key;
- var item1;
- var item2;
- while ((resultA = iA.next()) && !resultA.done) {
- key = resultA.value[0];
- item1 = resultA.value[1];
- if (key && typeof key === 'object') {
- if (!set) { set = new $Set(); }
- $setAdd(set, key);
- } else {
- item2 = $mapGet(b, key);
- if ((typeof item2 === 'undefined' && !$mapHas(b, key)) || !internalDeepEqual(item1, item2, opts, channel)) {
- if (opts.strict) {
- return false;
- }
- if (!mapMightHaveLoosePrim(a, b, key, item1, opts, channel)) {
- return false;
- }
- if (!set) { set = new $Set(); }
- $setAdd(set, key);
- }
- }
- }
- if (set) {
- while ((resultB = iB.next()) && !resultB.done) {
- key = resultB.value[0];
- item2 = resultB.value[1];
- if (key && typeof key === 'object') {
- if (!mapHasEqualEntry(set, a, key, item2, opts, channel)) {
- return false;
- }
- } else if (
- !opts.strict
- && (!a.has(key) || !internalDeepEqual($mapGet(a, key), item2, opts, channel))
- && !mapHasEqualEntry(set, a, key, item2, assign({}, opts, { strict: false }), channel)
- ) {
- return false;
- }
- }
- return $setSize(set) === 0;
- }
- return true;
- }
- function objEquiv(a, b, opts, channel) {
-
- var i, key;
- if (typeof a !== typeof b) { return false; }
- if (a == null || b == null) { return false; }
- if ($objToString(a) !== $objToString(b)) { return false; }
- if (isArguments(a) !== isArguments(b)) { return false; }
- var aIsArray = isArray(a);
- var bIsArray = isArray(b);
- if (aIsArray !== bIsArray) { return false; }
-
- var aIsError = a instanceof Error;
- var bIsError = b instanceof Error;
- if (aIsError !== bIsError) { return false; }
- if (aIsError || bIsError) {
- if (a.name !== b.name || a.message !== b.message) { return false; }
- }
- var aIsRegex = isRegex(a);
- var bIsRegex = isRegex(b);
- if (aIsRegex !== bIsRegex) { return false; }
- if ((aIsRegex || bIsRegex) && (a.source !== b.source || flags(a) !== flags(b))) {
- return false;
- }
- var aIsDate = isDate(a);
- var bIsDate = isDate(b);
- if (aIsDate !== bIsDate) { return false; }
- if (aIsDate || bIsDate) {
- if ($getTime(a) !== $getTime(b)) { return false; }
- }
- if (opts.strict && gPO && gPO(a) !== gPO(b)) { return false; }
- var aWhich = whichTypedArray(a);
- var bWhich = whichTypedArray(b);
- if (aWhich !== bWhich) {
- return false;
- }
- if (aWhich || bWhich) {
- if (a.length !== b.length) { return false; }
- for (i = 0; i < a.length; i++) {
- if (a[i] !== b[i]) { return false; }
- }
- return true;
- }
- var aIsBuffer = isBuffer(a);
- var bIsBuffer = isBuffer(b);
- if (aIsBuffer !== bIsBuffer) { return false; }
- if (aIsBuffer || bIsBuffer) {
- if (a.length !== b.length) { return false; }
- for (i = 0; i < a.length; i++) {
- if (a[i] !== b[i]) { return false; }
- }
- return true;
- }
- var aIsArrayBuffer = isArrayBuffer(a);
- var bIsArrayBuffer = isArrayBuffer(b);
- if (aIsArrayBuffer !== bIsArrayBuffer) { return false; }
- if (aIsArrayBuffer || bIsArrayBuffer) {
- if (byteLength(a) !== byteLength(b)) { return false; }
- return typeof Uint8Array === 'function' && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel);
- }
- var aIsSAB = isSharedArrayBuffer(a);
- var bIsSAB = isSharedArrayBuffer(b);
- if (aIsSAB !== bIsSAB) { return false; }
- if (aIsSAB || bIsSAB) {
- if (sabByteLength(a) !== sabByteLength(b)) { return false; }
- return typeof Uint8Array === 'function' && internalDeepEqual(new Uint8Array(a), new Uint8Array(b), opts, channel);
- }
- if (typeof a !== typeof b) { return false; }
- var ka = objectKeys(a);
- var kb = objectKeys(b);
-
- if (ka.length !== kb.length) { return false; }
-
- ka.sort();
- kb.sort();
-
- for (i = ka.length - 1; i >= 0; i--) {
- if (ka[i] != kb[i]) { return false; }
- }
-
- for (i = ka.length - 1; i >= 0; i--) {
- key = ka[i];
- if (!internalDeepEqual(a[key], b[key], opts, channel)) { return false; }
- }
- var aCollection = whichCollection(a);
- var bCollection = whichCollection(b);
- if (aCollection !== bCollection) {
- return false;
- }
- if (aCollection === 'Set' || bCollection === 'Set') {
- return setEquiv(a, b, opts, channel);
- }
- if (aCollection === 'Map') {
- return mapEquiv(a, b, opts, channel);
- }
- return true;
- }
- module.exports = function deepEqual(a, b, opts) {
- return internalDeepEqual(a, b, opts, getSideChannel());
- };
|