Erster Docker-Stand
This commit is contained in:
200
_node_modules/effect/src/Hash.ts
generated
Normal file
200
_node_modules/effect/src/Hash.ts
generated
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @since 2.0.0
|
||||
*/
|
||||
import { pipe } from "./Function.js"
|
||||
import { globalValue } from "./GlobalValue.js"
|
||||
import { hasProperty } from "./Predicate.js"
|
||||
import { structuralRegionState } from "./Utils.js"
|
||||
|
||||
/** @internal */
|
||||
const randomHashCache = globalValue(
|
||||
Symbol.for("effect/Hash/randomHashCache"),
|
||||
() => new WeakMap<object, number>()
|
||||
)
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category symbols
|
||||
*/
|
||||
export const symbol: unique symbol = Symbol.for("effect/Hash")
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category models
|
||||
*/
|
||||
export interface Hash {
|
||||
[symbol](): number
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const hash: <A>(self: A) => number = <A>(self: A) => {
|
||||
if (structuralRegionState.enabled === true) {
|
||||
return 0
|
||||
}
|
||||
|
||||
switch (typeof self) {
|
||||
case "number":
|
||||
return number(self)
|
||||
case "bigint":
|
||||
return string(self.toString(10))
|
||||
case "boolean":
|
||||
return string(String(self))
|
||||
case "symbol":
|
||||
return string(String(self))
|
||||
case "string":
|
||||
return string(self)
|
||||
case "undefined":
|
||||
return string("undefined")
|
||||
case "function":
|
||||
case "object": {
|
||||
if (self === null) {
|
||||
return string("null")
|
||||
} else if (self instanceof Date) {
|
||||
return hash(self.toISOString())
|
||||
} else if (self instanceof URL) {
|
||||
return hash(self.href)
|
||||
} else if (isHash(self)) {
|
||||
return self[symbol]()
|
||||
} else {
|
||||
return random(self)
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error(
|
||||
`BUG: unhandled typeof ${typeof self} - please report an issue at https://github.com/Effect-TS/effect/issues`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const random: <A extends object>(self: A) => number = (self) => {
|
||||
if (!randomHashCache.has(self)) {
|
||||
randomHashCache.set(self, number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)))
|
||||
}
|
||||
return randomHashCache.get(self)!
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const combine: (b: number) => (self: number) => number = (b) => (self) => (self * 53) ^ b
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const optimize = (n: number): number => (n & 0xbfffffff) | ((n >>> 1) & 0x40000000)
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category guards
|
||||
*/
|
||||
export const isHash = (u: unknown): u is Hash => hasProperty(u, symbol)
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const number = (n: number) => {
|
||||
if (n !== n || n === Infinity) {
|
||||
return 0
|
||||
}
|
||||
let h = n | 0
|
||||
if (h !== n) {
|
||||
h ^= n * 0xffffffff
|
||||
}
|
||||
while (n > 0xffffffff) {
|
||||
h ^= n /= 0xffffffff
|
||||
}
|
||||
return optimize(h)
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const string = (str: string) => {
|
||||
let h = 5381, i = str.length
|
||||
while (i) {
|
||||
h = (h * 33) ^ str.charCodeAt(--i)
|
||||
}
|
||||
return optimize(h)
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const structureKeys = <A extends object>(o: A, keys: ReadonlyArray<keyof A>) => {
|
||||
let h = 12289
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
h ^= pipe(string(keys[i]! as string), combine(hash((o as any)[keys[i]!])))
|
||||
}
|
||||
return optimize(h)
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const structure = <A extends object>(o: A) =>
|
||||
structureKeys(o, Object.keys(o) as unknown as ReadonlyArray<keyof A>)
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const array = <A>(arr: ReadonlyArray<A>) => {
|
||||
let h = 6151
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
h = pipe(h, combine(hash(arr[i])))
|
||||
}
|
||||
return optimize(h)
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
export const cached: {
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
(self: object): (hash: number) => number
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @category hashing
|
||||
*/
|
||||
(self: object, hash: number): number
|
||||
} = function() {
|
||||
if (arguments.length === 1) {
|
||||
const self = arguments[0] as object
|
||||
return function(hash: number) {
|
||||
Object.defineProperty(self, symbol, {
|
||||
value() {
|
||||
return hash
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
return hash
|
||||
} as any
|
||||
}
|
||||
const self = arguments[0] as object
|
||||
const hash = arguments[1] as number
|
||||
Object.defineProperty(self, symbol, {
|
||||
value() {
|
||||
return hash
|
||||
},
|
||||
enumerable: false
|
||||
})
|
||||
|
||||
return hash
|
||||
}
|
||||
Reference in New Issue
Block a user