Comparing version 3.1.2 to 4.0.0
@@ -14,3 +14,3 @@ /** | ||
const hashObject = require('hash-object'); | ||
const hashIt = require('../lib').default; | ||
const hash = require('../lib').default; | ||
@@ -90,4 +90,4 @@ let dataStairs = {end: 'is near'}; | ||
.add('hash-it', () => { | ||
hashIt(dataStairs); | ||
hashIt(dataArray); | ||
hash(dataStairs); | ||
hash(dataArray); | ||
}) | ||
@@ -94,0 +94,0 @@ .add('node-object-hash', () => { |
'use strict'; | ||
const hashIt = require('../lib').default; | ||
const hash = require('../lib').default; | ||
const {boolean, infinite, notANumber, nul, number, string, undef} = require('./primitive'); | ||
@@ -21,4 +21,9 @@ | ||
const recursiveObject = (() => { | ||
function Circular() { | ||
this.circular = this; | ||
function Circular(value) { | ||
this.deeply = { | ||
nested: { | ||
reference: this, | ||
value | ||
} | ||
}; | ||
} | ||
@@ -34,3 +39,3 @@ | ||
while (++index < cycles) { | ||
val = hashIt(array); | ||
val = hash(array, true); | ||
} | ||
@@ -44,3 +49,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(func); | ||
val = hash(func, true); | ||
} | ||
@@ -54,3 +59,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(map); | ||
val = hash(map, true); | ||
} | ||
@@ -64,3 +69,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(object); | ||
val = hash(object, true); | ||
} | ||
@@ -74,3 +79,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(recursiveObject, true); | ||
val = hash(recursiveObject, true); | ||
} | ||
@@ -84,3 +89,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(regex); | ||
val = hash(regex); | ||
} | ||
@@ -94,4 +99,4 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(set); | ||
val = hash(set, true); | ||
} | ||
}; |
@@ -10,9 +10,3 @@ 'use strict'; | ||
const header = () => { | ||
return `Benchmark cycles: ${repeats | ||
.map((cycles) => { | ||
return cycles.toLocaleString(); | ||
}) | ||
.join(' ')}`; | ||
}; | ||
const header = () => `Benchmark cycles: ${repeats.map((cycles) => cycles.toLocaleString()).join(' ')}`; | ||
@@ -19,0 +13,0 @@ let results = []; |
'use strict'; | ||
const hashIt = require('../lib').default; | ||
const hash = require('../lib').default; | ||
@@ -18,3 +18,3 @@ const boolean = (exports.boolean = true); | ||
while (++index < cycles) { | ||
val = hashIt(boolean); | ||
val = hash(boolean); | ||
} | ||
@@ -28,3 +28,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(infinite); | ||
val = hash(infinite); | ||
} | ||
@@ -38,3 +38,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(notANumber); | ||
val = hash(notANumber); | ||
} | ||
@@ -48,3 +48,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(nul); | ||
val = hash(nul); | ||
} | ||
@@ -58,3 +58,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(number); | ||
val = hash(number); | ||
} | ||
@@ -68,3 +68,3 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(string); | ||
val = hash(string); | ||
} | ||
@@ -78,4 +78,4 @@ }; | ||
while (++index < cycles) { | ||
val = hashIt(undef); | ||
val = hash(undef); | ||
} | ||
}; |
'use strict'; | ||
const REPEATS = [1000, 5000, 10000, 50000, 100000, 500000, 1000000, 5000000]; | ||
const TOTAL = REPEATS.reduce((sum, cycles) => { | ||
return sum + cycles; | ||
}, 0); | ||
const TOTAL = REPEATS.reduce((sum, cycles) => sum + cycles, 0); | ||
exports.test = (name, benchmark) => { | ||
let totalTime = 0, | ||
startTime, testTime; | ||
startTime, | ||
testTime; | ||
let displayText = `\n${name}:\n${REPEATS.map(cycles => { | ||
let displayText = `\n${name}:\n${REPEATS.map((cycles) => { | ||
startTime = Date.now(); | ||
@@ -14,0 +13,0 @@ |
# hashIt CHANGELOG | ||
## 4.0.0 | ||
Rewrite! Lots of changes under-the-hood for a much more consistent hash, and circular object handling out of the box. | ||
#### BREAKING CHANGES | ||
- `isEmpty`, `isEqual`,`isNull`, and `isUndefined` have been removed (all can be reproduced with new `is` and `is.all` functions) | ||
- `hash.isNull` => `hash.is(null)` | ||
- `hash.isUndefined` => `hash.is(undefined)` | ||
- `hash.isEqual` => `hash.is.all` | ||
- `hash.isEmpty` => `(object) => hash.is.any(object, undefined, null, '', 0, [], {}, new Map(), new Set())` | ||
- `Error` hashes now based on `error.stack` instead of `error.message` | ||
#### ENHANCEMENTS | ||
- Circular objects are now handled out of the box, thanks to [`fast-stringify`](https://github.com/planttheidea/fast-stringify) | ||
- Collision rates are near-zero (previously used traditional DJB2, which has small collision rates) | ||
- Better `ArrayBuffer` support with the use of `Buffer.from` when supported | ||
- SVG elements, DocumentFragments, and Events are now supported | ||
- `is` partial-application function allows for easy creation of any type of `isEqual` comparison method | ||
- `is.any` performs the same multiple-object check that `is.all` does, but only checks if one of the other objects is equal | ||
- `is.not` performs the same comparison that `is` does, but checks for non-equality | ||
#### FIXES | ||
- `Object` / `Map` / `Set` no longer returns different hashes based on order of key addition | ||
- `hash.isEqual` will no longer fail if nothing is passed | ||
## 3.1.2 | ||
* Remove extraneous `toString` call (performance) | ||
- Remove extraneous `toString` call (performance) | ||
## 3.1.1 | ||
* Improve hash uniqueness for HTML elements | ||
- Improve hash uniqueness for HTML elements | ||
## 3.1.0 | ||
* Add support for `Generator` (not just `GeneratorFunction`) | ||
* Streamline `typeof`- vs `toString`-driven handling for improved speed for most types | ||
- Add support for `Generator` (not just `GeneratorFunction`) | ||
- Streamline `typeof`- vs `toString`-driven handling for improved speed for most types | ||
## 3.0.0 | ||
* Improve speed (2-4x faster depending on type) | ||
* Smaller footprint (~25% reduction) | ||
* Improve hash accuracy for functions (hash now includes function body) | ||
* Fix issue where stack remained in memory after hash was built | ||
* Add ES transpilation for module-ready build tools | ||
- Improve speed (2-4x faster depending on type) | ||
- Smaller footprint (~25% reduction) | ||
- Improve hash accuracy for functions (hash now includes function body) | ||
- Fix issue where stack remained in memory after hash was built | ||
- Add ES transpilation for module-ready build tools | ||
#### BREAKING CHANGES | ||
* If using CommonJS, you need to specify `require('hash-it').default` instead of just `require('hash-it')` | ||
* Hashes themselves may have changed (especially for circular objects) | ||
* Removed `isRecursive` method on `hashIt` object (which was wrongly named to begin with) | ||
* To specifically handle _circular_ objects (which is what it really did), pass `true` as the second parameter to `hashIt` | ||
- If using CommonJS, you need to specify `require('hash-it').default` instead of just `require('hash-it')` | ||
- Hashes themselves may have changed (especially for circular objects) | ||
- Removed `isRecursive` method on `hashIt` object (which was wrongly named to begin with) | ||
- To specifically handle _circular_ objects (which is what it really did), pass `true` as the second parameter to `hashIt` | ||
## 2.1.2 | ||
* Move up isNull check in replacer (improve performance of more likely use-case) | ||
- Move up isNull check in replacer (improve performance of more likely use-case) | ||
## 2.1.1 | ||
* Create isNull utility instead of checking strict equality in multiple places | ||
- Create isNull utility instead of checking strict equality in multiple places | ||
## 2.1.0 | ||
* Overall speed improvement by an average of 18.74% (35.27% improvement on complex objects) | ||
- Overall speed improvement by an average of 18.74% (35.27% improvement on complex objects) | ||
## 2.0.1 | ||
* More speed improvements | ||
- More speed improvements | ||
## 2.0.0 | ||
* Use JSON.stringify with replacer as default, without try/catch | ||
* Move use of try/catch with fallback to prune to new `hashIt.withRecursion` method (only necessary for deeply-recursive objects like `window`) | ||
* Reorder switch statement for commonality of use cases | ||
* Leverage typeof in switch statements when possible for performance | ||
- Use JSON.stringify with replacer as default, without try/catch | ||
- Move use of try/catch with fallback to prune to new `hashIt.withRecursion` method (only necessary for deeply-recursive objects like `window`) | ||
- Reorder switch statement for commonality of use cases | ||
- Leverage typeof in switch statements when possible for performance | ||
## 1.3.1 | ||
* Add optimize-js plugin for performance in script version | ||
- Add optimize-js plugin for performance in script version | ||
## 1.3.0 | ||
* Add hashIt.isUndefined, hashIt.isNull, and hashIt.isEmpty methods | ||
* Reorder switch statements in replacer and getValueForStringification to reflect most likely to least likely (improves performance a touch) | ||
* Remove "Number" from number stringification | ||
* Leverage prependTypeToString whereever possible | ||
* Include Arguments object class | ||
- Add hashIt.isUndefined, hashIt.isNull, and hashIt.isEmpty methods | ||
- Reorder switch statements in replacer and getValueForStringification to reflect most likely to least likely (improves performance a touch) | ||
- Remove "Number" from number stringification | ||
- Leverage prependTypeToString whereever possible | ||
- Include Arguments object class | ||
## 1.2.1 | ||
* Calculation of Math hashCode now uses properties | ||
* Fix README | ||
- Calculation of Math hashCode now uses properties | ||
- Fix README | ||
## 1.2.0 | ||
* Add hashIt.isEqual method to test for equality | ||
* Prepend all values not string or number with object class name to help avoid collision with equivalent string values | ||
- Add hashIt.isEqual method to test for equality | ||
- Prepend all values not string or number with object class name to help avoid collision with equivalent string values | ||
## 1.1.0 | ||
* Add support for a variety of more object types | ||
* Fix replacer not using same stringifier for int arrays | ||
- Add support for a variety of more object types | ||
- Fix replacer not using same stringifier for int arrays | ||
## 1.0.0 | ||
* Initial release | ||
- Initial release |
1397
dist/hash-it.js
@@ -1,794 +0,833 @@ | ||
(function webpackUniversalModuleDefinition(root, factory) { | ||
if(typeof exports === 'object' && typeof module === 'object') | ||
module.exports = factory(); | ||
else if(typeof define === 'function' && define.amd) | ||
define("hashIt", [], factory); | ||
else if(typeof exports === 'object') | ||
exports["hashIt"] = factory(); | ||
else | ||
root["hashIt"] = factory(); | ||
})(typeof self !== 'undefined' ? self : this, function() { | ||
return /******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) { | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ } | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ i: moduleId, | ||
/******/ l: false, | ||
/******/ exports: {} | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.l = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // define getter function for harmony exports | ||
/******/ __webpack_require__.d = function(exports, name, getter) { | ||
/******/ if(!__webpack_require__.o(exports, name)) { | ||
/******/ Object.defineProperty(exports, name, { | ||
/******/ configurable: false, | ||
/******/ enumerable: true, | ||
/******/ get: getter | ||
/******/ }); | ||
/******/ } | ||
/******/ }; | ||
/******/ | ||
/******/ // getDefaultExport function for compatibility with non-harmony modules | ||
/******/ __webpack_require__.n = function(module) { | ||
/******/ var getter = module && module.__esModule ? | ||
/******/ function getDefault() { return module['default']; } : | ||
/******/ function getModuleExports() { return module; }; | ||
/******/ __webpack_require__.d(getter, 'a', getter); | ||
/******/ return getter; | ||
/******/ }; | ||
/******/ | ||
/******/ // Object.prototype.hasOwnProperty.call | ||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = 0); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ([ | ||
/* 0 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(factory((global.hashIt = {}))); | ||
}(this, (function (exports) { 'use strict'; | ||
module.exports = __webpack_require__(1); | ||
/** | ||
* @constant {Symbol} __ the value to be used as a placeholder | ||
*/ | ||
var __ = typeof Symbol === 'function' ? Symbol('curriable placeholder') : 0xedd1; | ||
/** | ||
* @function getArgs | ||
* | ||
* @description | ||
* get the complete args with previous placeholders being filled in | ||
* | ||
* @param {Arguments} originalArgs the arguments from the previous run | ||
* @param {Arguments} nextArgs the arguments from the next run | ||
* @returns {Array<*>} the complete list of args | ||
*/ | ||
var getArgs = function getArgs(originalArgs, nextArgs) { | ||
var args = new Array(originalArgs.length); | ||
/***/ }), | ||
/* 1 */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
var nextArgsIndex = 0; | ||
"use strict"; | ||
Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); | ||
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils__ = __webpack_require__(2); | ||
var _EMPTY_HASHES; | ||
for (var index = 0; index < originalArgs.length; index++) { | ||
args[index] = originalArgs[index] === __ && nextArgsIndex < nextArgs.length ? nextArgs[nextArgsIndex++] : originalArgs[index]; | ||
} | ||
if (nextArgsIndex < nextArgs.length) { | ||
for (; nextArgsIndex < nextArgs.length; nextArgsIndex++) { | ||
args.push(nextArgs[nextArgsIndex]); | ||
} | ||
} | ||
return args; | ||
}; | ||
/** | ||
* @function hashIt | ||
* | ||
* @description | ||
* return the unique integer hash value for the object | ||
* | ||
* @param {*} object the object to hash | ||
* @param {boolean} [isCircular] is the object a circular object | ||
* @returns {number} | ||
*/ | ||
var hashIt = function hashIt(object, isCircular) { | ||
var stringifiedValue = Object(__WEBPACK_IMPORTED_MODULE_0__utils__["b" /* getStringifiedValue */])(object, isCircular); | ||
/** | ||
* @function hasPlaceholder | ||
* | ||
* @description | ||
* determine if any of the arguments are placeholders | ||
* | ||
* @param {Arguments} args the args passed to the function | ||
* @param {number} arity the arity of the function | ||
* @returns {boolean} are any of the args placeholders | ||
*/ | ||
var hasPlaceholder = function hasPlaceholder(args, arity) { | ||
for (var index = 0; index < arity; index++) { | ||
if (args[index] === __) { | ||
return true; | ||
} | ||
} | ||
return Object(__WEBPACK_IMPORTED_MODULE_0__utils__["a" /* getIntegerHashValue */])(stringifiedValue); | ||
}; | ||
return false; | ||
}; | ||
var UNDEFINED_HASH = hashIt(undefined); | ||
var NULL_HASH = hashIt(null); | ||
var EMPTY_ARRAY_HASH = hashIt([]); | ||
var EMPTY_MAP_HASH = hashIt(new Map()); | ||
var EMPTY_NUMBER_HASH = hashIt(0); | ||
var EMPTY_OBJECT_HASH = hashIt({}); | ||
var EMPTY_SET_HASH = hashIt(new Set()); | ||
var EMPTY_STRING_HASH = hashIt(''); | ||
// utils | ||
var EMPTY_HASHES = (_EMPTY_HASHES = {}, _EMPTY_HASHES[EMPTY_ARRAY_HASH] = true, _EMPTY_HASHES[EMPTY_MAP_HASH] = true, _EMPTY_HASHES[EMPTY_NUMBER_HASH] = true, _EMPTY_HASHES[EMPTY_OBJECT_HASH] = true, _EMPTY_HASHES[EMPTY_SET_HASH] = true, _EMPTY_HASHES[EMPTY_STRING_HASH] = true, _EMPTY_HASHES[NULL_HASH] = true, _EMPTY_HASHES[UNDEFINED_HASH] = true, _EMPTY_HASHES); | ||
/** | ||
* @function curry | ||
* | ||
* @description | ||
* get the method passed as a curriable method based on its parameters | ||
* | ||
* @param {function} fn the method to make curriable | ||
* @param {number} [arity=fn.length] the arity of the curried method | ||
* @returns {function(...Array<any>): any} the fn passed as a curried function | ||
*/ | ||
function curry(fn) { | ||
var arity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : fn.length; | ||
/** | ||
* @function hashIt.isEqual | ||
* | ||
* @description | ||
* determine if all objects passed are equal in value to one another | ||
* | ||
* @param {...Array<*>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hashIt.isEqual = function () { | ||
for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) { | ||
objects[_key] = arguments[_key]; | ||
function curried() { | ||
var args = arguments; | ||
return args.length >= arity && !hasPlaceholder(args, arity) ? fn.apply(this, args) : function () { | ||
return curried.apply(this, getArgs(args, arguments)); | ||
}; | ||
} | ||
curried.arity = arity; | ||
curried.fn = fn; | ||
return curried; | ||
} | ||
var length = objects.length; | ||
curry.__ = __; | ||
if (length === 1) { | ||
throw new Error('isEqual requires at least two objects to be passed for comparison.'); | ||
/** | ||
* @function uncurry | ||
* | ||
* @description | ||
* return a function that is the non-curried version of the fn passed | ||
* | ||
* @param {function} curried the curried function to uncurry | ||
* @returns {function} the original fn | ||
*/ | ||
function uncurry(curried) { | ||
return curried.fn; | ||
} | ||
for (var index = 1; index < length; index++) { | ||
if (hashIt(objects[index - 1]) !== hashIt(objects[index])) { | ||
return false; | ||
curry.uncurry = uncurry; | ||
/** | ||
* @function first | ||
* | ||
* @description | ||
* get the first n number of items from the array as a new array (faster than native splice) | ||
* | ||
* @param {Array<any>} array the array to get the items from | ||
* @param {number} length the length to limit the size to | ||
* @returns {Array<any>} the array limited in size | ||
*/ | ||
var first = function first(array, length) { | ||
var newArray = new Array(length); | ||
for (var index = 0; index < length; index++) { | ||
newArray[index] = array[index]; | ||
} | ||
} | ||
return true; | ||
}; | ||
return newArray; | ||
}; | ||
/** | ||
* @function hashIt.isEmpty | ||
* | ||
* @description | ||
* determine if object is empty, meaning it is an array / object / map / set with values populated, | ||
* or is a string with no length, or is undefined or null | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object empty | ||
*/ | ||
hashIt.isEmpty = function (object) { | ||
return !!EMPTY_HASHES[hashIt(object)]; | ||
}; | ||
/** | ||
* @function getCircularValue | ||
* | ||
* @description | ||
* create a method that will get a placeholder for the circular value based | ||
* on the value saved in the cache for it | ||
* | ||
* @param {any} key the key of the object to stringify | ||
* @param {any} value the value of the object at key | ||
* @param {number} refCount the index of the ref | ||
* @returns {string} the circular value | ||
*/ | ||
var getCircularValue = function getCircularValue(key, value, refCount) { | ||
return '[ref-' + refCount + ']'; | ||
}; | ||
/** | ||
* @function hashIt.isNull | ||
* | ||
* @description | ||
* determine if object is null | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object null | ||
*/ | ||
hashIt.isNull = function (object) { | ||
return hashIt(object) === NULL_HASH; | ||
}; | ||
/** | ||
* @function indexOf | ||
* | ||
* @description | ||
* get the index of the value in the array (faster than native indexOf) | ||
* | ||
* @param {Array<any>} array the array to get the index of the value at | ||
* @param {any} value the value to match | ||
* @returns {number} the index of the value in array | ||
*/ | ||
var indexOf = function indexOf(array, value) { | ||
for (var index = 0; index < array.length; index++) { | ||
if (array[index] === value) { | ||
return index; | ||
} | ||
} | ||
/** | ||
* @function hashIt.isUndefined | ||
* | ||
* @description | ||
* determine if object is undefined | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object undefined | ||
*/ | ||
hashIt.isUndefined = function (object) { | ||
return hashIt(object) === UNDEFINED_HASH; | ||
}; | ||
return -1; | ||
}; | ||
/* harmony default export */ __webpack_exports__["default"] = (hashIt); | ||
/** | ||
* @function createReplacer | ||
* | ||
* @description | ||
* create a replacer method that handles circular values | ||
* | ||
* @param {function} [replacer] a custom replacer to use for non-circular values | ||
* @param {function} [circularReplacer] a custom replacer to use for circular methods | ||
* @returns {any} the value to stringify | ||
*/ | ||
var createReplacer = function createReplacer(replacer, circularReplacer) { | ||
var getCircularReplacer = circularReplacer || getCircularValue; | ||
var hasReplacer = typeof replacer === 'function'; | ||
/***/ }), | ||
/* 2 */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
var cache = [], | ||
locationOfThis = void 0, | ||
locationOfValue = void 0; | ||
"use strict"; | ||
/* unused harmony export getIterablePairs */ | ||
/* unused harmony export getStringFromArrayBuffer */ | ||
/* unused harmony export getTypePrefixedString */ | ||
/* unused harmony export getStringifiedElement */ | ||
/* unused harmony export getStringifiedValueByObjectClass */ | ||
/* unused harmony export getValueForStringification */ | ||
/* unused harmony export getCircularStackValue */ | ||
/* unused harmony export createReplacer */ | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return getIntegerHashValue; }); | ||
/* unused harmony export tryCatch */ | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return getStringifiedValue; }); | ||
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_json_prune__ = __webpack_require__(3); | ||
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_json_prune___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_json_prune__); | ||
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__constants__ = __webpack_require__(4); | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
return function (key, value) { | ||
if (cache.length) { | ||
locationOfThis = indexOf(cache, this); | ||
// external dependencies | ||
if (~locationOfThis) { | ||
cache = first(cache, locationOfThis + 1); | ||
} else { | ||
cache[cache.length] = this; | ||
} | ||
locationOfValue = indexOf(cache, value); | ||
// constants | ||
if (~locationOfValue) { | ||
return getCircularReplacer.call(this, key, value, locationOfValue); | ||
} | ||
} else { | ||
cache[0] = value; | ||
} | ||
return hasReplacer ? replacer.call(this, key, value) : value; | ||
}; | ||
}; | ||
var toString = Object.prototype.toString; | ||
// utils | ||
/** | ||
* @function getIterablePairs | ||
* | ||
* @description | ||
* get the [key,value] pairs for maps and sets | ||
* | ||
* @param {Map|Set} iterable the iterable to map | ||
* @param {string} type the type of object class | ||
* @returns {Array<Array>} the [key, value] pairs | ||
*/ | ||
var getIterablePairs = function getIterablePairs(iterable, type) { | ||
var pairs = [__WEBPACK_IMPORTED_MODULE_1__constants__["c" /* OBJECT_CLASS_MAP */][type]]; | ||
/** | ||
* @function stringify | ||
* | ||
* @description | ||
* strinigifer that handles circular values | ||
* | ||
* @param {any} value the value to stringify | ||
* @param {function} [replacer] a custom replacer function for stringifying standard values | ||
* @param {number} [indent] the number of spaces to indent the output by | ||
* @param {function} [circularReplacer] a custom replacer function for stringifying circular values | ||
* @returns {string} the stringified output | ||
*/ | ||
function stringify(value, replacer, indent, circularReplacer) { | ||
return JSON.stringify(value, createReplacer(replacer, circularReplacer), indent); | ||
} | ||
iterable.forEach(function (item, key) { | ||
pairs.push([key, item]); | ||
}); | ||
var _SELF_TAGS, _TOSTRING_TAGS, _TYPEDARRAY_TAGS, _UNPARSEABLE_TAGS; | ||
return pairs; | ||
}; | ||
/** | ||
* @constant {string} CIRCULAR_VALUE | ||
*/ | ||
var CIRCULAR_VALUE = '~'; | ||
/** | ||
* @function getStringFromArrayBuffer | ||
* | ||
* @description | ||
* get the string value of the buffer passed | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getStringFromArrayBuffer = function getStringFromArrayBuffer(buffer) { | ||
return typeof Uint16Array === 'undefined' ? '' : String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
}; | ||
/** | ||
* @function getTypePrefixedString | ||
* | ||
* @description | ||
* prepend type to string value | ||
* | ||
* @param {string} string the string to prepend | ||
* @param {string} type the type to add as a prefix | ||
* @returns {string} the prefixed string | ||
*/ | ||
var getTypePrefixedString = function getTypePrefixedString(string, type) { | ||
return __WEBPACK_IMPORTED_MODULE_1__constants__["c" /* OBJECT_CLASS_MAP */][type] + ' ' + string; | ||
}; | ||
/** | ||
* @constant {boolean} HAS_BUFFER_FROM_SUPPORT | ||
*/ | ||
var HAS_BUFFER_FROM_SUPPORT = typeof Buffer !== 'undefined' && typeof Buffer.from === 'function'; | ||
/** | ||
* @function getStringifiedElement | ||
* | ||
* @description | ||
* get the HTML element stringified by its type, attributes, and contents | ||
* | ||
* @param {HTMLElement} element the element to stringify | ||
* @returns {string} the stringified elements | ||
*/ | ||
var getStringifiedElement = function getStringifiedElement(element) { | ||
var attributes = element.attributes; | ||
/** | ||
* @constant {boolean} HAS_UINT16ARRAY_SUPPORT | ||
*/ | ||
var HAS_UINT16ARRAY_SUPPORT = typeof Uint16Array === 'function'; | ||
var attributesString = ''; | ||
/** | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
var HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
for (var index = 0; index < attributes.length; index++) { | ||
attributesString += attributes[index].name + '="' + attributes[index].value + '",'; | ||
} | ||
/** | ||
* @constant {RegExp} SVG_ELEMENT_REGEXP | ||
*/ | ||
var SVG_ELEMENT_REGEXP = /\[object (SVG(.*)Element)\]/; | ||
return element.tagName + ' ' + attributesString + ' ' + element.innerHTML; | ||
}; | ||
/** | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
*/ | ||
var OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'DocumentFragment', 'Error', 'Event', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet', 'Window']; | ||
/** | ||
* @function getStringifiedValueByObjectClass | ||
* | ||
* @description | ||
* get the stringified value of the object based based on its toString class | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @param {string} [passedObjectClass] the object class for the object passed | ||
* @returns {*} the value to stringify with | ||
*/ | ||
var getStringifiedValueByObjectClass = function getStringifiedValueByObjectClass(object, passedObjectClass) { | ||
var objectClass = passedObjectClass || toString.call(object); | ||
/** | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
*/ | ||
var OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["m" /* STRINGIFY_SELF_CLASSES */].indexOf(objectClass)) { | ||
return object; | ||
} | ||
return objectClasses; | ||
}, {}); | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["j" /* STRINGIFY_PREFIX_CLASSES */].indexOf(objectClass) || object === null) { | ||
return getTypePrefixedString(object, objectClass); | ||
} | ||
/** | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
*/ | ||
var OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
if (objectClass === __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].DATE) { | ||
return getTypePrefixedString(object.valueOf(), objectClass); | ||
} | ||
return objectClassTypes; | ||
}, {}); | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["h" /* STRINGIFY_ITERABLE_CLASSES */].indexOf(objectClass)) { | ||
return getIterablePairs(object, objectClass); | ||
} | ||
var ITERABLE_TAGS = { | ||
'[object Map]': true, | ||
'[object Set]': true | ||
}; | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["i" /* STRINGIFY_NOT_ENUMERABLE_CLASSES */].indexOf(objectClass)) { | ||
return getTypePrefixedString('NOT_ENUMERABLE', objectClass); | ||
} | ||
var PRIMITIVE_TAGS = { | ||
boolean: true, | ||
function: true, | ||
number: true, | ||
string: true, | ||
undefined: true | ||
}; | ||
if (objectClass === __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].ARRAYBUFFER) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object), objectClass); | ||
} | ||
var SELF_TAGS = (_SELF_TAGS = {}, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARGUMENTS] = true, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARRAY] = true, _SELF_TAGS); | ||
if (objectClass === __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].DATAVIEW) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object.buffer), objectClass); | ||
} | ||
var TOSTRING_TAGS = (_TOSTRING_TAGS = {}, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.REGEXP] = true, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.SYMBOL] = true, _TOSTRING_TAGS); | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["k" /* STRINGIFY_PREFIX_JOIN_CLASSES */].indexOf(objectClass)) { | ||
return getTypePrefixedString(object.join(','), objectClass); | ||
} | ||
var TYPEDARRAY_TAGS = (_TYPEDARRAY_TAGS = {}, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT32ARRAY] = true, _TYPEDARRAY_TAGS); | ||
if (objectClass === __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].MATH) { | ||
return __WEBPACK_IMPORTED_MODULE_1__constants__["b" /* MATH_OBJECT */]; | ||
} | ||
var UNPARSEABLE_TAGS = (_UNPARSEABLE_TAGS = {}, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.GENERATOR] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.PROMISE] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKMAP] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKSET] = true, _UNPARSEABLE_TAGS); | ||
return __WEBPACK_IMPORTED_MODULE_1__constants__["a" /* HTML_ELEMENT_REGEXP */].test(objectClass) ? getTypePrefixedString(getStringifiedElement(object), __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].HTMLELEMENT) : object; | ||
}; | ||
// external dependencies | ||
/** | ||
* @function getValueForStringification | ||
* | ||
* @description | ||
* get the string value for the object used for stringification | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @returns {*} the value to stringify with | ||
*/ | ||
var getValueForStringification = function getValueForStringification(object) { | ||
var type = typeof object === 'undefined' ? 'undefined' : _typeof(object); | ||
var charCodeAt = String.prototype.charCodeAt; | ||
var keys = Object.keys; | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["n" /* STRINGIFY_SELF_TYPES */].indexOf(type)) { | ||
return object; | ||
} | ||
/** | ||
* @function getFunctionName | ||
* | ||
* @description | ||
* get the name of the function based on a series of fallback attempts | ||
* | ||
* @param {function} fn the function to test | ||
* @returns {string} the function name | ||
*/ | ||
var getFunctionName = function getFunctionName(fn) { | ||
return fn.name || (fn.toString().match(/^\s*function\s*([^\(]*)/i) || [])[1] || 'anonymous'; | ||
}; | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["l" /* STRINGIFY_PREFIX_TYPES */].indexOf(type)) { | ||
return getTypePrefixedString(~__WEBPACK_IMPORTED_MODULE_1__constants__["o" /* STRINGIFY_TOSTRING_TYPES */].indexOf(type) ? object.constructor.prototype.toString.call(object) : object, toString.call(object)); | ||
} | ||
/** | ||
* @function getCircularValue | ||
* | ||
* @description | ||
* get the value used when circular references are found | ||
* | ||
* @returns {string} the value for stringification | ||
*/ | ||
var getCircularValue$1 = function getCircularValue() { | ||
return CIRCULAR_VALUE; | ||
}; | ||
return getStringifiedValueByObjectClass(object); | ||
}; | ||
/** | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2 | ||
* with enhancements for reduced collisions) | ||
* | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
var getIntegerHashValue = function getIntegerHashValue(string) { | ||
var index = string.length, | ||
hashA = 5381, | ||
hashB = 52711, | ||
charCode = void 0; | ||
/** | ||
* @function getCircularStackValue | ||
* | ||
* @description | ||
* get the value either from the recursive storage stack | ||
* or itself after being added to that stack | ||
* | ||
* @param {*} value the value to check for existing | ||
* @param {string} type the type of the value | ||
* @param {Array<*>} stack the current stack of values | ||
* @param {number} circularCounter the counter of circular references | ||
* @returns {*} the value to apply | ||
*/ | ||
var getCircularStackValue = function getCircularStackValue(value, type, stack, circularCounter) { | ||
if (!value) { | ||
return getTypePrefixedString(value, type); | ||
} | ||
while (index--) { | ||
charCode = charCodeAt.call(string, index); | ||
if (circularCounter > __WEBPACK_IMPORTED_MODULE_1__constants__["e" /* RECURSIVE_COUNTER_CUTOFF */]) { | ||
stack.length = 0; | ||
hashA = hashA * 33 ^ charCode; | ||
hashB = hashB * 33 ^ charCode; | ||
} | ||
return value; | ||
} | ||
return (hashA >>> 0) * 4096 + (hashB >>> 0); | ||
}; | ||
var existingIndex = stack.indexOf(value); | ||
/** | ||
* @function getSortedEvent | ||
* | ||
* @description | ||
* get the event object sorted by its properties | ||
* | ||
* @param {boolean} bubbles does the event bubble up through the DOM | ||
* @param {function} alias to stopPropagation | ||
* @param {boolean} cancelable is the event cancelable | ||
* @param {boolean} composed can the event bubble across the boundary to shadow DOM | ||
* @param {HTMLElement} [currentTarget] registered target for the event | ||
* @param {boolean} defaultPrevented has preventDefault been called on the event | ||
* @param {string} eventPhase the phase of the event flow being processed | ||
* @param {boolean} isTrusted was the event initiated by the browser | ||
* @param {HTMLElement} [target] the target with which the event was dispatched | ||
* @param {number} timeStamp the time at which the event was created | ||
* @param {string} type the name of the event | ||
* @returns {Object} the event object with all properties sorted | ||
*/ | ||
var getSortedEvent = function getSortedEvent(_ref) { | ||
var bubbles = _ref.bubbles, | ||
cancelBubble = _ref.cancelBubble, | ||
cancelable = _ref.cancelable, | ||
composed = _ref.composed, | ||
currentTarget = _ref.currentTarget, | ||
defaultPrevented = _ref.defaultPrevented, | ||
eventPhase = _ref.eventPhase, | ||
isTrusted = _ref.isTrusted, | ||
returnValue = _ref.returnValue, | ||
target = _ref.target, | ||
type = _ref.type; | ||
return { | ||
bubbles: bubbles, | ||
cancelBubble: cancelBubble, | ||
cancelable: cancelable, | ||
composed: composed, | ||
currentTarget: currentTarget, | ||
defaultPrevented: defaultPrevented, | ||
eventPhase: eventPhase, | ||
isTrusted: isTrusted, | ||
returnValue: returnValue, | ||
target: target, | ||
type: type | ||
}; | ||
}; | ||
if (!~existingIndex) { | ||
stack.push(value); | ||
/** | ||
* @function shouldSort | ||
* | ||
* @description | ||
* get the sort result based on the two values to compare | ||
* | ||
* @param {string} valueA the first value to compare | ||
* @param {string} valueB the second value to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
var shouldSort = function shouldSort(valueA, valueB) { | ||
return valueA > valueB; | ||
}; | ||
return value; | ||
} | ||
/** | ||
* @function shouldSortPair | ||
* | ||
* @description | ||
* get the sort result based on the two pairs to compare | ||
* | ||
* @param {Object} pairA the first pair to compare | ||
* @param {Object} pairB the second pair to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
var shouldSortPair = function shouldSortPair(pairA, pairB) { | ||
return shouldSort(pairA[0], pairB[0]); | ||
}; | ||
return '*Circular-' + existingIndex; | ||
}; | ||
/** | ||
* @function getPrefixedValue | ||
* | ||
* @description | ||
* get the value prefixed by the tag | ||
* | ||
* @param {string} tag the object tag | ||
* @param {any} value the value to stringify | ||
* @returns {string} the prefixed stringified value | ||
*/ | ||
var getPrefixedValue = function getPrefixedValue(tag, value) { | ||
return tag + '|' + value; | ||
}; | ||
/** | ||
* @function createReplacer | ||
* | ||
* @description | ||
* create the replacer function leveraging closure for recursive stack storage | ||
* | ||
* @param {Array<*>} stack the stack to store in memory | ||
* @returns {function} the replacer to use | ||
*/ | ||
var createReplacer = function createReplacer(stack) { | ||
var circularCounter = 1, | ||
objectClass = void 0; | ||
/** | ||
* @function sort | ||
* | ||
* @description | ||
* sort the array based on the fn passed | ||
* | ||
* @param {Array<any>} array the array to sort | ||
* @param {function} fn the sorting function | ||
* @returns {Array<any>} the sorted array | ||
*/ | ||
var sort = function sort(array, fn) { | ||
var subIndex = void 0, | ||
value = void 0; | ||
return function (key, value) { | ||
if (!key) { | ||
stack = [value]; | ||
for (var index = 0; index < array.length; index++) { | ||
value = array[index]; | ||
return value; | ||
} | ||
for (subIndex = index - 1; ~subIndex && fn(array[subIndex], value); subIndex--) { | ||
array[subIndex + 1] = array[subIndex]; | ||
} | ||
if (value === null) { | ||
return getStringifiedValueByObjectClass(value, __WEBPACK_IMPORTED_MODULE_1__constants__["d" /* OBJECT_CLASS_TYPE_MAP */].NULL); | ||
array[subIndex + 1] = value; | ||
} | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["p" /* STRINGIFY_TYPEOF_TYPES */].indexOf(typeof value === 'undefined' ? 'undefined' : _typeof(value))) { | ||
return getValueForStringification(value); | ||
return array; | ||
}; | ||
/** | ||
* @function getIterablePairs | ||
* | ||
* @description | ||
* get the pairs in the iterable for stringification | ||
* | ||
* @param {Map|Set} iterable the iterable to get the pairs for | ||
* @returns {Array<{key: string, value: any}>} the pairs | ||
*/ | ||
var getSortedIterablePairs = function getSortedIterablePairs(iterable) { | ||
var isMap = typeof iterable.get === 'function'; | ||
var pairs = []; | ||
iterable.forEach(function (value, key) { | ||
// eslint-disable-next-line no-use-before-define | ||
pairs.push(isMap ? [stringify$1(key), stringify$1(value)] : [stringify$1(value)]); | ||
}); | ||
sort(pairs, shouldSortPair); | ||
var finalPairs = new Array(iterable.size); | ||
var pair = void 0; | ||
for (var index = 0; index < iterable.size; index++) { | ||
pair = pairs[index]; | ||
finalPairs[index] = isMap ? '[' + pair[0] + ',' + pair[1] + ']' : pair[0]; | ||
} | ||
objectClass = toString.call(value); | ||
return getPrefixedValue(getFunctionName(iterable.constructor), '[' + finalPairs.join(',') + ']'); | ||
}; | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["f" /* REPLACE_RECURSIVE_VALUE_CLASSES */].indexOf(objectClass)) { | ||
return getCircularStackValue(value, objectClass, stack, ++circularCounter); | ||
/** | ||
* @function getSortedObject | ||
* | ||
* @description | ||
* get the object with the keys sorted | ||
* | ||
* @param {Object} object the object to sort | ||
* @returns {Object} the sorted object | ||
*/ | ||
var getSortedObject = function getSortedObject(object) { | ||
var objectKeys = sort(keys(object), shouldSort); | ||
var newObject = {}; | ||
var key = void 0; | ||
for (var index = 0; index < objectKeys.length; index++) { | ||
key = objectKeys[index]; | ||
newObject[key] = object[key]; | ||
} | ||
if (~__WEBPACK_IMPORTED_MODULE_1__constants__["g" /* REPLACE_STRINGIFICATION_CLASSES */].indexOf(objectClass)) { | ||
return getStringifiedValueByObjectClass(value, objectClass); | ||
return newObject; | ||
}; | ||
/** | ||
* @function getStringifiedArrayBufferFallback | ||
* | ||
* @description | ||
* get the string value of the buffer passed based on a Buffer | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getStringifiedArrayBufferFallback = function getStringifiedArrayBufferFallback(buffer) { | ||
return String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
}; | ||
/** | ||
* @function getStringifiedArrayBufferModern | ||
* | ||
* @description | ||
* get the string value of the buffer passed based on a Uint16Array | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getStringifiedArrayBufferModern = function getStringifiedArrayBufferModern(buffer) { | ||
return Buffer.from(buffer).toString('utf8'); | ||
}; | ||
/** | ||
* @function getStringifiedArrayBufferNoSupport | ||
* | ||
* @description | ||
* return a placeholder when no arraybuffer support exists | ||
* | ||
* @returns {string} the placeholder | ||
*/ | ||
var getStringifiedArrayBufferNoSupport = function getStringifiedArrayBufferNoSupport() { | ||
return ''; | ||
}; | ||
/** | ||
* @function getStringifiedArrayBuffer | ||
* | ||
* @description | ||
* get the string value of the buffer passed | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getStringifiedArrayBuffer = function () { | ||
return HAS_BUFFER_FROM_SUPPORT ? getStringifiedArrayBufferModern : HAS_UINT16ARRAY_SUPPORT ? getStringifiedArrayBufferFallback : getStringifiedArrayBufferNoSupport; | ||
}(); | ||
/** | ||
* @function getStringifiedDocumentFragment | ||
* | ||
* @description | ||
* build a string based on all the fragment's children | ||
* | ||
* @param {DocumentFragment} fragment the fragment to stringify | ||
* @returns {string} the stringified fragment | ||
*/ | ||
var getStringifiedDocumentFragment = function getStringifiedDocumentFragment(fragment) { | ||
var children = fragment.children; | ||
var innerHTML = ''; | ||
for (var index = 0; index < children.length; index++) { | ||
// eslint-disable-next-line no-use-before-define | ||
innerHTML += children[index].outerHTML; | ||
} | ||
return value; | ||
return innerHTML; | ||
}; | ||
}; | ||
/** | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2) | ||
* | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
var getIntegerHashValue = function getIntegerHashValue(string) { | ||
if (!string) { | ||
return 0; | ||
} | ||
/** | ||
* @function indexOf | ||
* | ||
* @description | ||
* get the index of the value in the array (faster than native indexOf) | ||
* | ||
* @param {Array<any>} array the array to get the index of the value at | ||
* @param {any} value the value to match | ||
* @returns {number} the index of the value in array | ||
*/ | ||
var indexOf$1 = function indexOf(array, value) { | ||
for (var index = 0; index < array.length; index++) { | ||
if (array[index] === value) { | ||
return index; | ||
} | ||
} | ||
var hashValue = 5381; | ||
return -1; | ||
}; | ||
for (var index = 0; index < string.length; index++) { | ||
hashValue = (hashValue << 5) + hashValue + string.charCodeAt(index); | ||
} | ||
/** | ||
* @function getNormalizedValue | ||
* | ||
* @description | ||
* get the value normalized for stringification | ||
* | ||
* @param {any} value the value to normalize | ||
* @param {WeakMap|Object} sortedCache the cache of sorted objects | ||
* @returns {any} the normalized value | ||
*/ | ||
var getNormalizedValue = function getNormalizedValue(value, sortedCache) { | ||
var type = typeof value; | ||
return hashValue >>> 0; | ||
}; | ||
if (type === 'string') { | ||
return value; | ||
} | ||
/** | ||
* @function tryCatch | ||
* | ||
* @description | ||
* move try/catch to standalone function as any function that contains a try/catch | ||
* is not optimized (this allows optimization for as much as possible) | ||
* | ||
* @param {*} value the value to stringify | ||
* @returns {string} the stringified value | ||
*/ | ||
var tryCatch = function tryCatch(value) { | ||
try { | ||
return JSON.stringify(value, createReplacer([])); | ||
} catch (exception) { | ||
return __WEBPACK_IMPORTED_MODULE_0_json_prune___default()(value); | ||
} | ||
}; | ||
if (PRIMITIVE_TAGS[type]) { | ||
return getPrefixedValue(type, value); | ||
} | ||
/** | ||
* @function getStringifiedValue | ||
* | ||
* @description | ||
* stringify the object passed leveraging JSON.stringify | ||
* with REPLACER, falling back to prune | ||
* | ||
* @param {*} object the object to stringify | ||
* @param {boolean} isCircular is the object circular or not | ||
* @returns {string} the stringified object | ||
*/ | ||
var getStringifiedValue = function getStringifiedValue(object, isCircular) { | ||
var valueForStringification = getValueForStringification(object); | ||
if (value === null) { | ||
return getPrefixedValue('null', value); | ||
} | ||
if (typeof valueForStringification === 'string') { | ||
return valueForStringification; | ||
} | ||
var tag = toString.call(value); | ||
return isCircular ? tryCatch(getValueForStringification(object)) : JSON.stringify(valueForStringification, createReplacer([])); | ||
}; | ||
if (SELF_TAGS[tag]) { | ||
return value; | ||
} | ||
/***/ }), | ||
/* 3 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
if (tag === OBJECT_CLASS_TYPE_MAP.OBJECT) { | ||
if (~indexOf$1(sortedCache, value)) { | ||
return CIRCULAR_VALUE; | ||
} | ||
// JSON.prune : a function to stringify any object without overflow | ||
// two additional optional parameters : | ||
// - the maximal depth (default : 6) | ||
// - the maximal length of arrays (default : 50) | ||
// You can also pass an "options" object. | ||
// examples : | ||
// var json = JSON.prune(window) | ||
// var arr = Array.apply(0,Array(1000)); var json = JSON.prune(arr, 4, 20) | ||
// var json = JSON.prune(window.location, {inheritedProperties:true}) | ||
// Web site : http://dystroy.org/JSON.prune/ | ||
// JSON.prune on github : https://github.com/Canop/JSON.prune | ||
// This was discussed here : http://stackoverflow.com/q/13861254/263525 | ||
// The code is based on Douglas Crockford's code : https://github.com/douglascrockford/JSON-js/blob/master/json2.js | ||
// No effort was done to support old browsers. JSON.prune will fail on IE8. | ||
(function () { | ||
'use strict'; | ||
sortedCache.push(value); | ||
var DEFAULT_MAX_DEPTH = 6; | ||
var DEFAULT_ARRAY_MAX_LENGTH = 50; | ||
var DEFAULT_PRUNED_VALUE = '"-pruned-"'; | ||
var seen; // Same variable used for all stringifications | ||
var iterator; // either forEachEnumerableOwnProperty, forEachEnumerableProperty or forEachProperty | ||
// iterates on enumerable own properties (default behavior) | ||
var forEachEnumerableOwnProperty = function(obj, callback) { | ||
for (var k in obj) { | ||
if (Object.prototype.hasOwnProperty.call(obj, k)) callback(k); | ||
} | ||
}; | ||
// iterates on enumerable properties | ||
var forEachEnumerableProperty = function(obj, callback) { | ||
for (var k in obj) callback(k); | ||
}; | ||
// iterates on properties, even non enumerable and inherited ones | ||
// This is dangerous | ||
var forEachProperty = function(obj, callback, excluded) { | ||
if (obj==null) return; | ||
excluded = excluded || {}; | ||
Object.getOwnPropertyNames(obj).forEach(function(k){ | ||
if (!excluded[k]) { | ||
callback(k); | ||
excluded[k] = true; | ||
} | ||
}); | ||
forEachProperty(Object.getPrototypeOf(obj), callback, excluded); | ||
}; | ||
return getSortedObject(value, sortedCache); | ||
} | ||
Object.defineProperty(Date.prototype, "toPrunedJSON", {value:Date.prototype.toJSON}); | ||
if (TOSTRING_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.toString()); | ||
} | ||
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | ||
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, | ||
meta = { // table of character substitutions | ||
'\b': '\\b', | ||
'\t': '\\t', | ||
'\n': '\\n', | ||
'\f': '\\f', | ||
'\r': '\\r', | ||
'"' : '\\"', | ||
'\\': '\\\\' | ||
}; | ||
if (ITERABLE_TAGS[tag]) { | ||
if (~indexOf$1(sortedCache, value)) { | ||
return CIRCULAR_VALUE; | ||
} | ||
function quote(string) { | ||
escapable.lastIndex = 0; | ||
return escapable.test(string) ? '"' + string.replace(escapable, function (a) { | ||
var c = meta[a]; | ||
return typeof c === 'string' | ||
? c | ||
: '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); | ||
}) + '"' : '"' + string + '"'; | ||
} | ||
sortedCache.push(value); | ||
return getSortedIterablePairs(value); | ||
} | ||
var prune = function (value, depthDecr, arrayMaxLength) { | ||
var prunedString = DEFAULT_PRUNED_VALUE; | ||
var replacer; | ||
if (typeof depthDecr == "object") { | ||
var options = depthDecr; | ||
depthDecr = options.depthDecr; | ||
arrayMaxLength = options.arrayMaxLength; | ||
iterator = options.iterator || forEachEnumerableOwnProperty; | ||
if (options.allProperties) iterator = forEachProperty; | ||
else if (options.inheritedProperties) iterator = forEachEnumerableProperty | ||
if ("prunedString" in options) { | ||
prunedString = options.prunedString; | ||
} | ||
if (options.replacer) { | ||
replacer = options.replacer; | ||
} | ||
} else { | ||
iterator = forEachEnumerableOwnProperty; | ||
} | ||
seen = []; | ||
depthDecr = depthDecr || DEFAULT_MAX_DEPTH; | ||
arrayMaxLength = arrayMaxLength || DEFAULT_ARRAY_MAX_LENGTH; | ||
function str(key, holder, depthDecr) { | ||
var i, k, v, length, partial, value = holder[key]; | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DATE) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.getTime()); | ||
} | ||
if (value && typeof value === 'object' && typeof value.toPrunedJSON === 'function') { | ||
value = value.toPrunedJSON(key); | ||
} | ||
if (value && typeof value.toJSON === 'function') { | ||
value = value.toJSON(); | ||
} | ||
if (tag === OBJECT_CLASS_TYPE_MAP.ERROR) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.stack); | ||
} | ||
switch (typeof value) { | ||
case 'string': | ||
return quote(value); | ||
case 'number': | ||
return isFinite(value) ? String(value) : 'null'; | ||
case 'boolean': | ||
case 'null': | ||
return String(value); | ||
case 'object': | ||
if (!value) { | ||
return 'null'; | ||
} | ||
if (depthDecr<=0 || seen.indexOf(value)!==-1) { | ||
if (replacer) { | ||
var replacement = replacer(value, prunedString, true); | ||
return replacement===undefined ? undefined : ''+replacement; | ||
} | ||
return prunedString; | ||
} | ||
seen.push(value); | ||
partial = []; | ||
if (Object.prototype.toString.apply(value) === '[object Array]') { | ||
length = Math.min(value.length, arrayMaxLength); | ||
for (i = 0; i < length; i += 1) { | ||
partial[i] = str(i, value, depthDecr-1) || 'null'; | ||
} | ||
v = '[' + partial.join(',') + ']'; | ||
if (replacer && value.length>arrayMaxLength) return replacer(value, v, false); | ||
return v; | ||
} | ||
iterator(value, function(k) { | ||
try { | ||
v = str(k, value, depthDecr-1); | ||
if (v) partial.push(quote(k) + ':' + v); | ||
} catch (e) { | ||
// this try/catch due to forbidden accessors on some objects | ||
} | ||
}); | ||
return '{' + partial.join(',') + '}'; | ||
case 'function': | ||
case 'undefined': | ||
return replacer ? replacer(value, undefined, false) : undefined; | ||
} | ||
} | ||
return str('', {'': value}, depthDecr); | ||
}; | ||
prune.log = function() { | ||
console.log.apply(console, Array.prototype.map.call(arguments, function(v) { | ||
return JSON.parse(JSON.prune(v)); | ||
})); | ||
}; | ||
prune.forEachProperty = forEachProperty; // you might want to also assign it to Object.forEachProperty | ||
if (tag === OBJECT_CLASS_TYPE_MAP.EVENT) { | ||
return getSortedEvent(value); | ||
} | ||
if (true) module.exports = prune; | ||
else JSON.prune = prune; | ||
}()); | ||
if (UNPARSEABLE_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], 'NOT_ENUMERABLE'); | ||
} | ||
if (HTML_ELEMENT_REGEXP.test(tag) || SVG_ELEMENT_REGEXP.test(tag)) { | ||
return getPrefixedValue(tag.slice(8, -1), value.outerHTML); | ||
} | ||
/***/ }), | ||
/* 4 */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DOCUMENTFRAGMENT) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedDocumentFragment(value)); | ||
} | ||
"use strict"; | ||
/* unused harmony export OBJECT_CLASSES */ | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return OBJECT_CLASS_MAP; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return OBJECT_CLASS_TYPE_MAP; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "e", function() { return RECURSIVE_COUNTER_CUTOFF; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "f", function() { return REPLACE_RECURSIVE_VALUE_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "g", function() { return REPLACE_STRINGIFICATION_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "m", function() { return STRINGIFY_SELF_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "j", function() { return STRINGIFY_PREFIX_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return STRINGIFY_ITERABLE_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "i", function() { return STRINGIFY_NOT_ENUMERABLE_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "k", function() { return STRINGIFY_PREFIX_JOIN_CLASSES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "n", function() { return STRINGIFY_SELF_TYPES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "l", function() { return STRINGIFY_PREFIX_TYPES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "o", function() { return STRINGIFY_TOSTRING_TYPES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "p", function() { return STRINGIFY_TYPEOF_TYPES; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return HTML_ELEMENT_REGEXP; }); | ||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return MATH_OBJECT; }); | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
if (TYPEDARRAY_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.join(',')); | ||
} | ||
/** | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
*/ | ||
var OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet']; | ||
if (tag === OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value)); | ||
} | ||
/** | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
*/ | ||
var OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DATAVIEW) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value.buffer)); | ||
} | ||
return objectClasses; | ||
}, {}); | ||
return value; | ||
}; | ||
/** | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
*/ | ||
var OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
/** | ||
* @function replacer | ||
* | ||
* @description | ||
* create the replacer function used for stringification | ||
* | ||
* @param {WeakSet|Object} sortedCache the cache to use for sorting objects | ||
* @returns {function(key: string, value: any)} function getting the normalized value | ||
*/ | ||
var createReplacer$1 = function createReplacer(sortedCache) { | ||
return function (key, value) { | ||
return getNormalizedValue(value, sortedCache); | ||
}; | ||
}; | ||
return objectClassTypes; | ||
}, {}); | ||
/** | ||
* @function stringify | ||
* | ||
* @description | ||
* stringify the value based on the options passed | ||
* | ||
* @param {any} value the value to stringify | ||
* @returns {string} the stringified value | ||
*/ | ||
function stringify$1(value) { | ||
return typeof value === 'object' && value && !(value instanceof RegExp || value instanceof Date) ? stringify(value, createReplacer$1([]), null, getCircularValue$1) : getNormalizedValue(value); | ||
} | ||
/** | ||
* @constant {number} RECURSIVE_COUNTER_CUTOFF | ||
*/ | ||
var RECURSIVE_COUNTER_CUTOFF = 512; | ||
// external dependencies | ||
/** | ||
* @constant {Array<string>} REPLACE_RECURSIVE_VALUE_CLASSES | ||
*/ | ||
var REPLACE_RECURSIVE_VALUE_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT]; | ||
/** | ||
* @function hash | ||
* | ||
* @description | ||
* hash the value passed to a unique, consistent hash value | ||
* | ||
* @param {any} value the value to hash | ||
* @returns {number} the object hash | ||
*/ | ||
var hash = function hash(value) { | ||
return getIntegerHashValue(stringify$1(value)); | ||
}; | ||
/** | ||
* @constant {Array<string>} REPLACE_STRINGIFICATION_CLASSES | ||
*/ | ||
var REPLACE_STRINGIFICATION_CLASSES = [OBJECT_CLASS_TYPE_MAP.DATE, OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET, OBJECT_CLASS_TYPE_MAP.REGEXP, OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.GENERATORFUNCTION, OBJECT_CLASS_TYPE_MAP.MATH, OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER, OBJECT_CLASS_TYPE_MAP.DATAVIEW, OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY, OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
/** | ||
* @function hash.is | ||
* | ||
* @description | ||
* create a comparator for the first object passed to determine if the second is equal | ||
* | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
hash.is = curry(function (object, otherObject) { | ||
return hash(object) === hash(otherObject); | ||
}); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_CLASSES | ||
*/ | ||
var STRINGIFY_SELF_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT, OBJECT_CLASS_TYPE_MAP.ARGUMENTS]; | ||
/** | ||
* @function hash.is.all | ||
* | ||
* @description | ||
* determine if all of the objects passed are equal in value to the first | ||
* | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hash.is.all = curry(function () { | ||
for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) { | ||
objects[_key] = arguments[_key]; | ||
} | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_CLASSES | ||
*/ | ||
var STRINGIFY_PREFIX_CLASSES = [OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.REGEXP]; | ||
var isEqual = hash.is(objects.shift()); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_ITERABLE_CLASSES | ||
*/ | ||
var STRINGIFY_ITERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET]; | ||
for (var index = 0; index < objects.length; index++) { | ||
if (!isEqual(objects[index])) { | ||
return false; | ||
} | ||
} | ||
/** | ||
* @constant {Array<string>} STRINGIFY_NOT_ENUMERABLE_CLASSES | ||
*/ | ||
var STRINGIFY_NOT_ENUMERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
return true; | ||
}, 2); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_JOIN_CLASSES | ||
*/ | ||
var STRINGIFY_PREFIX_JOIN_CLASSES = [OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY]; | ||
/** | ||
* @function hash.is.any | ||
* | ||
* @description | ||
* determine if any of the objects passed are equal in value to the first | ||
* | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hash.is.any = curry(function () { | ||
for (var _len2 = arguments.length, objects = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
objects[_key2] = arguments[_key2]; | ||
} | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_TYPES | ||
*/ | ||
var STRINGIFY_SELF_TYPES = ['string', 'number']; | ||
var isEqual = hash.is(objects.shift()); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_TYPES | ||
*/ | ||
var STRINGIFY_PREFIX_TYPES = ['boolean', 'undefined', 'function', 'symbol']; | ||
for (var index = 0; index < objects.length; index++) { | ||
if (isEqual(objects[index])) { | ||
return true; | ||
} | ||
} | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TOSTRING_TYPES | ||
*/ | ||
var STRINGIFY_TOSTRING_TYPES = ['symbol', 'function']; | ||
return false; | ||
}, 2); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TYPEOF_TYPES | ||
*/ | ||
var STRINGIFY_TYPEOF_TYPES = [].concat(STRINGIFY_SELF_TYPES, STRINGIFY_PREFIX_TYPES); | ||
/** | ||
* @function hash.is.not | ||
* | ||
* @description | ||
* create a comparator for the first object passed to determine if the second is not equal | ||
* | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
hash.is.not = curry(function (object, otherObject) { | ||
return hash(object) !== hash(otherObject); | ||
}); | ||
/** | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
var HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
exports.hash = hash; | ||
exports.default = hash; | ||
/** | ||
* @constant {Object} MATH_OBJECT | ||
*/ | ||
var MATH_OBJECT = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT2'].reduce(function (mathObject, property) { | ||
var _extends2; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
return _extends({}, mathObject, (_extends2 = {}, _extends2[property] = Math[property], _extends2)); | ||
}, {}); | ||
/***/ }) | ||
/******/ ]); | ||
}); | ||
//# sourceMappingURL=hash-it.js.map | ||
}))); | ||
//# sourceMappingURL=hash-it.js.map |
@@ -1,1 +0,1 @@ | ||
!(function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define("hashIt",[],n):"object"==typeof exports?exports.hashIt=n():t.hashIt=n()})("undefined"!=typeof self?self:this,(function(){return (function(t){function n(e){if(r[e])return r[e].exports;var o=r[e]={i:e,l:!1,exports:{}};return t[e].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var r={};return n.m=t,n.c=r,n.d=function(t,r,e){n.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:e})},n.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(r,"a",r),r},n.o=function(t,n){return Object.prototype.hasOwnProperty.call(t,n)},n.p="",n(n.s=0)})([function(t,n,r){t.exports=r(1)},function(t,n,r){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var e,o=r(2),u=r.n(o),i=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},f=["Arguments","Array","ArrayBuffer","Boolean","DataView","Date","Error","Float32Array","Float64Array","Function","Generator","GeneratorFunction","HTMLElement","Int8Array","Int16Array","Int32Array","Map","Math","Null","Number","Object","Promise","RegExp","Set","String","Symbol","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","Undefined","WeakMap","WeakSet"],a=f.reduce((function(t,n){return t["[object "+n+"]"]=n,t}),{}),c=Object.keys(a).reduce((function(t,n){return t[a[n].toUpperCase()]=n,t}),{}),l=[c.ARRAY,c.OBJECT],A=[c.DATE,c.MAP,c.SET,c.REGEXP,c.ERROR,c.GENERATORFUNCTION,c.MATH,c.ARRAYBUFFER,c.DATAVIEW,c.FLOAT32ARRAY,c.FLOAT64ARRAY,c.INT8ARRAY,c.INT16ARRAY,c.INT32ARRAY,c.UINT8ARRAY,c.UINT8CLAMPEDARRAY,c.UINT16ARRAY,c.UINT32ARRAY,c.PROMISE,c.GENERATOR,c.WEAKMAP,c.WEAKSET],p=[c.ARRAY,c.OBJECT,c.ARGUMENTS],s=[c.ERROR,c.REGEXP],d=[c.MAP,c.SET],y=[c.PROMISE,c.GENERATOR,c.WEAKMAP,c.WEAKSET],R=[c.FLOAT32ARRAY,c.FLOAT64ARRAY,c.INT8ARRAY,c.INT16ARRAY,c.INT32ARRAY,c.UINT8ARRAY,c.UINT8CLAMPEDARRAY,c.UINT16ARRAY,c.UINT32ARRAY],O=["string","number"],E=["boolean","undefined","function","symbol"],b=["symbol","function"],T=[].concat(O,E),v=/\[object (HTML(.*)Element)\]/,N=["E","LN2","LN10","LOG2E","LOG10E","PI","SQRT1_2","SQRT2"].reduce((function(t,n){var r;return i({},t,(r={},r[n]=Math[n],r))}),{}),h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},S=Object.prototype.toString,g=function(t,n){var r=[a[n]];return t.forEach((function(t,n){r.push([n,t])})),r},x=function(t){return"undefined"==typeof Uint16Array?"":String.fromCharCode.apply(null,new Uint16Array(t))},m=function(t,n){return a[n]+" "+t},I=function(t){for(var n=t.attributes,r="",e=0;e<n.length;e++)r+=n[e].name+'="'+n[e].value+'",';return t.tagName+" "+r+" "+t.innerHTML},j=function(t,n){var r=n||S.call(t);return~p.indexOf(r)?t:~s.indexOf(r)||null===t?m(t,r):r===c.DATE?m(t.valueOf(),r):~d.indexOf(r)?g(t,r):~y.indexOf(r)?m("NOT_ENUMERABLE",r):r===c.ARRAYBUFFER?m(x(t),r):r===c.DATAVIEW?m(x(t.buffer),r):~R.indexOf(r)?m(t.join(","),r):r===c.MATH?N:v.test(r)?m(I(t),c.HTMLELEMENT):t},M=function(t){var n=void 0===t?"undefined":h(t);return~O.indexOf(n)?t:~E.indexOf(n)?m(~b.indexOf(n)?t.constructor.prototype.toString.call(t):t,S.call(t)):j(t)},P=function(t,n,r,e){if(!t)return m(t,n);if(e>512)return r.length=0,t;var o=r.indexOf(t);return~o?"*Circular-"+o:(r.push(t),t)},U=function(t){var n=1,r=void 0;return function(e,o){return e?null===o?j(o,c.NULL):~T.indexOf(void 0===o?"undefined":h(o))?M(o):(r=S.call(o),~l.indexOf(r)?P(o,r,t,++n):~A.indexOf(r)?j(o,r):o):(t=[o],o)}},Y=function(t){if(!t)return 0;for(var n=5381,r=0;r<t.length;r++)n=(n<<5)+n+t.charCodeAt(r);return n>>>0},L=function(t){try{return JSON.stringify(t,U([]))}catch(n){return u()(t)}},F=function(t,n){var r=M(t);return"string"==typeof r?r:n?L(M(t)):JSON.stringify(r,U([]))},w=function(t,n){var r=F(t,n);return Y(r)},C=w(void 0),D=w(null),G=w([]),J=w(new Map),W=w(0),B=w({}),H=w(new Set),_=w(""),K=(e={},e[G]=!0,e[J]=!0,e[W]=!0,e[B]=!0,e[H]=!0,e[_]=!0,e[D]=!0,e[C]=!0,e);w.isEqual=function(){for(var t=arguments.length,n=Array(t),r=0;r<t;r++)n[r]=arguments[r];var e=n.length;if(1===e)throw new Error("isEqual requires at least two objects to be passed for comparison.");for(var o=1;o<e;o++)if(w(n[o-1])!==w(n[o]))return!1;return!0},w.isEmpty=function(t){return!!K[w(t)]},w.isNull=function(t){return w(t)===D},w.isUndefined=function(t){return w(t)===C};n.default=w},function(t,n,r){!(function(){"use strict";function n(t){return f.lastIndex=0,f.test(t)?'"'+t.replace(f,(function(t){var n=a[t];return"string"==typeof n?n:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)}))+'"':'"'+t+'"'}var r,e,o=function(t,n){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&n(r)},u=function(t,n){for(var r in t)n(r)},i=function(t,n,r){null!=t&&(r=r||{},Object.getOwnPropertyNames(t).forEach((function(t){r[t]||(n(t),r[t]=!0)})),i(Object.getPrototypeOf(t),n,r))};Object.defineProperty(Date.prototype,"toPrunedJSON",{value:Date.prototype.toJSON});var f=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,a={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},c=function(t,f,a){function c(t,o,u){var i,f,p,s,d=o[t];switch(d&&"object"==typeof d&&"function"==typeof d.toPrunedJSON&&(d=d.toPrunedJSON(t)),d&&"function"==typeof d.toJSON&&(d=d.toJSON()),typeof d){case"string":return n(d);case"number":return isFinite(d)?String(d):"null";case"boolean":case"null":return String(d);case"object":if(!d)return"null";if(u<=0||-1!==r.indexOf(d)){if(l){var y=l(d,A,!0);return void 0===y?void 0:""+y}return A}if(r.push(d),s=[],"[object Array]"===Object.prototype.toString.apply(d)){for(p=Math.min(d.length,a),i=0;i<p;i+=1)s[i]=c(i,d,u-1)||"null";return f="["+s.join(",")+"]",l&&d.length>a?l(d,f,!1):f}return e(d,(function(t){try{f=c(t,d,u-1),f&&s.push(n(t)+":"+f)}catch(t){}})),"{"+s.join(",")+"}";case"function":case"undefined":return l?l(d,void 0,!1):void 0}}var l,A='"-pruned-"';if("object"==typeof f){var p=f;f=p.depthDecr,a=p.arrayMaxLength,e=p.iterator||o,p.allProperties?e=i:p.inheritedProperties&&(e=u),"prunedString"in p&&(A=p.prunedString),p.replacer&&(l=p.replacer)}else e=o;return r=[],f=f||6,a=a||50,c("",{"":t},f)};c.log=function(){},c.forEachProperty=i,t.exports=c})()}])})); | ||
!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r(n.hashIt={})}(this,function(n){"use strict";var o="function"==typeof Symbol?Symbol("curriable placeholder"):60881;function r(r){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:r.length;function e(){var n=arguments;return n.length>=t&&!function(n,r){for(var t=0;t<r;t++)if(n[t]===o)return!0;return!1}(n,t)?r.apply(this,n):function(){return e.apply(this,function(n,r){for(var t=new Array(n.length),e=0,u=0;u<n.length;u++)t[u]=n[u]===o&&e<r.length?r[e++]:n[u];if(e<r.length)for(;e<r.length;e++)t.push(r[e]);return t}(n,arguments))}}return e.arity=t,e.fn=r,e}r.__=o,r.uncurry=function(n){return n.fn};var t,e,u,i,a=function(n,r,t){return"[ref-"+t+"]"},c=function(n,r){for(var t=0;t<n.length;t++)if(n[t]===r)return t;return-1},f=function(t,n){var e=n||a,u="function"==typeof t,o=[],i=void 0,f=void 0;return function(n,r){if(o.length){if(~(i=c(o,this))?o=function(n,r){for(var t=new Array(r),e=0;e<r;e++)t[e]=n[e];return t}(o,i+1):o[o.length]=this,~(f=c(o,r)))return e.call(this,n,r,f)}else o[0]=r;return u?t.call(this,n,r):r}};var l="undefined"!=typeof Buffer&&"function"==typeof Buffer.from,s="function"==typeof Uint16Array,A=/\[object (HTML(.*)Element)\]/,y=/\[object (SVG(.*)Element)\]/,h=["Arguments","Array","ArrayBuffer","Boolean","DataView","Date","DocumentFragment","Error","Event","Float32Array","Float64Array","Function","Generator","GeneratorFunction","HTMLElement","Int8Array","Int16Array","Int32Array","Map","Null","Number","Object","Promise","RegExp","Set","String","Symbol","Uint8Array","Uint8ClampedArray","Uint16Array","Uint32Array","Undefined","WeakMap","WeakSet","Window"].reduce(function(n,r){return n["[object "+r+"]"]=r,n},{}),d=Object.keys(h).reduce(function(n,r){return n[h[r].toUpperCase()]=r,n},{}),g={"[object Map]":!0,"[object Set]":!0},p={boolean:!0,function:!0,number:!0,string:!0,undefined:!0},v=((t={})[d.ARGUMENTS]=!0,t[d.ARRAY]=!0,t),R=((e={})[d.REGEXP]=!0,e[d.SYMBOL]=!0,e),b=((u={})[d.FLOAT32ARRAY]=!0,u[d.FLOAT64ARRAY]=!0,u[d.INT8ARRAY]=!0,u[d.INT16ARRAY]=!0,u[d.INT32ARRAY]=!0,u[d.UINT8ARRAY]=!0,u[d.UINT8CLAMPEDARRAY]=!0,u[d.UINT16ARRAY]=!0,u[d.UINT32ARRAY]=!0,u),E=((i={})[d.GENERATOR]=!0,i[d.PROMISE]=!0,i[d.WEAKMAP]=!0,i[d.WEAKSET]=!0,i),T=String.prototype.charCodeAt,m=Object.keys,S=function(){return"~"},N=function(n,r){return r<n},M=function(n,r){return N(n[0],r[0])},U=function(n,r){return n+"|"+r},O=function(n,r){for(var t=void 0,e=void 0,u=0;u<n.length;u++){for(e=n[u],t=u-1;~t&&r(n[t],e);t--)n[t+1]=n[t];n[t+1]=e}return n},j=l?function(n){return Buffer.from(n).toString("utf8")}:s?function(n){return String.fromCharCode.apply(null,new Uint16Array(n))}:function(){return""},I=function(n,r){for(var t=0;t<n.length;t++)if(n[t]===r)return t;return-1},Y=function(n,r){var t=typeof n;if("string"===t)return n;if(p[t])return U(t,n);if(null===n)return U("null",n);var e,u=toString.call(n);return v[u]?n:u===d.OBJECT?~I(r,n)?"~":(r.push(n),function(n){for(var r=O(m(n),N),t={},e=void 0,u=0;u<r.length;u++)t[e=r[u]]=n[e];return t}(n)):R[u]?U(h[u],n.toString()):g[u]?~I(r,n)?"~":(r.push(n),function(n){var t="function"==typeof n.get,e=[];n.forEach(function(n,r){e.push(t?[F(r),F(n)]:[F(n)])}),O(e,M);for(var r,u=new Array(n.size),o=void 0,i=0;i<n.size;i++)o=e[i],u[i]=t?"["+o[0]+","+o[1]+"]":o[0];return U((r=n.constructor).name||(r.toString().match(/^\s*function\s*([^\(]*)/i)||[])[1]||"anonymous","["+u.join(",")+"]")}(n)):u===d.DATE?U(h[u],n.getTime()):u===d.ERROR?U(h[u],n.stack):u===d.EVENT?{bubbles:(e=n).bubbles,cancelBubble:e.cancelBubble,cancelable:e.cancelable,composed:e.composed,currentTarget:e.currentTarget,defaultPrevented:e.defaultPrevented,eventPhase:e.eventPhase,isTrusted:e.isTrusted,returnValue:e.returnValue,target:e.target,type:e.type}:E[u]?U(h[u],"NOT_ENUMERABLE"):A.test(u)||y.test(u)?U(u.slice(8,-1),n.outerHTML):u===d.DOCUMENTFRAGMENT?U(h[u],function(n){for(var r=n.children,t="",e=0;e<r.length;e++)t+=r[e].outerHTML;return t}(n)):b[u]?U(h[u],n.join(",")):u===d.ARRAYBUFFER?U(h[u],j(n)):u===d.DATAVIEW?U(h[u],j(n.buffer)):n},B=function(t){return function(n,r){return Y(r,t)}};function F(n){return"object"==typeof n&&n&&!(n instanceof RegExp||n instanceof Date)?(r=n,t=B([]),e=null,u=S,JSON.stringify(r,f(t,u),e)):Y(n);var r,t,e,u}var P=function(n){return function(n){for(var r=n.length,t=5381,e=52711,u=void 0;r--;)t=33*t^(u=T.call(n,r)),e=33*e^u;return 4096*(t>>>0)+(e>>>0)}(F(n))};(P.is=r(function(n,r){return P(n)===P(r)})).all=r(function(){for(var n=arguments.length,r=Array(n),t=0;t<n;t++)r[t]=arguments[t];for(var e=P.is(r.shift()),u=0;u<r.length;u++)if(!e(r[u]))return!1;return!0},2),P.is.any=r(function(){for(var n=arguments.length,r=Array(n),t=0;t<n;t++)r[t]=arguments[t];for(var e=P.is(r.shift()),u=0;u<r.length;u++)if(e(r[u]))return!0;return!1},2),P.is.not=r(function(n,r){return P(n)!==P(r)}),n.hash=P,n.default=P,Object.defineProperty(n,"__esModule",{value:!0})}); |
@@ -1,98 +0,75 @@ | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _SELF_TAGS, _TOSTRING_TAGS, _TYPEDARRAY_TAGS, _UNPARSEABLE_TAGS; | ||
/** | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
* @constant {string} CIRCULAR_VALUE | ||
*/ | ||
export var OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet']; | ||
export var CIRCULAR_VALUE = '~'; | ||
/** | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
* @constant {Array<any>} EMPTY_VALUES | ||
*/ | ||
export var OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
export var EMPTY_VALUES = [void 0, null, '', [], {}].concat(typeof Map === 'function' ? [new Map()] : []).concat(typeof Set === 'function' ? [new Set()] : []); | ||
return objectClasses; | ||
}, {}); | ||
/** | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
* @constant {boolean} HAS_BUFFER_FROM_SUPPORT | ||
*/ | ||
export var OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
export var HAS_BUFFER_FROM_SUPPORT = typeof Buffer !== 'undefined' && typeof Buffer.from === 'function'; | ||
return objectClassTypes; | ||
}, {}); | ||
/** | ||
* @constant {number} RECURSIVE_COUNTER_CUTOFF | ||
* @constant {boolean} HAS_UINT16ARRAY_SUPPORT | ||
*/ | ||
export var RECURSIVE_COUNTER_CUTOFF = 512; | ||
export var HAS_UINT16ARRAY_SUPPORT = typeof Uint16Array === 'function'; | ||
/** | ||
* @constant {Array<string>} REPLACE_RECURSIVE_VALUE_CLASSES | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
export var REPLACE_RECURSIVE_VALUE_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT]; | ||
export var HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
/** | ||
* @constant {Array<string>} REPLACE_STRINGIFICATION_CLASSES | ||
* @constant {RegExp} SVG_ELEMENT_REGEXP | ||
*/ | ||
export var REPLACE_STRINGIFICATION_CLASSES = [OBJECT_CLASS_TYPE_MAP.DATE, OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET, OBJECT_CLASS_TYPE_MAP.REGEXP, OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.GENERATORFUNCTION, OBJECT_CLASS_TYPE_MAP.MATH, OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER, OBJECT_CLASS_TYPE_MAP.DATAVIEW, OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY, OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
export var SVG_ELEMENT_REGEXP = /\[object (SVG(.*)Element)\]/; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_CLASSES | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
*/ | ||
export var STRINGIFY_SELF_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT, OBJECT_CLASS_TYPE_MAP.ARGUMENTS]; | ||
export var OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'DocumentFragment', 'Error', 'Event', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet', 'Window']; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_CLASSES | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
*/ | ||
export var STRINGIFY_PREFIX_CLASSES = [OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.REGEXP]; | ||
export var OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_ITERABLE_CLASSES | ||
*/ | ||
export var STRINGIFY_ITERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET]; | ||
return objectClasses; | ||
}, {}); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_NOT_ENUMERABLE_CLASSES | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
*/ | ||
export var STRINGIFY_NOT_ENUMERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
export var OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_JOIN_CLASSES | ||
*/ | ||
export var STRINGIFY_PREFIX_JOIN_CLASSES = [OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY]; | ||
return objectClassTypes; | ||
}, {}); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_TYPES | ||
*/ | ||
export var STRINGIFY_SELF_TYPES = ['string', 'number']; | ||
export var ITERABLE_TAGS = { | ||
'[object Map]': true, | ||
'[object Set]': true | ||
}; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_TYPES | ||
*/ | ||
export var STRINGIFY_PREFIX_TYPES = ['boolean', 'undefined', 'function', 'symbol']; | ||
export var PRIMITIVE_TAGS = { | ||
boolean: true, | ||
function: true, | ||
number: true, | ||
string: true, | ||
undefined: true | ||
}; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TOSTRING_TYPES | ||
*/ | ||
export var STRINGIFY_TOSTRING_TYPES = ['symbol', 'function']; | ||
export var SELF_TAGS = (_SELF_TAGS = {}, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARGUMENTS] = true, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARRAY] = true, _SELF_TAGS); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TYPEOF_TYPES | ||
*/ | ||
export var STRINGIFY_TYPEOF_TYPES = [].concat(STRINGIFY_SELF_TYPES, STRINGIFY_PREFIX_TYPES); | ||
export var TOSTRING_TAGS = (_TOSTRING_TAGS = {}, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.REGEXP] = true, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.SYMBOL] = true, _TOSTRING_TAGS); | ||
/** | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
export var HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
export var TYPEDARRAY_TAGS = (_TYPEDARRAY_TAGS = {}, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT32ARRAY] = true, _TYPEDARRAY_TAGS); | ||
/** | ||
* @constant {Object} MATH_OBJECT | ||
*/ | ||
export var MATH_OBJECT = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT2'].reduce(function (mathObject, property) { | ||
var _extends2; | ||
return _extends({}, mathObject, (_extends2 = {}, _extends2[property] = Math[property], _extends2)); | ||
}, {}); | ||
export var UNPARSEABLE_TAGS = (_UNPARSEABLE_TAGS = {}, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.GENERATOR] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.PROMISE] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKMAP] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKSET] = true, _UNPARSEABLE_TAGS); |
117
es/index.js
@@ -1,42 +0,43 @@ | ||
var _EMPTY_HASHES; | ||
// external dependencies | ||
import { curry } from 'curriable'; | ||
import { getIntegerHashValue, getStringifiedValue } from './utils'; | ||
// utils | ||
import { getIntegerHashValue, stringify } from './utils'; | ||
/** | ||
* @function hashIt | ||
* @function hash | ||
* | ||
* @description | ||
* return the unique integer hash value for the object | ||
* hash the value passed to a unique, consistent hash value | ||
* | ||
* @param {*} object the object to hash | ||
* @param {boolean} [isCircular] is the object a circular object | ||
* @returns {number} | ||
* @param {any} value the value to hash | ||
* @returns {number} the object hash | ||
*/ | ||
var hashIt = function hashIt(object, isCircular) { | ||
var stringifiedValue = getStringifiedValue(object, isCircular); | ||
return getIntegerHashValue(stringifiedValue); | ||
export var hash = function hash(value) { | ||
return getIntegerHashValue(stringify(value)); | ||
}; | ||
var UNDEFINED_HASH = hashIt(undefined); | ||
var NULL_HASH = hashIt(null); | ||
var EMPTY_ARRAY_HASH = hashIt([]); | ||
var EMPTY_MAP_HASH = hashIt(new Map()); | ||
var EMPTY_NUMBER_HASH = hashIt(0); | ||
var EMPTY_OBJECT_HASH = hashIt({}); | ||
var EMPTY_SET_HASH = hashIt(new Set()); | ||
var EMPTY_STRING_HASH = hashIt(''); | ||
/** | ||
* @function hash.is | ||
* | ||
* @description | ||
* create a comparator for the first object passed to determine if the second is equal | ||
* | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
hash.is = curry(function (object, otherObject) { | ||
return hash(object) === hash(otherObject); | ||
}); | ||
var EMPTY_HASHES = (_EMPTY_HASHES = {}, _EMPTY_HASHES[EMPTY_ARRAY_HASH] = true, _EMPTY_HASHES[EMPTY_MAP_HASH] = true, _EMPTY_HASHES[EMPTY_NUMBER_HASH] = true, _EMPTY_HASHES[EMPTY_OBJECT_HASH] = true, _EMPTY_HASHES[EMPTY_SET_HASH] = true, _EMPTY_HASHES[EMPTY_STRING_HASH] = true, _EMPTY_HASHES[NULL_HASH] = true, _EMPTY_HASHES[UNDEFINED_HASH] = true, _EMPTY_HASHES); | ||
/** | ||
* @function hashIt.isEqual | ||
* @function hash.is.all | ||
* | ||
* @description | ||
* determine if all objects passed are equal in value to one another | ||
* determine if all of the objects passed are equal in value to the first | ||
* | ||
* @param {...Array<*>} objects the objects to test for equality | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hashIt.isEqual = function () { | ||
hash.is.all = curry(function () { | ||
for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) { | ||
@@ -46,10 +47,6 @@ objects[_key] = arguments[_key]; | ||
var length = objects.length; | ||
var isEqual = hash.is(objects.shift()); | ||
if (length === 1) { | ||
throw new Error('isEqual requires at least two objects to be passed for comparison.'); | ||
} | ||
for (var index = 1; index < length; index++) { | ||
if (hashIt(objects[index - 1]) !== hashIt(objects[index])) { | ||
for (var index = 0; index < objects.length; index++) { | ||
if (!isEqual(objects[index])) { | ||
return false; | ||
@@ -60,44 +57,42 @@ } | ||
return true; | ||
}; | ||
}, 2); | ||
/** | ||
* @function hashIt.isEmpty | ||
* @function hash.is.any | ||
* | ||
* @description | ||
* determine if object is empty, meaning it is an array / object / map / set with values populated, | ||
* or is a string with no length, or is undefined or null | ||
* determine if any of the objects passed are equal in value to the first | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object empty | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hashIt.isEmpty = function (object) { | ||
return !!EMPTY_HASHES[hashIt(object)]; | ||
}; | ||
hash.is.any = curry(function () { | ||
for (var _len2 = arguments.length, objects = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
objects[_key2] = arguments[_key2]; | ||
} | ||
/** | ||
* @function hashIt.isNull | ||
* | ||
* @description | ||
* determine if object is null | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object null | ||
*/ | ||
hashIt.isNull = function (object) { | ||
return hashIt(object) === NULL_HASH; | ||
}; | ||
var isEqual = hash.is(objects.shift()); | ||
for (var index = 0; index < objects.length; index++) { | ||
if (isEqual(objects[index])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}, 2); | ||
/** | ||
* @function hashIt.isUndefined | ||
* @function hash.is.not | ||
* | ||
* @description | ||
* determine if object is undefined | ||
* create a comparator for the first object passed to determine if the second is not equal | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object undefined | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
hashIt.isUndefined = function (object) { | ||
return hashIt(object) === UNDEFINED_HASH; | ||
}; | ||
hash.is.not = curry(function (object, otherObject) { | ||
return hash(object) !== hash(otherObject); | ||
}); | ||
export default hashIt; | ||
export default hash; |
508
es/utils.js
@@ -1,291 +0,447 @@ | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
// external dependencies | ||
import prune from 'json-prune'; | ||
import fastStringify from 'fast-stringify'; | ||
// constants | ||
import { HTML_ELEMENT_REGEXP, OBJECT_CLASS_MAP, OBJECT_CLASS_TYPE_MAP, MATH_OBJECT, RECURSIVE_COUNTER_CUTOFF, REPLACE_RECURSIVE_VALUE_CLASSES, REPLACE_STRINGIFICATION_CLASSES, STRINGIFY_ITERABLE_CLASSES, STRINGIFY_NOT_ENUMERABLE_CLASSES, STRINGIFY_PREFIX_JOIN_CLASSES, STRINGIFY_PREFIX_CLASSES, STRINGIFY_PREFIX_TYPES, STRINGIFY_SELF_CLASSES, STRINGIFY_SELF_TYPES, STRINGIFY_TOSTRING_TYPES, STRINGIFY_TYPEOF_TYPES } from './constants'; | ||
import { CIRCULAR_VALUE, HAS_BUFFER_FROM_SUPPORT, HAS_UINT16ARRAY_SUPPORT, HTML_ELEMENT_REGEXP, ITERABLE_TAGS, OBJECT_CLASS_MAP, OBJECT_CLASS_TYPE_MAP, PRIMITIVE_TAGS, SELF_TAGS, SVG_ELEMENT_REGEXP, TOSTRING_TAGS, TYPEDARRAY_TAGS, UNPARSEABLE_TAGS } from './constants'; | ||
var toString = Object.prototype.toString; | ||
var charCodeAt = String.prototype.charCodeAt; | ||
var keys = Object.keys; | ||
/** | ||
* @function getIterablePairs | ||
* @function getFunctionName | ||
* | ||
* @description | ||
* get the [key,value] pairs for maps and sets | ||
* get the name of the function based on a series of fallback attempts | ||
* | ||
* @param {Map|Set} iterable the iterable to map | ||
* @param {string} type the type of object class | ||
* @returns {Array<Array>} the [key, value] pairs | ||
* @param {function} fn the function to test | ||
* @returns {string} the function name | ||
*/ | ||
export var getIterablePairs = function getIterablePairs(iterable, type) { | ||
var pairs = [OBJECT_CLASS_MAP[type]]; | ||
export var getFunctionName = function getFunctionName(fn) { | ||
return fn.name || (fn.toString().match(/^\s*function\s*([^\(]*)/i) || [])[1] || 'anonymous'; | ||
}; | ||
iterable.forEach(function (item, key) { | ||
pairs.push([key, item]); | ||
}); | ||
/** | ||
* @function getCircularValue | ||
* | ||
* @description | ||
* get the value used when circular references are found | ||
* | ||
* @returns {string} the value for stringification | ||
*/ | ||
export var getCircularValue = function getCircularValue() { | ||
return CIRCULAR_VALUE; | ||
}; | ||
return pairs; | ||
/** | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2 | ||
* with enhancements for reduced collisions) | ||
* | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
export var getIntegerHashValue = function getIntegerHashValue(string) { | ||
var index = string.length, | ||
hashA = 5381, | ||
hashB = 52711, | ||
charCode = void 0; | ||
while (index--) { | ||
charCode = charCodeAt.call(string, index); | ||
hashA = hashA * 33 ^ charCode; | ||
hashB = hashB * 33 ^ charCode; | ||
} | ||
return (hashA >>> 0) * 4096 + (hashB >>> 0); | ||
}; | ||
/** | ||
* @function getStringFromArrayBuffer | ||
* @function getSortedEvent | ||
* | ||
* @description | ||
* get the string value of the buffer passed | ||
* get the event object sorted by its properties | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
* @param {boolean} bubbles does the event bubble up through the DOM | ||
* @param {function} alias to stopPropagation | ||
* @param {boolean} cancelable is the event cancelable | ||
* @param {boolean} composed can the event bubble across the boundary to shadow DOM | ||
* @param {HTMLElement} [currentTarget] registered target for the event | ||
* @param {boolean} defaultPrevented has preventDefault been called on the event | ||
* @param {string} eventPhase the phase of the event flow being processed | ||
* @param {boolean} isTrusted was the event initiated by the browser | ||
* @param {HTMLElement} [target] the target with which the event was dispatched | ||
* @param {number} timeStamp the time at which the event was created | ||
* @param {string} type the name of the event | ||
* @returns {Object} the event object with all properties sorted | ||
*/ | ||
export var getStringFromArrayBuffer = function getStringFromArrayBuffer(buffer) { | ||
return typeof Uint16Array === 'undefined' ? '' : String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
export var getSortedEvent = function getSortedEvent(_ref) { | ||
var bubbles = _ref.bubbles, | ||
cancelBubble = _ref.cancelBubble, | ||
cancelable = _ref.cancelable, | ||
composed = _ref.composed, | ||
currentTarget = _ref.currentTarget, | ||
defaultPrevented = _ref.defaultPrevented, | ||
eventPhase = _ref.eventPhase, | ||
isTrusted = _ref.isTrusted, | ||
returnValue = _ref.returnValue, | ||
target = _ref.target, | ||
type = _ref.type; | ||
return { | ||
bubbles: bubbles, | ||
cancelBubble: cancelBubble, | ||
cancelable: cancelable, | ||
composed: composed, | ||
currentTarget: currentTarget, | ||
defaultPrevented: defaultPrevented, | ||
eventPhase: eventPhase, | ||
isTrusted: isTrusted, | ||
returnValue: returnValue, | ||
target: target, | ||
type: type | ||
}; | ||
}; | ||
/** | ||
* @function getTypePrefixedString | ||
* @function shouldSort | ||
* | ||
* @description | ||
* prepend type to string value | ||
* get the sort result based on the two values to compare | ||
* | ||
* @param {string} string the string to prepend | ||
* @param {string} type the type to add as a prefix | ||
* @returns {string} the prefixed string | ||
* @param {string} valueA the first value to compare | ||
* @param {string} valueB the second value to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
export var getTypePrefixedString = function getTypePrefixedString(string, type) { | ||
return OBJECT_CLASS_MAP[type] + ' ' + string; | ||
export var shouldSort = function shouldSort(valueA, valueB) { | ||
return valueA > valueB; | ||
}; | ||
/** | ||
* @function getStringifiedElement | ||
* @function shouldSortPair | ||
* | ||
* @description | ||
* get the HTML element stringified by its type, attributes, and contents | ||
* get the sort result based on the two pairs to compare | ||
* | ||
* @param {HTMLElement} element the element to stringify | ||
* @returns {string} the stringified elements | ||
* @param {Object} pairA the first pair to compare | ||
* @param {Object} pairB the second pair to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
export var getStringifiedElement = function getStringifiedElement(element) { | ||
var attributes = element.attributes; | ||
export var shouldSortPair = function shouldSortPair(pairA, pairB) { | ||
return shouldSort(pairA[0], pairB[0]); | ||
}; | ||
var attributesString = ''; | ||
/** | ||
* @function getPrefixedValue | ||
* | ||
* @description | ||
* get the value prefixed by the tag | ||
* | ||
* @param {string} tag the object tag | ||
* @param {any} value the value to stringify | ||
* @returns {string} the prefixed stringified value | ||
*/ | ||
export var getPrefixedValue = function getPrefixedValue(tag, value) { | ||
return tag + '|' + value; | ||
}; | ||
for (var index = 0; index < attributes.length; index++) { | ||
attributesString += attributes[index].name + '="' + attributes[index].value + '",'; | ||
/** | ||
* @function sort | ||
* | ||
* @description | ||
* sort the array based on the fn passed | ||
* | ||
* @param {Array<any>} array the array to sort | ||
* @param {function} fn the sorting function | ||
* @returns {Array<any>} the sorted array | ||
*/ | ||
export var sort = function sort(array, fn) { | ||
var subIndex = void 0, | ||
value = void 0; | ||
for (var index = 0; index < array.length; index++) { | ||
value = array[index]; | ||
for (subIndex = index - 1; ~subIndex && fn(array[subIndex], value); subIndex--) { | ||
array[subIndex + 1] = array[subIndex]; | ||
} | ||
array[subIndex + 1] = value; | ||
} | ||
return element.tagName + ' ' + attributesString + ' ' + element.innerHTML; | ||
return array; | ||
}; | ||
/** | ||
* @function getStringifiedValueByObjectClass | ||
* @function getIterablePairs | ||
* | ||
* @description | ||
* get the stringified value of the object based based on its toString class | ||
* get the pairs in the iterable for stringification | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @param {string} [passedObjectClass] the object class for the object passed | ||
* @returns {*} the value to stringify with | ||
* @param {Map|Set} iterable the iterable to get the pairs for | ||
* @returns {Array<{key: string, value: any}>} the pairs | ||
*/ | ||
export var getStringifiedValueByObjectClass = function getStringifiedValueByObjectClass(object, passedObjectClass) { | ||
var objectClass = passedObjectClass || toString.call(object); | ||
export var getSortedIterablePairs = function getSortedIterablePairs(iterable) { | ||
var isMap = typeof iterable.get === 'function'; | ||
var pairs = []; | ||
if (~STRINGIFY_SELF_CLASSES.indexOf(objectClass)) { | ||
return object; | ||
} | ||
iterable.forEach(function (value, key) { | ||
// eslint-disable-next-line no-use-before-define | ||
pairs.push(isMap ? [stringify(key), stringify(value)] : [stringify(value)]); | ||
}); | ||
if (~STRINGIFY_PREFIX_CLASSES.indexOf(objectClass) || object === null) { | ||
return getTypePrefixedString(object, objectClass); | ||
} | ||
sort(pairs, shouldSortPair); | ||
if (objectClass === OBJECT_CLASS_TYPE_MAP.DATE) { | ||
return getTypePrefixedString(object.valueOf(), objectClass); | ||
} | ||
var finalPairs = new Array(iterable.size); | ||
if (~STRINGIFY_ITERABLE_CLASSES.indexOf(objectClass)) { | ||
return getIterablePairs(object, objectClass); | ||
} | ||
var pair = void 0; | ||
if (~STRINGIFY_NOT_ENUMERABLE_CLASSES.indexOf(objectClass)) { | ||
return getTypePrefixedString('NOT_ENUMERABLE', objectClass); | ||
} | ||
for (var index = 0; index < iterable.size; index++) { | ||
pair = pairs[index]; | ||
if (objectClass === OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object), objectClass); | ||
finalPairs[index] = isMap ? '[' + pair[0] + ',' + pair[1] + ']' : pair[0]; | ||
} | ||
if (objectClass === OBJECT_CLASS_TYPE_MAP.DATAVIEW) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object.buffer), objectClass); | ||
} | ||
return getPrefixedValue(getFunctionName(iterable.constructor), '[' + finalPairs.join(',') + ']'); | ||
}; | ||
if (~STRINGIFY_PREFIX_JOIN_CLASSES.indexOf(objectClass)) { | ||
return getTypePrefixedString(object.join(','), objectClass); | ||
} | ||
/** | ||
* @function getSortedObject | ||
* | ||
* @description | ||
* get the object with the keys sorted | ||
* | ||
* @param {Object} object the object to sort | ||
* @returns {Object} the sorted object | ||
*/ | ||
export var getSortedObject = function getSortedObject(object) { | ||
var objectKeys = sort(keys(object), shouldSort); | ||
var newObject = {}; | ||
if (objectClass === OBJECT_CLASS_TYPE_MAP.MATH) { | ||
return MATH_OBJECT; | ||
var key = void 0; | ||
for (var index = 0; index < objectKeys.length; index++) { | ||
key = objectKeys[index]; | ||
newObject[key] = object[key]; | ||
} | ||
return HTML_ELEMENT_REGEXP.test(objectClass) ? getTypePrefixedString(getStringifiedElement(object), OBJECT_CLASS_TYPE_MAP.HTMLELEMENT) : object; | ||
return newObject; | ||
}; | ||
/** | ||
* @function getValueForStringification | ||
* @function getStringifiedArrayBufferFallback | ||
* | ||
* @description | ||
* get the string value for the object used for stringification | ||
* get the string value of the buffer passed based on a Buffer | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @returns {*} the value to stringify with | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
export var getValueForStringification = function getValueForStringification(object) { | ||
var type = typeof object === 'undefined' ? 'undefined' : _typeof(object); | ||
export var getStringifiedArrayBufferFallback = function getStringifiedArrayBufferFallback(buffer) { | ||
return String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
}; | ||
if (~STRINGIFY_SELF_TYPES.indexOf(type)) { | ||
return object; | ||
} | ||
/** | ||
* @function getStringifiedArrayBufferModern | ||
* | ||
* @description | ||
* get the string value of the buffer passed based on a Uint16Array | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
export var getStringifiedArrayBufferModern = function getStringifiedArrayBufferModern(buffer) { | ||
return Buffer.from(buffer).toString('utf8'); | ||
}; | ||
if (~STRINGIFY_PREFIX_TYPES.indexOf(type)) { | ||
return getTypePrefixedString(~STRINGIFY_TOSTRING_TYPES.indexOf(type) ? object.constructor.prototype.toString.call(object) : object, toString.call(object)); | ||
} | ||
return getStringifiedValueByObjectClass(object); | ||
/** | ||
* @function getStringifiedArrayBufferNoSupport | ||
* | ||
* @description | ||
* return a placeholder when no arraybuffer support exists | ||
* | ||
* @returns {string} the placeholder | ||
*/ | ||
export var getStringifiedArrayBufferNoSupport = function getStringifiedArrayBufferNoSupport() { | ||
return ''; | ||
}; | ||
/** | ||
* @function getCircularStackValue | ||
* @function getStringifiedArrayBuffer | ||
* | ||
* @description | ||
* get the value either from the recursive storage stack | ||
* or itself after being added to that stack | ||
* get the string value of the buffer passed | ||
* | ||
* @param {*} value the value to check for existing | ||
* @param {string} type the type of the value | ||
* @param {Array<*>} stack the current stack of values | ||
* @param {number} circularCounter the counter of circular references | ||
* @returns {*} the value to apply | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
export var getCircularStackValue = function getCircularStackValue(value, type, stack, circularCounter) { | ||
if (!value) { | ||
return getTypePrefixedString(value, type); | ||
} | ||
export var getStringifiedArrayBuffer = function () { | ||
return HAS_BUFFER_FROM_SUPPORT ? getStringifiedArrayBufferModern : HAS_UINT16ARRAY_SUPPORT ? getStringifiedArrayBufferFallback : getStringifiedArrayBufferNoSupport; | ||
}(); | ||
if (circularCounter > RECURSIVE_COUNTER_CUTOFF) { | ||
stack.length = 0; | ||
/** | ||
* @function getStringifiedDocumentFragment | ||
* | ||
* @description | ||
* build a string based on all the fragment's children | ||
* | ||
* @param {DocumentFragment} fragment the fragment to stringify | ||
* @returns {string} the stringified fragment | ||
*/ | ||
export var getStringifiedDocumentFragment = function getStringifiedDocumentFragment(fragment) { | ||
var children = fragment.children; | ||
return value; | ||
var innerHTML = ''; | ||
for (var index = 0; index < children.length; index++) { | ||
// eslint-disable-next-line no-use-before-define | ||
innerHTML += children[index].outerHTML; | ||
} | ||
var existingIndex = stack.indexOf(value); | ||
return innerHTML; | ||
}; | ||
if (!~existingIndex) { | ||
stack.push(value); | ||
return value; | ||
/** | ||
* @function indexOf | ||
* | ||
* @description | ||
* get the index of the value in the array (faster than native indexOf) | ||
* | ||
* @param {Array<any>} array the array to get the index of the value at | ||
* @param {any} value the value to match | ||
* @returns {number} the index of the value in array | ||
*/ | ||
export var indexOf = function indexOf(array, value) { | ||
for (var index = 0; index < array.length; index++) { | ||
if (array[index] === value) { | ||
return index; | ||
} | ||
} | ||
return '*Circular-' + existingIndex; | ||
return -1; | ||
}; | ||
/** | ||
* @function createReplacer | ||
* @function getNormalizedValue | ||
* | ||
* @description | ||
* create the replacer function leveraging closure for recursive stack storage | ||
* get the value normalized for stringification | ||
* | ||
* @param {Array<*>} stack the stack to store in memory | ||
* @returns {function} the replacer to use | ||
* @param {any} value the value to normalize | ||
* @param {WeakMap|Object} sortedCache the cache of sorted objects | ||
* @returns {any} the normalized value | ||
*/ | ||
export var createReplacer = function createReplacer(stack) { | ||
var circularCounter = 1, | ||
objectClass = void 0; | ||
export var getNormalizedValue = function getNormalizedValue(value, sortedCache) { | ||
var type = typeof value; | ||
return function (key, value) { | ||
if (!key) { | ||
stack = [value]; | ||
if (type === 'string') { | ||
return value; | ||
} | ||
return value; | ||
} | ||
if (PRIMITIVE_TAGS[type]) { | ||
return getPrefixedValue(type, value); | ||
} | ||
if (value === null) { | ||
return getStringifiedValueByObjectClass(value, OBJECT_CLASS_TYPE_MAP.NULL); | ||
} | ||
if (value === null) { | ||
return getPrefixedValue('null', value); | ||
} | ||
if (~STRINGIFY_TYPEOF_TYPES.indexOf(typeof value === 'undefined' ? 'undefined' : _typeof(value))) { | ||
return getValueForStringification(value); | ||
} | ||
var tag = toString.call(value); | ||
objectClass = toString.call(value); | ||
if (SELF_TAGS[tag]) { | ||
return value; | ||
} | ||
if (~REPLACE_RECURSIVE_VALUE_CLASSES.indexOf(objectClass)) { | ||
return getCircularStackValue(value, objectClass, stack, ++circularCounter); | ||
if (tag === OBJECT_CLASS_TYPE_MAP.OBJECT) { | ||
if (~indexOf(sortedCache, value)) { | ||
return CIRCULAR_VALUE; | ||
} | ||
if (~REPLACE_STRINGIFICATION_CLASSES.indexOf(objectClass)) { | ||
return getStringifiedValueByObjectClass(value, objectClass); | ||
sortedCache.push(value); | ||
return getSortedObject(value, sortedCache); | ||
} | ||
if (TOSTRING_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.toString()); | ||
} | ||
if (ITERABLE_TAGS[tag]) { | ||
if (~indexOf(sortedCache, value)) { | ||
return CIRCULAR_VALUE; | ||
} | ||
return value; | ||
}; | ||
}; | ||
sortedCache.push(value); | ||
/** | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2) | ||
* | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
export var getIntegerHashValue = function getIntegerHashValue(string) { | ||
if (!string) { | ||
return 0; | ||
return getSortedIterablePairs(value); | ||
} | ||
var hashValue = 5381; | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DATE) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.getTime()); | ||
} | ||
for (var index = 0; index < string.length; index++) { | ||
hashValue = (hashValue << 5) + hashValue + string.charCodeAt(index); | ||
if (tag === OBJECT_CLASS_TYPE_MAP.ERROR) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.stack); | ||
} | ||
return hashValue >>> 0; | ||
if (tag === OBJECT_CLASS_TYPE_MAP.EVENT) { | ||
return getSortedEvent(value); | ||
} | ||
if (UNPARSEABLE_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], 'NOT_ENUMERABLE'); | ||
} | ||
if (HTML_ELEMENT_REGEXP.test(tag) || SVG_ELEMENT_REGEXP.test(tag)) { | ||
return getPrefixedValue(tag.slice(8, -1), value.outerHTML); | ||
} | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DOCUMENTFRAGMENT) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedDocumentFragment(value)); | ||
} | ||
if (TYPEDARRAY_TAGS[tag]) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], value.join(',')); | ||
} | ||
if (tag === OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value)); | ||
} | ||
if (tag === OBJECT_CLASS_TYPE_MAP.DATAVIEW) { | ||
return getPrefixedValue(OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value.buffer)); | ||
} | ||
return value; | ||
}; | ||
/** | ||
* @function tryCatch | ||
* @function replacer | ||
* | ||
* @description | ||
* move try/catch to standalone function as any function that contains a try/catch | ||
* is not optimized (this allows optimization for as much as possible) | ||
* create the replacer function used for stringification | ||
* | ||
* @param {*} value the value to stringify | ||
* @returns {string} the stringified value | ||
* @param {WeakSet|Object} sortedCache the cache to use for sorting objects | ||
* @returns {function(key: string, value: any)} function getting the normalized value | ||
*/ | ||
export var tryCatch = function tryCatch(value) { | ||
try { | ||
return JSON.stringify(value, createReplacer([])); | ||
} catch (exception) { | ||
return prune(value); | ||
} | ||
export var createReplacer = function createReplacer(sortedCache) { | ||
return function (key, value) { | ||
return getNormalizedValue(value, sortedCache); | ||
}; | ||
}; | ||
/** | ||
* @function getStringifiedValue | ||
* @function stringify | ||
* | ||
* @description | ||
* stringify the object passed leveraging JSON.stringify | ||
* with REPLACER, falling back to prune | ||
* stringify the value based on the options passed | ||
* | ||
* @param {*} object the object to stringify | ||
* @param {boolean} isCircular is the object circular or not | ||
* @returns {string} the stringified object | ||
* @param {any} value the value to stringify | ||
* @returns {string} the stringified value | ||
*/ | ||
export var getStringifiedValue = function getStringifiedValue(object, isCircular) { | ||
var valueForStringification = getValueForStringification(object); | ||
if (typeof valueForStringification === 'string') { | ||
return valueForStringification; | ||
} | ||
return isCircular ? tryCatch(getValueForStringification(object)) : JSON.stringify(valueForStringification, createReplacer([])); | ||
}; | ||
export function stringify(value) { | ||
return typeof value === 'object' && value && !(value instanceof RegExp || value instanceof Date) ? fastStringify(value, createReplacer([]), null, getCircularValue) : getNormalizedValue(value); | ||
} |
@@ -5,99 +5,76 @@ 'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _SELF_TAGS, _TOSTRING_TAGS, _TYPEDARRAY_TAGS, _UNPARSEABLE_TAGS; | ||
/** | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
* @constant {string} CIRCULAR_VALUE | ||
*/ | ||
var OBJECT_CLASSES = exports.OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet']; | ||
var CIRCULAR_VALUE = exports.CIRCULAR_VALUE = '~'; | ||
/** | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
* @constant {Array<any>} EMPTY_VALUES | ||
*/ | ||
var OBJECT_CLASS_MAP = exports.OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
var EMPTY_VALUES = exports.EMPTY_VALUES = [void 0, null, '', [], {}].concat(typeof Map === 'function' ? [new Map()] : []).concat(typeof Set === 'function' ? [new Set()] : []); | ||
return objectClasses; | ||
}, {}); | ||
/** | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
* @constant {boolean} HAS_BUFFER_FROM_SUPPORT | ||
*/ | ||
var OBJECT_CLASS_TYPE_MAP = exports.OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
var HAS_BUFFER_FROM_SUPPORT = exports.HAS_BUFFER_FROM_SUPPORT = typeof Buffer !== 'undefined' && typeof Buffer.from === 'function'; | ||
return objectClassTypes; | ||
}, {}); | ||
/** | ||
* @constant {number} RECURSIVE_COUNTER_CUTOFF | ||
* @constant {boolean} HAS_UINT16ARRAY_SUPPORT | ||
*/ | ||
var RECURSIVE_COUNTER_CUTOFF = exports.RECURSIVE_COUNTER_CUTOFF = 512; | ||
var HAS_UINT16ARRAY_SUPPORT = exports.HAS_UINT16ARRAY_SUPPORT = typeof Uint16Array === 'function'; | ||
/** | ||
* @constant {Array<string>} REPLACE_RECURSIVE_VALUE_CLASSES | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
var REPLACE_RECURSIVE_VALUE_CLASSES = exports.REPLACE_RECURSIVE_VALUE_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT]; | ||
var HTML_ELEMENT_REGEXP = exports.HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
/** | ||
* @constant {Array<string>} REPLACE_STRINGIFICATION_CLASSES | ||
* @constant {RegExp} SVG_ELEMENT_REGEXP | ||
*/ | ||
var REPLACE_STRINGIFICATION_CLASSES = exports.REPLACE_STRINGIFICATION_CLASSES = [OBJECT_CLASS_TYPE_MAP.DATE, OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET, OBJECT_CLASS_TYPE_MAP.REGEXP, OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.GENERATORFUNCTION, OBJECT_CLASS_TYPE_MAP.MATH, OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER, OBJECT_CLASS_TYPE_MAP.DATAVIEW, OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY, OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
var SVG_ELEMENT_REGEXP = exports.SVG_ELEMENT_REGEXP = /\[object (SVG(.*)Element)\]/; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_CLASSES | ||
* @constant {Array<string>} OBJECT_CLASSES | ||
*/ | ||
var STRINGIFY_SELF_CLASSES = exports.STRINGIFY_SELF_CLASSES = [OBJECT_CLASS_TYPE_MAP.ARRAY, OBJECT_CLASS_TYPE_MAP.OBJECT, OBJECT_CLASS_TYPE_MAP.ARGUMENTS]; | ||
var OBJECT_CLASSES = exports.OBJECT_CLASSES = ['Arguments', 'Array', 'ArrayBuffer', 'Boolean', 'DataView', 'Date', 'DocumentFragment', 'Error', 'Event', 'Float32Array', 'Float64Array', 'Function', 'Generator', 'GeneratorFunction', 'HTMLElement', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Null', 'Number', 'Object', 'Promise', 'RegExp', 'Set', 'String', 'Symbol', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'Undefined', 'WeakMap', 'WeakSet', 'Window']; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_CLASSES | ||
* @constant {Object} OBJECT_CLASS_MAP | ||
*/ | ||
var STRINGIFY_PREFIX_CLASSES = exports.STRINGIFY_PREFIX_CLASSES = [OBJECT_CLASS_TYPE_MAP.ERROR, OBJECT_CLASS_TYPE_MAP.REGEXP]; | ||
var OBJECT_CLASS_MAP = exports.OBJECT_CLASS_MAP = OBJECT_CLASSES.reduce(function (objectClasses, type) { | ||
objectClasses['[object ' + type + ']'] = type; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_ITERABLE_CLASSES | ||
*/ | ||
var STRINGIFY_ITERABLE_CLASSES = exports.STRINGIFY_ITERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.MAP, OBJECT_CLASS_TYPE_MAP.SET]; | ||
return objectClasses; | ||
}, {}); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_NOT_ENUMERABLE_CLASSES | ||
* @constant {Object} OBJECT_CLASS_TYPE_MAP | ||
*/ | ||
var STRINGIFY_NOT_ENUMERABLE_CLASSES = exports.STRINGIFY_NOT_ENUMERABLE_CLASSES = [OBJECT_CLASS_TYPE_MAP.PROMISE, OBJECT_CLASS_TYPE_MAP.GENERATOR, OBJECT_CLASS_TYPE_MAP.WEAKMAP, OBJECT_CLASS_TYPE_MAP.WEAKSET]; | ||
var OBJECT_CLASS_TYPE_MAP = exports.OBJECT_CLASS_TYPE_MAP = Object.keys(OBJECT_CLASS_MAP).reduce(function (objectClassTypes, objectClass) { | ||
objectClassTypes[OBJECT_CLASS_MAP[objectClass].toUpperCase()] = objectClass; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_JOIN_CLASSES | ||
*/ | ||
var STRINGIFY_PREFIX_JOIN_CLASSES = exports.STRINGIFY_PREFIX_JOIN_CLASSES = [OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY, OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY, OBJECT_CLASS_TYPE_MAP.INT8ARRAY, OBJECT_CLASS_TYPE_MAP.INT16ARRAY, OBJECT_CLASS_TYPE_MAP.INT32ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8ARRAY, OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY, OBJECT_CLASS_TYPE_MAP.UINT16ARRAY, OBJECT_CLASS_TYPE_MAP.UINT32ARRAY]; | ||
return objectClassTypes; | ||
}, {}); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_SELF_TYPES | ||
*/ | ||
var STRINGIFY_SELF_TYPES = exports.STRINGIFY_SELF_TYPES = ['string', 'number']; | ||
var ITERABLE_TAGS = exports.ITERABLE_TAGS = { | ||
'[object Map]': true, | ||
'[object Set]': true | ||
}; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_PREFIX_TYPES | ||
*/ | ||
var STRINGIFY_PREFIX_TYPES = exports.STRINGIFY_PREFIX_TYPES = ['boolean', 'undefined', 'function', 'symbol']; | ||
var PRIMITIVE_TAGS = exports.PRIMITIVE_TAGS = { | ||
boolean: true, | ||
function: true, | ||
number: true, | ||
string: true, | ||
undefined: true | ||
}; | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TOSTRING_TYPES | ||
*/ | ||
var STRINGIFY_TOSTRING_TYPES = exports.STRINGIFY_TOSTRING_TYPES = ['symbol', 'function']; | ||
var SELF_TAGS = exports.SELF_TAGS = (_SELF_TAGS = {}, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARGUMENTS] = true, _SELF_TAGS[OBJECT_CLASS_TYPE_MAP.ARRAY] = true, _SELF_TAGS); | ||
/** | ||
* @constant {Array<string>} STRINGIFY_TYPEOF_TYPES | ||
*/ | ||
var STRINGIFY_TYPEOF_TYPES = exports.STRINGIFY_TYPEOF_TYPES = [].concat(STRINGIFY_SELF_TYPES, STRINGIFY_PREFIX_TYPES); | ||
var TOSTRING_TAGS = exports.TOSTRING_TAGS = (_TOSTRING_TAGS = {}, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.REGEXP] = true, _TOSTRING_TAGS[OBJECT_CLASS_TYPE_MAP.SYMBOL] = true, _TOSTRING_TAGS); | ||
/** | ||
* @constant {RegExp} HTML_ELEMENT_REGEXP | ||
*/ | ||
var HTML_ELEMENT_REGEXP = exports.HTML_ELEMENT_REGEXP = /\[object (HTML(.*)Element)\]/; | ||
var TYPEDARRAY_TAGS = exports.TYPEDARRAY_TAGS = (_TYPEDARRAY_TAGS = {}, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.FLOAT64ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.INT32ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT8CLAMPEDARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT16ARRAY] = true, _TYPEDARRAY_TAGS[OBJECT_CLASS_TYPE_MAP.UINT32ARRAY] = true, _TYPEDARRAY_TAGS); | ||
/** | ||
* @constant {Object} MATH_OBJECT | ||
*/ | ||
var MATH_OBJECT = exports.MATH_OBJECT = ['E', 'LN2', 'LN10', 'LOG2E', 'LOG10E', 'PI', 'SQRT1_2', 'SQRT2'].reduce(function (mathObject, property) { | ||
var _extends2; | ||
return _extends({}, mathObject, (_extends2 = {}, _extends2[property] = Math[property], _extends2)); | ||
}, {}); | ||
var UNPARSEABLE_TAGS = exports.UNPARSEABLE_TAGS = (_UNPARSEABLE_TAGS = {}, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.GENERATOR] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.PROMISE] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKMAP] = true, _UNPARSEABLE_TAGS[OBJECT_CLASS_TYPE_MAP.WEAKSET] = true, _UNPARSEABLE_TAGS); |
116
lib/index.js
'use strict'; | ||
exports.__esModule = true; | ||
exports.hash = undefined; | ||
var _EMPTY_HASHES; | ||
var _curriable = require('curriable'); | ||
@@ -10,38 +11,41 @@ var _utils = require('./utils'); | ||
/** | ||
* @function hashIt | ||
* @function hash | ||
* | ||
* @description | ||
* return the unique integer hash value for the object | ||
* hash the value passed to a unique, consistent hash value | ||
* | ||
* @param {*} object the object to hash | ||
* @param {boolean} [isCircular] is the object a circular object | ||
* @returns {number} | ||
* @param {any} value the value to hash | ||
* @returns {number} the object hash | ||
*/ | ||
var hashIt = function hashIt(object, isCircular) { | ||
var stringifiedValue = (0, _utils.getStringifiedValue)(object, isCircular); | ||
return (0, _utils.getIntegerHashValue)(stringifiedValue); | ||
// external dependencies | ||
var hash = exports.hash = function hash(value) { | ||
return (0, _utils.getIntegerHashValue)((0, _utils.stringify)(value)); | ||
}; | ||
var UNDEFINED_HASH = hashIt(undefined); | ||
var NULL_HASH = hashIt(null); | ||
var EMPTY_ARRAY_HASH = hashIt([]); | ||
var EMPTY_MAP_HASH = hashIt(new Map()); | ||
var EMPTY_NUMBER_HASH = hashIt(0); | ||
var EMPTY_OBJECT_HASH = hashIt({}); | ||
var EMPTY_SET_HASH = hashIt(new Set()); | ||
var EMPTY_STRING_HASH = hashIt(''); | ||
/** | ||
* @function hash.is | ||
* | ||
* @description | ||
* create a comparator for the first object passed to determine if the second is equal | ||
* | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
var EMPTY_HASHES = (_EMPTY_HASHES = {}, _EMPTY_HASHES[EMPTY_ARRAY_HASH] = true, _EMPTY_HASHES[EMPTY_MAP_HASH] = true, _EMPTY_HASHES[EMPTY_NUMBER_HASH] = true, _EMPTY_HASHES[EMPTY_OBJECT_HASH] = true, _EMPTY_HASHES[EMPTY_SET_HASH] = true, _EMPTY_HASHES[EMPTY_STRING_HASH] = true, _EMPTY_HASHES[NULL_HASH] = true, _EMPTY_HASHES[UNDEFINED_HASH] = true, _EMPTY_HASHES); | ||
// utils | ||
hash.is = (0, _curriable.curry)(function (object, otherObject) { | ||
return hash(object) === hash(otherObject); | ||
}); | ||
/** | ||
* @function hashIt.isEqual | ||
* @function hash.is.all | ||
* | ||
* @description | ||
* determine if all objects passed are equal in value to one another | ||
* determine if all of the objects passed are equal in value to the first | ||
* | ||
* @param {...Array<*>} objects the objects to test for equality | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hashIt.isEqual = function () { | ||
hash.is.all = (0, _curriable.curry)(function () { | ||
for (var _len = arguments.length, objects = Array(_len), _key = 0; _key < _len; _key++) { | ||
@@ -51,10 +55,6 @@ objects[_key] = arguments[_key]; | ||
var length = objects.length; | ||
var isEqual = hash.is(objects.shift()); | ||
if (length === 1) { | ||
throw new Error('isEqual requires at least two objects to be passed for comparison.'); | ||
} | ||
for (var index = 1; index < length; index++) { | ||
if (hashIt(objects[index - 1]) !== hashIt(objects[index])) { | ||
for (var index = 0; index < objects.length; index++) { | ||
if (!isEqual(objects[index])) { | ||
return false; | ||
@@ -65,44 +65,42 @@ } | ||
return true; | ||
}; | ||
}, 2); | ||
/** | ||
* @function hashIt.isEmpty | ||
* @function hash.is.any | ||
* | ||
* @description | ||
* determine if object is empty, meaning it is an array / object / map / set with values populated, | ||
* or is a string with no length, or is undefined or null | ||
* determine if any of the objects passed are equal in value to the first | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object empty | ||
* @param {...Array<any>} objects the objects to test for equality | ||
* @returns {boolean} are the objects equal | ||
*/ | ||
hashIt.isEmpty = function (object) { | ||
return !!EMPTY_HASHES[hashIt(object)]; | ||
}; | ||
hash.is.any = (0, _curriable.curry)(function () { | ||
for (var _len2 = arguments.length, objects = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
objects[_key2] = arguments[_key2]; | ||
} | ||
/** | ||
* @function hashIt.isNull | ||
* | ||
* @description | ||
* determine if object is null | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object null | ||
*/ | ||
hashIt.isNull = function (object) { | ||
return hashIt(object) === NULL_HASH; | ||
}; | ||
var isEqual = hash.is(objects.shift()); | ||
for (var index = 0; index < objects.length; index++) { | ||
if (isEqual(objects[index])) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}, 2); | ||
/** | ||
* @function hashIt.isUndefined | ||
* @function hash.is.not | ||
* | ||
* @description | ||
* determine if object is undefined | ||
* create a comparator for the first object passed to determine if the second is not equal | ||
* | ||
* @param {*} object the object to test | ||
* @returns {boolean} is the object undefined | ||
* @param {any} object the object to test against | ||
* @returns {function(any): boolean} the method to test against the object | ||
*/ | ||
hashIt.isUndefined = function (object) { | ||
return hashIt(object) === UNDEFINED_HASH; | ||
}; | ||
hash.is.not = (0, _curriable.curry)(function (object, otherObject) { | ||
return hash(object) !== hash(otherObject); | ||
}); | ||
exports.default = hashIt; | ||
exports.default = hash; |
515
lib/utils.js
'use strict'; | ||
exports.__esModule = true; | ||
exports.getStringifiedValue = exports.tryCatch = exports.getIntegerHashValue = exports.createReplacer = exports.getCircularStackValue = exports.getValueForStringification = exports.getStringifiedValueByObjectClass = exports.getStringifiedElement = exports.getTypePrefixedString = exports.getStringFromArrayBuffer = exports.getIterablePairs = undefined; | ||
exports.createReplacer = exports.getNormalizedValue = exports.indexOf = exports.getStringifiedDocumentFragment = exports.getStringifiedArrayBuffer = exports.getStringifiedArrayBufferNoSupport = exports.getStringifiedArrayBufferModern = exports.getStringifiedArrayBufferFallback = exports.getSortedObject = exports.getSortedIterablePairs = exports.sort = exports.getPrefixedValue = exports.shouldSortPair = exports.shouldSort = exports.getSortedEvent = exports.getIntegerHashValue = exports.getCircularValue = exports.getFunctionName = undefined; | ||
exports.stringify = stringify; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // external dependencies | ||
var _fastStringify = require('fast-stringify'); | ||
var _fastStringify2 = _interopRequireDefault(_fastStringify); | ||
// constants | ||
var _constants = require('./constants'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _jsonPrune = require('json-prune'); | ||
// external dependencies | ||
var charCodeAt = String.prototype.charCodeAt; | ||
var _jsonPrune2 = _interopRequireDefault(_jsonPrune); | ||
// constants | ||
var _constants = require('./constants'); | ||
var keys = Object.keys; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* @function getFunctionName | ||
* | ||
* @description | ||
* get the name of the function based on a series of fallback attempts | ||
* | ||
* @param {function} fn the function to test | ||
* @returns {string} the function name | ||
*/ | ||
var getFunctionName = exports.getFunctionName = function getFunctionName(fn) { | ||
return fn.name || (fn.toString().match(/^\s*function\s*([^\(]*)/i) || [])[1] || 'anonymous'; | ||
}; | ||
var toString = Object.prototype.toString; | ||
/** | ||
* @function getCircularValue | ||
* | ||
* @description | ||
* get the value used when circular references are found | ||
* | ||
* @returns {string} the value for stringification | ||
*/ | ||
var getCircularValue = exports.getCircularValue = function getCircularValue() { | ||
return _constants.CIRCULAR_VALUE; | ||
}; | ||
/** | ||
* @function getIterablePairs | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* get the [key,value] pairs for maps and sets | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2 | ||
* with enhancements for reduced collisions) | ||
* | ||
* @param {Map|Set} iterable the iterable to map | ||
* @param {string} type the type of object class | ||
* @returns {Array<Array>} the [key, value] pairs | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
var getIterablePairs = exports.getIterablePairs = function getIterablePairs(iterable, type) { | ||
var pairs = [_constants.OBJECT_CLASS_MAP[type]]; | ||
var getIntegerHashValue = exports.getIntegerHashValue = function getIntegerHashValue(string) { | ||
var index = string.length, | ||
hashA = 5381, | ||
hashB = 52711, | ||
charCode = void 0; | ||
iterable.forEach(function (item, key) { | ||
pairs.push([key, item]); | ||
}); | ||
while (index--) { | ||
charCode = charCodeAt.call(string, index); | ||
return pairs; | ||
hashA = hashA * 33 ^ charCode; | ||
hashB = hashB * 33 ^ charCode; | ||
} | ||
return (hashA >>> 0) * 4096 + (hashB >>> 0); | ||
}; | ||
/** | ||
* @function getStringFromArrayBuffer | ||
* @function getSortedEvent | ||
* | ||
* @description | ||
* get the string value of the buffer passed | ||
* get the event object sorted by its properties | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
* @param {boolean} bubbles does the event bubble up through the DOM | ||
* @param {function} alias to stopPropagation | ||
* @param {boolean} cancelable is the event cancelable | ||
* @param {boolean} composed can the event bubble across the boundary to shadow DOM | ||
* @param {HTMLElement} [currentTarget] registered target for the event | ||
* @param {boolean} defaultPrevented has preventDefault been called on the event | ||
* @param {string} eventPhase the phase of the event flow being processed | ||
* @param {boolean} isTrusted was the event initiated by the browser | ||
* @param {HTMLElement} [target] the target with which the event was dispatched | ||
* @param {number} timeStamp the time at which the event was created | ||
* @param {string} type the name of the event | ||
* @returns {Object} the event object with all properties sorted | ||
*/ | ||
var getStringFromArrayBuffer = exports.getStringFromArrayBuffer = function getStringFromArrayBuffer(buffer) { | ||
return typeof Uint16Array === 'undefined' ? '' : String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
var getSortedEvent = exports.getSortedEvent = function getSortedEvent(_ref) { | ||
var bubbles = _ref.bubbles, | ||
cancelBubble = _ref.cancelBubble, | ||
cancelable = _ref.cancelable, | ||
composed = _ref.composed, | ||
currentTarget = _ref.currentTarget, | ||
defaultPrevented = _ref.defaultPrevented, | ||
eventPhase = _ref.eventPhase, | ||
isTrusted = _ref.isTrusted, | ||
returnValue = _ref.returnValue, | ||
target = _ref.target, | ||
type = _ref.type; | ||
return { | ||
bubbles: bubbles, | ||
cancelBubble: cancelBubble, | ||
cancelable: cancelable, | ||
composed: composed, | ||
currentTarget: currentTarget, | ||
defaultPrevented: defaultPrevented, | ||
eventPhase: eventPhase, | ||
isTrusted: isTrusted, | ||
returnValue: returnValue, | ||
target: target, | ||
type: type | ||
}; | ||
}; | ||
/** | ||
* @function getTypePrefixedString | ||
* @function shouldSort | ||
* | ||
* @description | ||
* prepend type to string value | ||
* get the sort result based on the two values to compare | ||
* | ||
* @param {string} string the string to prepend | ||
* @param {string} type the type to add as a prefix | ||
* @returns {string} the prefixed string | ||
* @param {string} valueA the first value to compare | ||
* @param {string} valueB the second value to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
var getTypePrefixedString = exports.getTypePrefixedString = function getTypePrefixedString(string, type) { | ||
return _constants.OBJECT_CLASS_MAP[type] + ' ' + string; | ||
var shouldSort = exports.shouldSort = function shouldSort(valueA, valueB) { | ||
return valueA > valueB; | ||
}; | ||
/** | ||
* @function getStringifiedElement | ||
* @function shouldSortPair | ||
* | ||
* @description | ||
* get the HTML element stringified by its type, attributes, and contents | ||
* get the sort result based on the two pairs to compare | ||
* | ||
* @param {HTMLElement} element the element to stringify | ||
* @returns {string} the stringified elements | ||
* @param {Object} pairA the first pair to compare | ||
* @param {Object} pairB the second pair to compare | ||
* @returns {boolean} should the value be sorted | ||
*/ | ||
var getStringifiedElement = exports.getStringifiedElement = function getStringifiedElement(element) { | ||
var attributes = element.attributes; | ||
var shouldSortPair = exports.shouldSortPair = function shouldSortPair(pairA, pairB) { | ||
return shouldSort(pairA[0], pairB[0]); | ||
}; | ||
var attributesString = ''; | ||
/** | ||
* @function getPrefixedValue | ||
* | ||
* @description | ||
* get the value prefixed by the tag | ||
* | ||
* @param {string} tag the object tag | ||
* @param {any} value the value to stringify | ||
* @returns {string} the prefixed stringified value | ||
*/ | ||
var getPrefixedValue = exports.getPrefixedValue = function getPrefixedValue(tag, value) { | ||
return tag + '|' + value; | ||
}; | ||
for (var index = 0; index < attributes.length; index++) { | ||
attributesString += attributes[index].name + '="' + attributes[index].value + '",'; | ||
/** | ||
* @function sort | ||
* | ||
* @description | ||
* sort the array based on the fn passed | ||
* | ||
* @param {Array<any>} array the array to sort | ||
* @param {function} fn the sorting function | ||
* @returns {Array<any>} the sorted array | ||
*/ | ||
var sort = exports.sort = function sort(array, fn) { | ||
var subIndex = void 0, | ||
value = void 0; | ||
for (var index = 0; index < array.length; index++) { | ||
value = array[index]; | ||
for (subIndex = index - 1; ~subIndex && fn(array[subIndex], value); subIndex--) { | ||
array[subIndex + 1] = array[subIndex]; | ||
} | ||
array[subIndex + 1] = value; | ||
} | ||
return element.tagName + ' ' + attributesString + ' ' + element.innerHTML; | ||
return array; | ||
}; | ||
/** | ||
* @function getStringifiedValueByObjectClass | ||
* @function getIterablePairs | ||
* | ||
* @description | ||
* get the stringified value of the object based based on its toString class | ||
* get the pairs in the iterable for stringification | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @param {string} [passedObjectClass] the object class for the object passed | ||
* @returns {*} the value to stringify with | ||
* @param {Map|Set} iterable the iterable to get the pairs for | ||
* @returns {Array<{key: string, value: any}>} the pairs | ||
*/ | ||
var getStringifiedValueByObjectClass = exports.getStringifiedValueByObjectClass = function getStringifiedValueByObjectClass(object, passedObjectClass) { | ||
var objectClass = passedObjectClass || toString.call(object); | ||
var getSortedIterablePairs = exports.getSortedIterablePairs = function getSortedIterablePairs(iterable) { | ||
var isMap = typeof iterable.get === 'function'; | ||
var pairs = []; | ||
if (~_constants.STRINGIFY_SELF_CLASSES.indexOf(objectClass)) { | ||
return object; | ||
} | ||
iterable.forEach(function (value, key) { | ||
// eslint-disable-next-line no-use-before-define | ||
pairs.push(isMap ? [stringify(key), stringify(value)] : [stringify(value)]); | ||
}); | ||
if (~_constants.STRINGIFY_PREFIX_CLASSES.indexOf(objectClass) || object === null) { | ||
return getTypePrefixedString(object, objectClass); | ||
} | ||
sort(pairs, shouldSortPair); | ||
if (objectClass === _constants.OBJECT_CLASS_TYPE_MAP.DATE) { | ||
return getTypePrefixedString(object.valueOf(), objectClass); | ||
} | ||
var finalPairs = new Array(iterable.size); | ||
if (~_constants.STRINGIFY_ITERABLE_CLASSES.indexOf(objectClass)) { | ||
return getIterablePairs(object, objectClass); | ||
} | ||
var pair = void 0; | ||
if (~_constants.STRINGIFY_NOT_ENUMERABLE_CLASSES.indexOf(objectClass)) { | ||
return getTypePrefixedString('NOT_ENUMERABLE', objectClass); | ||
} | ||
for (var index = 0; index < iterable.size; index++) { | ||
pair = pairs[index]; | ||
if (objectClass === _constants.OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object), objectClass); | ||
finalPairs[index] = isMap ? '[' + pair[0] + ',' + pair[1] + ']' : pair[0]; | ||
} | ||
if (objectClass === _constants.OBJECT_CLASS_TYPE_MAP.DATAVIEW) { | ||
return getTypePrefixedString(getStringFromArrayBuffer(object.buffer), objectClass); | ||
} | ||
return getPrefixedValue(getFunctionName(iterable.constructor), '[' + finalPairs.join(',') + ']'); | ||
}; | ||
if (~_constants.STRINGIFY_PREFIX_JOIN_CLASSES.indexOf(objectClass)) { | ||
return getTypePrefixedString(object.join(','), objectClass); | ||
} | ||
/** | ||
* @function getSortedObject | ||
* | ||
* @description | ||
* get the object with the keys sorted | ||
* | ||
* @param {Object} object the object to sort | ||
* @returns {Object} the sorted object | ||
*/ | ||
var getSortedObject = exports.getSortedObject = function getSortedObject(object) { | ||
var objectKeys = sort(keys(object), shouldSort); | ||
var newObject = {}; | ||
if (objectClass === _constants.OBJECT_CLASS_TYPE_MAP.MATH) { | ||
return _constants.MATH_OBJECT; | ||
var key = void 0; | ||
for (var index = 0; index < objectKeys.length; index++) { | ||
key = objectKeys[index]; | ||
newObject[key] = object[key]; | ||
} | ||
return _constants.HTML_ELEMENT_REGEXP.test(objectClass) ? getTypePrefixedString(getStringifiedElement(object), _constants.OBJECT_CLASS_TYPE_MAP.HTMLELEMENT) : object; | ||
return newObject; | ||
}; | ||
/** | ||
* @function getValueForStringification | ||
* @function getStringifiedArrayBufferFallback | ||
* | ||
* @description | ||
* get the string value for the object used for stringification | ||
* get the string value of the buffer passed based on a Buffer | ||
* | ||
* @param {*} object the object to get the stringification value for | ||
* @returns {*} the value to stringify with | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getValueForStringification = exports.getValueForStringification = function getValueForStringification(object) { | ||
var type = typeof object === 'undefined' ? 'undefined' : _typeof(object); | ||
var getStringifiedArrayBufferFallback = exports.getStringifiedArrayBufferFallback = function getStringifiedArrayBufferFallback(buffer) { | ||
return String.fromCharCode.apply(null, new Uint16Array(buffer)); | ||
}; | ||
if (~_constants.STRINGIFY_SELF_TYPES.indexOf(type)) { | ||
return object; | ||
} | ||
/** | ||
* @function getStringifiedArrayBufferModern | ||
* | ||
* @description | ||
* get the string value of the buffer passed based on a Uint16Array | ||
* | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getStringifiedArrayBufferModern = exports.getStringifiedArrayBufferModern = function getStringifiedArrayBufferModern(buffer) { | ||
return Buffer.from(buffer).toString('utf8'); | ||
}; | ||
if (~_constants.STRINGIFY_PREFIX_TYPES.indexOf(type)) { | ||
return getTypePrefixedString(~_constants.STRINGIFY_TOSTRING_TYPES.indexOf(type) ? object.constructor.prototype.toString.call(object) : object, toString.call(object)); | ||
} | ||
return getStringifiedValueByObjectClass(object); | ||
/** | ||
* @function getStringifiedArrayBufferNoSupport | ||
* | ||
* @description | ||
* return a placeholder when no arraybuffer support exists | ||
* | ||
* @returns {string} the placeholder | ||
*/ | ||
var getStringifiedArrayBufferNoSupport = exports.getStringifiedArrayBufferNoSupport = function getStringifiedArrayBufferNoSupport() { | ||
return ''; | ||
}; | ||
/** | ||
* @function getCircularStackValue | ||
* @function getStringifiedArrayBuffer | ||
* | ||
* @description | ||
* get the value either from the recursive storage stack | ||
* or itself after being added to that stack | ||
* get the string value of the buffer passed | ||
* | ||
* @param {*} value the value to check for existing | ||
* @param {string} type the type of the value | ||
* @param {Array<*>} stack the current stack of values | ||
* @param {number} circularCounter the counter of circular references | ||
* @returns {*} the value to apply | ||
* @param {ArrayBuffer} buffer the array buffer to convert | ||
* @returns {string} the stringified buffer | ||
*/ | ||
var getCircularStackValue = exports.getCircularStackValue = function getCircularStackValue(value, type, stack, circularCounter) { | ||
if (!value) { | ||
return getTypePrefixedString(value, type); | ||
} | ||
var getStringifiedArrayBuffer = exports.getStringifiedArrayBuffer = function () { | ||
return _constants.HAS_BUFFER_FROM_SUPPORT ? getStringifiedArrayBufferModern : _constants.HAS_UINT16ARRAY_SUPPORT ? getStringifiedArrayBufferFallback : getStringifiedArrayBufferNoSupport; | ||
}(); | ||
if (circularCounter > _constants.RECURSIVE_COUNTER_CUTOFF) { | ||
stack.length = 0; | ||
/** | ||
* @function getStringifiedDocumentFragment | ||
* | ||
* @description | ||
* build a string based on all the fragment's children | ||
* | ||
* @param {DocumentFragment} fragment the fragment to stringify | ||
* @returns {string} the stringified fragment | ||
*/ | ||
var getStringifiedDocumentFragment = exports.getStringifiedDocumentFragment = function getStringifiedDocumentFragment(fragment) { | ||
var children = fragment.children; | ||
return value; | ||
var innerHTML = ''; | ||
for (var index = 0; index < children.length; index++) { | ||
// eslint-disable-next-line no-use-before-define | ||
innerHTML += children[index].outerHTML; | ||
} | ||
var existingIndex = stack.indexOf(value); | ||
return innerHTML; | ||
}; | ||
if (!~existingIndex) { | ||
stack.push(value); | ||
return value; | ||
/** | ||
* @function indexOf | ||
* | ||
* @description | ||
* get the index of the value in the array (faster than native indexOf) | ||
* | ||
* @param {Array<any>} array the array to get the index of the value at | ||
* @param {any} value the value to match | ||
* @returns {number} the index of the value in array | ||
*/ | ||
var indexOf = exports.indexOf = function indexOf(array, value) { | ||
for (var index = 0; index < array.length; index++) { | ||
if (array[index] === value) { | ||
return index; | ||
} | ||
} | ||
return '*Circular-' + existingIndex; | ||
return -1; | ||
}; | ||
/** | ||
* @function createReplacer | ||
* @function getNormalizedValue | ||
* | ||
* @description | ||
* create the replacer function leveraging closure for recursive stack storage | ||
* get the value normalized for stringification | ||
* | ||
* @param {Array<*>} stack the stack to store in memory | ||
* @returns {function} the replacer to use | ||
* @param {any} value the value to normalize | ||
* @param {WeakMap|Object} sortedCache the cache of sorted objects | ||
* @returns {any} the normalized value | ||
*/ | ||
var createReplacer = exports.createReplacer = function createReplacer(stack) { | ||
var circularCounter = 1, | ||
objectClass = void 0; | ||
var getNormalizedValue = exports.getNormalizedValue = function getNormalizedValue(value, sortedCache) { | ||
var type = typeof value; | ||
return function (key, value) { | ||
if (!key) { | ||
stack = [value]; | ||
if (type === 'string') { | ||
return value; | ||
} | ||
return value; | ||
} | ||
if (_constants.PRIMITIVE_TAGS[type]) { | ||
return getPrefixedValue(type, value); | ||
} | ||
if (value === null) { | ||
return getStringifiedValueByObjectClass(value, _constants.OBJECT_CLASS_TYPE_MAP.NULL); | ||
} | ||
if (value === null) { | ||
return getPrefixedValue('null', value); | ||
} | ||
if (~_constants.STRINGIFY_TYPEOF_TYPES.indexOf(typeof value === 'undefined' ? 'undefined' : _typeof(value))) { | ||
return getValueForStringification(value); | ||
} | ||
var tag = toString.call(value); | ||
objectClass = toString.call(value); | ||
if (_constants.SELF_TAGS[tag]) { | ||
return value; | ||
} | ||
if (~_constants.REPLACE_RECURSIVE_VALUE_CLASSES.indexOf(objectClass)) { | ||
return getCircularStackValue(value, objectClass, stack, ++circularCounter); | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.OBJECT) { | ||
if (~indexOf(sortedCache, value)) { | ||
return _constants.CIRCULAR_VALUE; | ||
} | ||
if (~_constants.REPLACE_STRINGIFICATION_CLASSES.indexOf(objectClass)) { | ||
return getStringifiedValueByObjectClass(value, objectClass); | ||
sortedCache.push(value); | ||
return getSortedObject(value, sortedCache); | ||
} | ||
if (_constants.TOSTRING_TAGS[tag]) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.toString()); | ||
} | ||
if (_constants.ITERABLE_TAGS[tag]) { | ||
if (~indexOf(sortedCache, value)) { | ||
return _constants.CIRCULAR_VALUE; | ||
} | ||
return value; | ||
}; | ||
}; | ||
sortedCache.push(value); | ||
/** | ||
* @function getIntegerHashValue | ||
* | ||
* @description | ||
* based on string passed, get the integer hash value | ||
* through bitwise operation (based on spinoff of dbj2) | ||
* | ||
* @param {string} string the string to get the hash value for | ||
* @returns {number} the hash value | ||
*/ | ||
var getIntegerHashValue = exports.getIntegerHashValue = function getIntegerHashValue(string) { | ||
if (!string) { | ||
return 0; | ||
return getSortedIterablePairs(value); | ||
} | ||
var hashValue = 5381; | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DATE) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.getTime()); | ||
} | ||
for (var index = 0; index < string.length; index++) { | ||
hashValue = (hashValue << 5) + hashValue + string.charCodeAt(index); | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.ERROR) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.stack); | ||
} | ||
return hashValue >>> 0; | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.EVENT) { | ||
return getSortedEvent(value); | ||
} | ||
if (_constants.UNPARSEABLE_TAGS[tag]) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], 'NOT_ENUMERABLE'); | ||
} | ||
if (_constants.HTML_ELEMENT_REGEXP.test(tag) || _constants.SVG_ELEMENT_REGEXP.test(tag)) { | ||
return getPrefixedValue(tag.slice(8, -1), value.outerHTML); | ||
} | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DOCUMENTFRAGMENT) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedDocumentFragment(value)); | ||
} | ||
if (_constants.TYPEDARRAY_TAGS[tag]) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], value.join(',')); | ||
} | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.ARRAYBUFFER) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value)); | ||
} | ||
if (tag === _constants.OBJECT_CLASS_TYPE_MAP.DATAVIEW) { | ||
return getPrefixedValue(_constants.OBJECT_CLASS_MAP[tag], getStringifiedArrayBuffer(value.buffer)); | ||
} | ||
return value; | ||
}; | ||
/** | ||
* @function tryCatch | ||
* @function replacer | ||
* | ||
* @description | ||
* move try/catch to standalone function as any function that contains a try/catch | ||
* is not optimized (this allows optimization for as much as possible) | ||
* create the replacer function used for stringification | ||
* | ||
* @param {*} value the value to stringify | ||
* @returns {string} the stringified value | ||
* @param {WeakSet|Object} sortedCache the cache to use for sorting objects | ||
* @returns {function(key: string, value: any)} function getting the normalized value | ||
*/ | ||
var tryCatch = exports.tryCatch = function tryCatch(value) { | ||
try { | ||
return JSON.stringify(value, createReplacer([])); | ||
} catch (exception) { | ||
return (0, _jsonPrune2.default)(value); | ||
} | ||
var createReplacer = exports.createReplacer = function createReplacer(sortedCache) { | ||
return function (key, value) { | ||
return getNormalizedValue(value, sortedCache); | ||
}; | ||
}; | ||
/** | ||
* @function getStringifiedValue | ||
* @function stringify | ||
* | ||
* @description | ||
* stringify the object passed leveraging JSON.stringify | ||
* with REPLACER, falling back to prune | ||
* stringify the value based on the options passed | ||
* | ||
* @param {*} object the object to stringify | ||
* @param {boolean} isCircular is the object circular or not | ||
* @returns {string} the stringified object | ||
* @param {any} value the value to stringify | ||
* @returns {string} the stringified value | ||
*/ | ||
var getStringifiedValue = exports.getStringifiedValue = function getStringifiedValue(object, isCircular) { | ||
var valueForStringification = getValueForStringification(object); | ||
if (typeof valueForStringification === 'string') { | ||
return valueForStringification; | ||
} | ||
return isCircular ? tryCatch(getValueForStringification(object)) : JSON.stringify(valueForStringification, createReplacer([])); | ||
}; | ||
function stringify(value) { | ||
return typeof value === 'object' && value && !(value instanceof RegExp || value instanceof Date) ? (0, _fastStringify2.default)(value, createReplacer([]), null, getCircularValue) : getNormalizedValue(value); | ||
} |
@@ -12,7 +12,7 @@ { | ||
"files": [ | ||
"test/*.js" | ||
"test/*.js", | ||
"!test/data/*" | ||
], | ||
"require": [ | ||
"babel-register", | ||
"babel-polyfill", | ||
"./test/helpers/setup-browser-env.js" | ||
@@ -35,10 +35,10 @@ ], | ||
"devDependencies": { | ||
"ava": "^0.24.0", | ||
"ava": "^0.25.0", | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "^8.1.2", | ||
"babel-loader": "^7.1.2", | ||
"babel-core": "^6.26.3", | ||
"babel-eslint": "^8.2.3", | ||
"babel-loader": "^7.1.4", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-polyfill": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-preset-env": "^1.7.0", | ||
"babel-preset-react": "6.24.1", | ||
@@ -49,21 +49,27 @@ "babel-preset-stage-2": "^6.24.1", | ||
"benchmark": "^2.1.4", | ||
"browser-env": "^3.2.4", | ||
"eslint": "^4.14.0", | ||
"browser-env": "^3.2.5", | ||
"eslint": "^4.19.1", | ||
"eslint-config-rapid7": "^2.11.1", | ||
"eslint-friendly-formatter": "3.0.0", | ||
"eslint-loader": "^1.9.0", | ||
"eslint-friendly-formatter": "4.0.1", | ||
"eslint-loader": "^2.0.0", | ||
"faker": "^4.1.0", | ||
"hash-object": "^0.1.7", | ||
"html-webpack-plugin": "^2.30.1", | ||
"html-webpack-plugin": "^3.2.0", | ||
"in-publish": "2.0.0", | ||
"node-object-hash": "^1.3.0", | ||
"nyc": "^11.4.1", | ||
"object-hash": "^1.2.0", | ||
"node-object-hash": "^1.4.1", | ||
"nyc": "^12.0.2", | ||
"object-hash": "^1.3.0", | ||
"optimize-js-plugin": "^0.0.4", | ||
"react": "^16.2.0", | ||
"react-dom": "^16.2.0", | ||
"react": "^16.4.0", | ||
"react-dom": "^16.4.0", | ||
"rimraf": "^2.6.2", | ||
"sinon": "4.1.3", | ||
"webpack": "^3.10.0", | ||
"webpack-dev-server": "2.9.7" | ||
"rollup": "^0.60.2", | ||
"rollup-plugin-babel": "^3.0.4", | ||
"rollup-plugin-node-resolve": "^3.3.0", | ||
"rollup-plugin-uglify": "^4.0.0", | ||
"sinon": "6.0.0", | ||
"uuid": "^3.2.1", | ||
"webpack": "^4.12.0", | ||
"webpack-cli": "^3.0.3", | ||
"webpack-dev-server": "3.1.4" | ||
}, | ||
@@ -81,2 +87,13 @@ "homepage": "https://github.com/planttheidea/hash-it#readme", | ||
"name": "hash-it", | ||
"nyc": { | ||
"exclude": [ | ||
"test/*", | ||
"test/data/*" | ||
], | ||
"reporter": [ | ||
"text", | ||
"html", | ||
"text-summary" | ||
] | ||
}, | ||
"repository": { | ||
@@ -89,4 +106,3 @@ "type": "git", | ||
"benchmark:compare": "npm run transpile:lib && node benchmarks/compare.js", | ||
"build": "NODE_ENV=development webpack --progress --colors --config=webpack/webpack.config.js", | ||
"build:minified": "NODE_ENV=production webpack --progress --colors --config=webpack/webpack.config.minified.js", | ||
"build": "NODE_ENV=production rollup -c", | ||
"clean": "npm run clean:lib && npm run clean:es && npm run clean:dist", | ||
@@ -97,3 +113,3 @@ "clean:dist": "rimraf dist", | ||
"dev": "NODE_ENV=development webpack-dev-server --colors --progress --config=webpack/webpack.config.dev.js", | ||
"dist": "npm run clean:dist && npm run build && npm run build:minified", | ||
"dist": "npm run clean:dist && npm run build", | ||
"lint": "NODE_ENV=test eslint src", | ||
@@ -109,6 +125,8 @@ "prepublish": "if in-publish; then npm run prepublish:compile; fi", | ||
}, | ||
"version": "3.1.2", | ||
"version": "4.0.0", | ||
"dependencies": { | ||
"curriable": "^1.1.0", | ||
"fast-stringify": "^1.0.4", | ||
"json-prune": "^1.1.0" | ||
} | ||
} |
286
README.md
@@ -1,2 +0,2 @@ | ||
# hashIt | ||
# hash-it | ||
@@ -7,13 +7,13 @@ Fast and consistent hashCode for any object type | ||
* [Usage](#usage) | ||
* [Overview](#overview) | ||
* [Utility functions](#utility-functions) | ||
* [isEmpty](#isempty) | ||
* [isEqual](#isequal) | ||
* [isNull](#isnull) | ||
* [isUndefined](#isundefined) | ||
* [Gotchas](#gotchas) | ||
* [Browser support](#browser-support) | ||
* [Node support](#node-support) | ||
* [Development](#development) | ||
- [Usage](#usage) | ||
- [Overview](#overview) | ||
- [Utility functions](#utility-functions) | ||
- [is](#is) | ||
- [is.all](#isall) | ||
- [is.any](#isany) | ||
- [is.not](#isnot) | ||
- [Gotchas](#gotchas) | ||
- [Browser support](#browser-support) | ||
- [Node support](#node-support) | ||
- [Development](#development) | ||
@@ -24,15 +24,15 @@ ## Usage | ||
// ES2015 | ||
import hashIt from 'hash-it'; | ||
import hash from "hash-it"; | ||
// CommonJS | ||
const hashIt = require('hash-it').default; | ||
const hash = require("hash-it").default; | ||
// script | ||
const hashIt = window.hashIt; | ||
const hash = window.hashIt; | ||
// hash any standard object | ||
console.log(hashIt({foo: 'bar'})); // 2639617176 | ||
console.log(hash({ foo: "bar" })); // 8999940026732 | ||
// or if you know it is a circular object | ||
console.log(hashIt(window, true)); // 482488043 | ||
// or a circular object | ||
console.log(hash(window)); // 6514964902729 | ||
``` | ||
@@ -42,3 +42,3 @@ | ||
`hashIt` has a simple goal: provide a fast and consistent hashCode for any object type that is uniquely based on its values. This has a number of uses such as duplication prevention or fast equality comparisons. | ||
`hash-it` has a simple goal: provide a fast, consistent, unique hashCode for any object type that is uniquely based on its values. This has a number of uses such as duplication prevention, equality comparisons, blockchain construction, etc. | ||
@@ -53,10 +53,9 @@ _Any object type?_ | ||
* `Promise` | ||
* There is no way to obtain the values contained within due to its asynchronous nature | ||
* `Generator` (the result of calling a `GeneratorFunction`) | ||
* Like `Promise`, there is no way to obtain the values contained within due to its dynamic iterable nature | ||
* `WeakMap` / `WeakSet` | ||
- `Promise` | ||
- There is no way to obtain the values contained within due to its asynchronous nature | ||
- `Generator` (the result of calling a `GeneratorFunction`) | ||
- Like `Promise`, there is no way to obtain the values contained within due to its dynamic iterable nature | ||
- `WeakMap` / `WeakSet` | ||
- The spec explicitly forbids iteration over them, so the unique values cannot be discovered | ||
* The spec explicitly forbids iteration over them, so the unique values cannot be discovered | ||
In each of these cases, no matter what the values of the object, they will always yield the same hash result, which is unique to each object type. If you have any ideas about how these can be uniquely hashed, I welcome them! | ||
@@ -66,35 +65,40 @@ | ||
* `Arguments` | ||
* `Array` | ||
* `ArrayBuffer` | ||
* `Boolean` | ||
* `DataView` | ||
* `Date` (based on `valueOf`) | ||
* `Error` (based on `message`) | ||
* Includes all sub-types (e.g. `TypeError`, `ReferenceError`, etc.) | ||
* `Float32Array` | ||
* `Float64Array` | ||
* `Function` (based on `toString`) | ||
* `GeneratorFunction` (based on `toString`) | ||
* `Int8Array` | ||
* `Int16Array` | ||
* `Int32Array` | ||
* `HTMLElement` (based on `tagName`, `attributes`, and `innerHTML`) | ||
* Includes all sub-types (e.g. `HTMLAnchorElement`, `HTMLDivElement`, etc.) | ||
* `Map` | ||
* `Math` (based on `E`, `LN2`, `LN10`, `LOG2E`, `LOG10E`, `PI`, `SQRT1_2`, and `SQRT2`) | ||
* `Null` | ||
* `Number` | ||
* `Object` (can handle circular objects) | ||
* `Proxy` | ||
* `RegExp` | ||
* `Set` | ||
* `String` | ||
* `Symbol` | ||
* `Uint8Array` | ||
* `Uint8ClampedArray` | ||
* `Uint16Array` | ||
* `Uint32Array` | ||
* `Undefined` | ||
* `Window` | ||
- `Arguments` | ||
- `Array` | ||
- `ArrayBuffer` | ||
- `AsyncFunction` (based on `toString`) | ||
- `Boolean` | ||
- `DataView` (based on its `buffer`) | ||
- `Date` (based on `getTime`) | ||
- `DocumentFragment` (based on `outerHTML` of all `children`) | ||
- `Error` (based on `stack`) | ||
- Includes all sub-types (e.g., `TypeError`, `ReferenceError`, etc.) | ||
- `Event` (based on all properties other than `Event.timeStamp`) | ||
- Includes all sub-types (e.g., `MouseEvent`, `KeyboardEvent`, etc.) | ||
- `Float32Array` | ||
- `Float64Array` | ||
- `Function` (based on `toString`) | ||
- `GeneratorFunction` (based on `toString`) | ||
- `Int8Array` | ||
- `Int16Array` | ||
- `Int32Array` | ||
- `HTMLElement` (based on `outerHTML`) | ||
- Includes all sub-types (e.g., `HTMLAnchorElement`, `HTMLDivElement`, etc.) | ||
- `Map` (order-agnostic) | ||
- `Null` | ||
- `Number` | ||
- `Object` (handles circular objects, order-agnostic) | ||
- `Proxy` | ||
- `RegExp` | ||
- `Set` (order-agnostic) | ||
- `String` | ||
- `SVGElement` (based on `outerHTML`) | ||
- Includes all sub-types (e.g., `SVGRectElement`, `SVGPolygonElement`, etc.) | ||
- `Symbol` (based on `toString`) | ||
- `Uint8Array` | ||
- `Uint8ClampedArray` | ||
- `Uint16Array` | ||
- `Uint32Array` | ||
- `Undefined` | ||
- `Window` | ||
@@ -105,49 +109,121 @@ This is basically all I could think of, but if I have missed an object class let me know and I will add it! | ||
#### isEmpty | ||
#### is | ||
`isEmpty(object: any): boolean` | ||
`is(object: any, otherObject: any): boolean` | ||
Determines if object is empty based on hashCode, with empty defined as: | ||
Compares the two objects to determine equality. | ||
* Empty array (`[]`) | ||
* Empty map (`new Map()`) | ||
* Empty number, or zero (`0`) | ||
* Empty object (`{}`) | ||
* Empty set (`new Set()`) | ||
* Empty string (`''`) | ||
* Undefined (`undefined`) | ||
* Null (`null`) | ||
```javascript | ||
console.log(hash.is(null, 123)); // false | ||
console.log(hash.is(null, null)); // true | ||
``` | ||
This differs from the implementation by `lodash`, where a value is considered not empty if an `Array`, `Object`, `Map`, or `Set`. Think of this definition of empty as "having no value(s)". | ||
**NOTE**: This can also be used with partial-application to create prepared equality comparators. | ||
#### isEqual | ||
```javascript | ||
const isNull = hash.is(null); | ||
`isEqual(object1: any, object2: any[, object3: any[, ...objectN]]): boolean` | ||
console.log(isNull(123)); // false | ||
console.log(isNull(null)); // true | ||
``` | ||
Compares all objects passed to it to determine if they are equal to one another based on hashCode | ||
#### is.all | ||
`is.all(object1: any, object2: any[, object3: any[, ...objectN]]): boolean` | ||
Compares the first object to all other objects passed to determine if all are equal based on hashCode | ||
```javascript | ||
const foo = { | ||
foo: 'bar' | ||
foo: "bar" | ||
}; | ||
const alsoFoo = { | ||
foo: 'bar' | ||
foo: "bar" | ||
}; | ||
const stillFoo = { | ||
foo: "bar" | ||
}; | ||
console.log(foo === alsoFoo); // false | ||
console.log(hashIt.isEqual(foo, alsoFoo)); // true | ||
console.log(hash.is.all(foo, alsoFoo)); // true | ||
console.log(hash.is.all(foo, alsoFoo, stillFoo)); // true | ||
``` | ||
#### isNull | ||
**NOTE**: This can also be used with partial-application to create prepared equality comparators. | ||
`isNull(object: any): boolean` | ||
```javascript | ||
const foo = { | ||
foo: "bar" | ||
}; | ||
const alsoFoo = { | ||
foo: "bar" | ||
}; | ||
const stillFoo = { | ||
foo: "bar" | ||
}; | ||
Determines if object is null based on hashCode | ||
const isAllFoo = hash.is.all(foo); | ||
#### isUndefined | ||
console.log(isAllFoo(alsoFoo, stillFoo)); // true | ||
``` | ||
`isUndefined(object: any): boolean` | ||
#### is.any | ||
Determines if object is undefined based on hashCode | ||
`is.any(object1: any, object2: any[, object3: any[, ...objectN]]): boolean` | ||
Compares the first object to all other objects passed to determine if any are equal based on hashCode | ||
```javascript | ||
const foo = { | ||
foo: "bar" | ||
}; | ||
const alsoFoo = { | ||
foo: "bar" | ||
}; | ||
const nopeBar = { | ||
bar: "baz" | ||
}; | ||
console.log(hash.is.any(foo, alsoFoo)); // true | ||
console.log(hash.is.any(foo, nopeBar)); // false | ||
console.log(hash.is.any(foo, alsoFoo, nopeBar)); // true | ||
``` | ||
**NOTE**: This can also be used with partial-application to create prepared equality comparators. | ||
```javascript | ||
const foo = { | ||
foo: "bar" | ||
}; | ||
const alsoFoo = { | ||
foo: "bar" | ||
}; | ||
const nopeBar = { | ||
bar: "baz" | ||
}; | ||
const isAnyFoo = hash.is.any(foo); | ||
console.log(isAnyFoo(alsoFoo, nopeBar)); // true | ||
``` | ||
#### is.not | ||
`is.not(object: any, otherObject: any): boolean` | ||
Compares the two objects to determine non-equality. | ||
```javascript | ||
console.log(hash.is.not(null, 123)); // true | ||
console.log(hash.is.not(null, null)); // false | ||
``` | ||
**NOTE**: This can also be used with partial-application to create prepared equality comparators. | ||
```javascript | ||
const isNotNull = hash.is.not(null); | ||
console.log(isNull(123)); // true | ||
console.log(isNull(null)); // flse | ||
``` | ||
## Gotchas | ||
@@ -159,14 +235,14 @@ | ||
* Chrome (all versions) | ||
* Firefox (all versions) | ||
* Edge (all versions) | ||
* Opera 15+ | ||
* IE 9+ | ||
* Safari 6+ | ||
* iOS 8+ | ||
* Android 4+ | ||
- Chrome (all versions) | ||
- Firefox (all versions) | ||
- Edge (all versions) | ||
- Opera 15+ | ||
- IE 9+ | ||
- Safari 6+ | ||
- iOS 8+ | ||
- Android 4+ | ||
## Node support | ||
* 4+ | ||
- 4+ | ||
@@ -177,14 +253,14 @@ ## Development | ||
* `build` => run webpack to build development `dist` file with NODE_ENV=development | ||
* `build:minified` => run webpack to build production `dist` file with NODE_ENV=production | ||
* `dev` => run webpack dev server to run example app / playground | ||
* `dist` => runs `build` and `build:minified` | ||
* `lint` => run ESLint against all files in the `src` folder | ||
* `prepublish` => runs `prepublish:compile` when publishing | ||
* `prepublish:compile` => run `lint`, `test:coverage`, `transpile:es`, `transpile:lib`, `dist` | ||
* `test` => run AVA test functions with `NODE_ENV=test` | ||
* `test:coverage` => run `test` but with `nyc` for coverage checker | ||
* `test:watch` => run `test`, but with persistent watcher | ||
* `transpile:lib` => run babel against all files in `src` to create files in `lib` | ||
* `transpile:es` => run babel against all files in `src` to create files in `es`, preserving ES2015 modules (for | ||
- `build` => run webpack to build development `dist` file with NODE_ENV=development | ||
- `build:minified` => run webpack to build production `dist` file with NODE_ENV=production | ||
- `dev` => run webpack dev server to run example app / playground | ||
- `dist` => runs `build` and `build:minified` | ||
- `lint` => run ESLint against all files in the `src` folder | ||
- `prepublish` => runs `prepublish:compile` when publishing | ||
- `prepublish:compile` => run `lint`, `test:coverage`, `transpile:es`, `transpile:lib`, `dist` | ||
- `test` => run AVA test functions with `NODE_ENV=test` | ||
- `test:coverage` => run `test` but with `nyc` for coverage checker | ||
- `test:watch` => run `test`, but with persistent watcher | ||
- `transpile:lib` => run babel against all files in `src` to create files in `lib` | ||
- `transpile:es` => run babel against all files in `src` to create files in `es`, preserving ES2015 modules (for | ||
[`pkg.module`](https://github.com/rollup/rollup/wiki/pkg.module)) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
130797
19
2128
259
3
38
1
+ Addedcurriable@^1.1.0
+ Addedfast-stringify@^1.0.4
+ Addedcurriable@1.3.0(transitive)
+ Addedfast-stringify@1.1.2(transitive)