Package Exports
- hash-it
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (hash-it) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
hash-it
Fast and consistent hashCode for any object type
Table of contents
Usage
// ES2015
import hash from "hash-it";
// CommonJS
const hash = require("hash-it").default;
// script
const hash = window.hashIt;
// hash any standard object
console.log(hash({ foo: "bar" })); // 8999940026732
// or a circular object
console.log(hash(window)); // 6514964902729Overview
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.
Any object type?
Yes, any object type. Primitives, ES2015 classes like Symbol, DOM elements (yes, you can even hash the window object if you want). Any object type.
With no exceptions?
Well ... sadly, no, there are a few exceptions.
Promise- There is no way to obtain the values contained within due to its asynchronous nature
Generator(the result of calling aGeneratorFunction)- Like
Promise, there is no way to obtain the values contained within due to its dynamic iterable nature
- Like
WeakMap/WeakSet- 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!
Here is the list of object classes that have been tested and shown to produce unique hashCodes:
ArgumentsArrayArrayBufferAsyncFunction(based ontoString)BooleanDataView(based on itsbuffer)Date(based ongetTime)DocumentFragment(based onouterHTMLof allchildren)Error(based onstack)- Includes all sub-types (e.g.,
TypeError,ReferenceError, etc.)
- Includes all sub-types (e.g.,
Event(based on all properties other thanEvent.timeStamp)- Includes all sub-types (e.g.,
MouseEvent,KeyboardEvent, etc.)
- Includes all sub-types (e.g.,
Float32ArrayFloat64ArrayFunction(based ontoString)GeneratorFunction(based ontoString)Int8ArrayInt16ArrayInt32ArrayHTMLElement(based onouterHTML)- Includes all sub-types (e.g.,
HTMLAnchorElement,HTMLDivElement, etc.)
- Includes all sub-types (e.g.,
Map(order-agnostic)NullNumberObject(handles circular objects, order-agnostic)ProxyRegExpSet(order-agnostic)StringSVGElement(based onouterHTML)- Includes all sub-types (e.g.,
SVGRectElement,SVGPolygonElement, etc.)
- Includes all sub-types (e.g.,
Symbol(based ontoString)Uint8ArrayUint8ClampedArrayUint16ArrayUint32ArrayUndefinedWindow
This is basically all I could think of, but if I have missed an object class let me know and I will add it!
Utility functions
is
is(object: any, otherObject: any): boolean
Compares the two objects to determine equality.
console.log(hash.is(null, 123)); // false
console.log(hash.is(null, null)); // trueNOTE: This can also be used with partial-application to create prepared equality comparators.
const isNull = hash.is(null);
console.log(isNull(123)); // false
console.log(isNull(null)); // trueis.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
const foo = {
foo: "bar"
};
const alsoFoo = {
foo: "bar"
};
const stillFoo = {
foo: "bar"
};
console.log(hash.is.all(foo, alsoFoo)); // true
console.log(hash.is.all(foo, alsoFoo, stillFoo)); // trueNOTE: This can also be used with partial-application to create prepared equality comparators.
const foo = {
foo: "bar"
};
const alsoFoo = {
foo: "bar"
};
const stillFoo = {
foo: "bar"
};
const isAllFoo = hash.is.all(foo);
console.log(isAllFoo(alsoFoo, stillFoo)); // trueis.any
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
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)); // trueNOTE: This can also be used with partial-application to create prepared equality comparators.
const foo = {
foo: "bar"
};
const alsoFoo = {
foo: "bar"
};
const nopeBar = {
bar: "baz"
};
const isAnyFoo = hash.is.any(foo);
console.log(isAnyFoo(alsoFoo, nopeBar)); // trueis.not
is.not(object: any, otherObject: any): boolean
Compares the two objects to determine non-equality.
console.log(hash.is.not(null, 123)); // true
console.log(hash.is.not(null, null)); // falseNOTE: This can also be used with partial-application to create prepared equality comparators.
const isNotNull = hash.is.not(null);
console.log(isNull(123)); // true
console.log(isNull(null)); // flseGotchas
While the hashes will be consistent when calculated within the same browser environment, there is no guarantee that the hashCode will be the same across different browsers due to browser-specific implementations of features. A vast majority of the time things line up, but there are some edge cases that can cause differences, so just something to be mindful of.
Browser support
- Chrome (all versions)
- Firefox (all versions)
- Edge (all versions)
- Opera 15+
- IE 9+
- Safari 6+
- iOS 8+
- Android 4+
Node support
- 4+
Development
Standard stuff, clone the repo and npm install dependencies. The npm scripts available:
build=> run webpack to build developmentdistfile with NODE_ENV=developmentbuild:minified=> run webpack to build productiondistfile with NODE_ENV=productiondev=> run webpack dev server to run example app / playgrounddist=> runsbuildandbuild:minifiedlint=> run ESLint against all files in thesrcfolderprepublish=> runsprepublish:compilewhen publishingprepublish:compile=> runlint,test:coverage,transpile:es,transpile:lib,disttest=> run AVA test functions withNODE_ENV=testtest:coverage=> runtestbut withnycfor coverage checkertest:watch=> runtest, but with persistent watchertranspile:lib=> run babel against all files insrcto create files inlibtranspile:es=> run babel against all files insrcto create files ines, preserving ES2015 modules (forpkg.module)