{"version":3,"sources":["../../src/index.ts","../../src/cache.ts","../../src/providers/crc.ts","../../src/providers/crypto.ts","../../src/providers/djb2.ts","../../src/providers/fnv1.ts","../../src/providers/murmur.ts","../../src/providers.ts"],"sourcesContent":["import { Hookified } from \"hookified\";\nimport { Cache } from \"./cache.js\";\nimport { CRC } from \"./providers/crc.js\";\nimport { WebCrypto } from \"./providers/crypto.js\";\nimport { DJB2 } from \"./providers/djb2.js\";\nimport { FNV1 } from \"./providers/fnv1.js\";\nimport { Murmur } from \"./providers/murmur.js\";\nimport { HashProviders } from \"./providers.js\";\nimport type {\n\tHasheryLoadProviderOptions,\n\tHasheryOptions,\n\tHasheryToHashOptions,\n\tHasheryToHashSyncOptions,\n\tHasheryToNumberOptions,\n\tHasheryToNumberSyncOptions,\n\tHashProvider,\n\tParseFn,\n\tStringifyFn,\n\tWebCryptoHashAlgorithm,\n} from \"./types.js\";\n\nexport class Hashery extends Hookified {\n\tprivate _parse: ParseFn = JSON.parse;\n\tprivate _stringify: StringifyFn = JSON.stringify;\n\tprivate _providers = new HashProviders();\n\tprivate _defaultAlgorithm: string = \"SHA-256\";\n\tprivate _defaultAlgorithmSync: string = \"djb2\";\n\tprivate _cache: Cache;\n\n\tconstructor(options?: HasheryOptions) {\n\t\tsuper(options);\n\n\t\tif (options?.parse) {\n\t\t\tthis._parse = options.parse;\n\t\t}\n\n\t\tif (options?.stringify) {\n\t\t\tthis._stringify = options.stringify;\n\t\t}\n\n\t\tif (options?.defaultAlgorithm) {\n\t\t\tthis._defaultAlgorithm = options.defaultAlgorithm;\n\t\t}\n\n\t\tif (options?.defaultAlgorithmSync) {\n\t\t\tthis._defaultAlgorithmSync = options.defaultAlgorithmSync;\n\t\t}\n\n\t\tthis._cache = new Cache(options?.cache);\n\n\t\tthis.loadProviders(options?.providers, {\n\t\t\tincludeBase: options?.includeBase ?? true,\n\t\t});\n\t}\n\n\t/**\n\t * Gets the parse function used to deserialize stored values.\n\t * @returns The current parse function (defaults to JSON.parse)\n\t */\n\tpublic get parse(): ParseFn {\n\t\treturn this._parse;\n\t}\n\n\t/**\n\t * Sets the parse function used to deserialize stored values.\n\t * @param value - The parse function to use for deserialization\n\t */\n\tpublic set parse(value: ParseFn) {\n\t\tthis._parse = value;\n\t}\n\n\t/**\n\t * Gets the stringify function used to serialize values for storage.\n\t * @returns The current stringify function (defaults to JSON.stringify)\n\t */\n\tpublic get stringify(): StringifyFn {\n\t\treturn this._stringify;\n\t}\n\n\t/**\n\t * Sets the stringify function used to serialize values for storage.\n\t * @param value - The stringify function to use for serialization\n\t */\n\tpublic set stringify(value: StringifyFn) {\n\t\tthis._stringify = value;\n\t}\n\n\t/**\n\t * Gets the HashProviders instance used to manage hash providers.\n\t * @returns The current HashProviders instance\n\t */\n\tpublic get providers(): HashProviders {\n\t\treturn this._providers;\n\t}\n\n\t/**\n\t * Sets the HashProviders instance used to manage hash providers.\n\t * @param value - The HashProviders instance to use\n\t */\n\tpublic set providers(value: HashProviders) {\n\t\tthis._providers = value;\n\t}\n\n\t/**\n\t * Gets the names of all registered hash algorithm providers.\n\t * @returns An array of provider names (e.g., ['SHA-256', 'SHA-384', 'SHA-512'])\n\t */\n\tpublic get names(): Array<string> {\n\t\treturn this._providers.names;\n\t}\n\n\t/**\n\t * Gets the default hash algorithm used when none is specified.\n\t * @returns The current default algorithm (defaults to 'SHA-256')\n\t */\n\tpublic get defaultAlgorithm(): string {\n\t\treturn this._defaultAlgorithm;\n\t}\n\n\t/**\n\t * Sets the default hash algorithm to use when none is specified.\n\t * @param value - The default algorithm to use (e.g., 'SHA-256', 'SHA-512', 'djb2')\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * hashery.defaultAlgorithm = 'SHA-512';\n\t *\n\t * // Now toHash will use SHA-512 by default\n\t * const hash = await hashery.toHash({ data: 'example' });\n\t * ```\n\t */\n\tpublic set defaultAlgorithm(value: string) {\n\t\tthis._defaultAlgorithm = value;\n\t}\n\n\t/**\n\t * Gets the default synchronous hash algorithm used when none is specified.\n\t * @returns The current default synchronous algorithm (defaults to 'djb2')\n\t */\n\tpublic get defaultAlgorithmSync(): string {\n\t\treturn this._defaultAlgorithmSync;\n\t}\n\n\t/**\n\t * Sets the default synchronous hash algorithm to use when none is specified.\n\t * @param value - The default synchronous algorithm to use (e.g., 'djb2', 'fnv1', 'murmur', 'crc32')\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * hashery.defaultAlgorithmSync = 'fnv1';\n\t *\n\t * // Now synchronous operations will use fnv1 by default\n\t * ```\n\t */\n\tpublic set defaultAlgorithmSync(value: string) {\n\t\tthis._defaultAlgorithmSync = value;\n\t}\n\n\t/**\n\t * Gets the cache instance used to store computed hash values.\n\t * @returns The Cache instance\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery({ cache: { enabled: true } });\n\t *\n\t * // Access the cache\n\t * hashery.cache.enabled; // true\n\t * hashery.cache.size; // number of cached items\n\t * hashery.cache.clear(); // clear all cached items\n\t * ```\n\t */\n\tpublic get cache(): Cache {\n\t\treturn this._cache;\n\t}\n\n\t/**\n\t * Generates a cryptographic hash of the provided data using the Web Crypto API.\n\t * The data is first stringified using the configured stringify function, then hashed.\n\t *\n\t * If an invalid algorithm is provided, a 'warn' event is emitted and the method falls back\n\t * to the default algorithm. You can listen to these warnings:\n\t * ```ts\n\t * hashery.on('warn', (message) => console.log(message));\n\t * ```\n\t *\n\t * @param data - The data to hash (will be stringified before hashing)\n\t * @param options - Optional configuration object\n\t * @param options.algorithm - The hash algorithm to use (defaults to 'SHA-256')\n\t * @param options.maxLength - Optional maximum length for the hash output\n\t * @returns A Promise that resolves to the hexadecimal string representation of the hash\n\t *\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * const hash = await hashery.toHash({ name: 'John', age: 30 });\n\t * console.log(hash); // \"a1b2c3d4...\"\n\t *\n\t * // Using a different algorithm\n\t * const hash512 = await hashery.toHash({ name: 'John' }, { algorithm: 'SHA-512' });\n\t * ```\n\t */\n\tpublic async toHash(\n\t\tdata: unknown,\n\t\toptions?: HasheryToHashOptions,\n\t): Promise<string> {\n\t\t// Before hook - allows modification of input data and algorithm\n\t\tconst context = {\n\t\t\tdata,\n\t\t\talgorithm: options?.algorithm ?? this._defaultAlgorithm,\n\t\t\tmaxLength: options?.maxLength,\n\t\t};\n\t\tawait this.beforeHook(\"toHash\", context);\n\n\t\t// Stringify the data using the configured stringify function\n\t\tconst stringified = this._stringify(context.data);\n\n\t\t// Check cache first\n\t\tconst cacheKey = `${context.algorithm}:${stringified}`;\n\t\tif (this._cache.enabled) {\n\t\t\tconst cached = this._cache.get(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tlet cachedHash = cached;\n\t\t\t\t// Apply maxLength if specified\n\t\t\t\tif (options?.maxLength && cachedHash.length > options.maxLength) {\n\t\t\t\t\tcachedHash = cachedHash.substring(0, options.maxLength);\n\t\t\t\t}\n\n\t\t\t\t// After hook - run even on cache hits for consistent behavior\n\t\t\t\tconst result = {\n\t\t\t\t\thash: cachedHash,\n\t\t\t\t\tdata: context.data,\n\t\t\t\t\talgorithm: context.algorithm,\n\t\t\t\t};\n\t\t\t\tawait this.afterHook(\"toHash\", result);\n\n\t\t\t\treturn result.hash;\n\t\t\t}\n\t\t}\n\n\t\t// Convert the string to a Uint8Array\n\t\tconst encoder = new TextEncoder();\n\t\tconst dataBuffer = encoder.encode(stringified);\n\n\t\t// Get the provider for the specified algorithm\n\t\tlet provider = this._providers.get(context.algorithm);\n\t\tif (!provider) {\n\t\t\t// Emit warning for invalid algorithm\n\t\t\tthis.emit(\n\t\t\t\t\"warn\",\n\t\t\t\t`Invalid algorithm '${context.algorithm}' not found. Falling back to default algorithm '${this._defaultAlgorithm}'.`,\n\t\t\t);\n\n\t\t\tprovider = new WebCrypto({\n\t\t\t\talgorithm: this._defaultAlgorithm as WebCryptoHashAlgorithm,\n\t\t\t});\n\t\t}\n\n\t\t// Use the provider to hash the data\n\t\tlet hash = await provider.toHash(dataBuffer);\n\n\t\t// Store the full hash in cache before truncation\n\t\tif (this._cache.enabled) {\n\t\t\tthis._cache.set(cacheKey, hash);\n\t\t}\n\n\t\t// if there is a max then change the hash\n\t\tif (options?.maxLength && hash.length > options?.maxLength) {\n\t\t\thash = hash.substring(0, options.maxLength);\n\t\t}\n\n\t\t// After hook - allows modification/logging of result\n\t\tconst result = { hash, data: context.data, algorithm: context.algorithm };\n\t\tawait this.afterHook(\"toHash\", result);\n\n\t\treturn result.hash;\n\t}\n\n\t/**\n\t * Generates a deterministic number within a specified range based on the hash of the provided data.\n\t * This method uses the toHash function to create a consistent hash, then maps it to a number\n\t * between min and max (inclusive).\n\t *\n\t * @param data - The data to hash (will be stringified before hashing)\n\t * @param options - Configuration options (optional, defaults to min: 0, max: 100)\n\t * @param options.min - The minimum value of the range (inclusive, defaults to 0)\n\t * @param options.max - The maximum value of the range (inclusive, defaults to 100)\n\t * @param options.algorithm - The hash algorithm to use (defaults to 'SHA-256')\n\t * @param options.hashLength - Number of characters from hash to use for conversion (defaults to 16)\n\t * @returns A Promise that resolves to a number between min and max (inclusive)\n\t *\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * const num = await hashery.toNumber({ user: 'john' }); // Uses default min: 0, max: 100\n\t * console.log(num); // Always returns the same number for the same input, e.g., 42\n\t *\n\t * // Using custom range\n\t * const num2 = await hashery.toNumber({ user: 'john' }, { min: 1, max: 100 });\n\t *\n\t * // Using a different algorithm\n\t * const num512 = await hashery.toNumber({ user: 'john' }, { min: 0, max: 255, algorithm: 'SHA-512' });\n\t * ```\n\t */\n\tpublic async toNumber(\n\t\tdata: unknown,\n\t\toptions: HasheryToNumberOptions = {},\n\t): Promise<number> {\n\t\tconst {\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\talgorithm = this._defaultAlgorithm,\n\t\t\thashLength = 16,\n\t\t} = options;\n\n\t\tif (min > max) {\n\t\t\tthrow new Error(\"min cannot be greater than max\");\n\t\t}\n\n\t\t// Get the hash as a hex string\n\t\t// Take the first hashLength characters of the hash to convert to a number\n\t\t// This provides good distribution while avoiding precision issues with JavaScript numbers\n\t\tconst hash = await this.toHash(data, { algorithm, maxLength: hashLength });\n\n\t\t// Convert hex to a number\n\t\tconst hashNumber = Number.parseInt(hash, 16);\n\n\t\t// Map the hash number to the desired range\n\t\tconst range = max - min + 1;\n\t\tconst mapped = min + (hashNumber % range);\n\n\t\treturn mapped;\n\t}\n\n\t/**\n\t * Generates a hash of the provided data synchronously using a non-cryptographic hash algorithm.\n\t * The data is first stringified using the configured stringify function, then hashed.\n\t *\n\t * Note: This method only works with synchronous hash providers (djb2, fnv1, murmur, crc32).\n\t * WebCrypto algorithms (SHA-256, SHA-384, SHA-512) are not supported and will throw an error.\n\t *\n\t * If an invalid algorithm is provided, a 'warn' event is emitted and the method falls back\n\t * to the default synchronous algorithm. You can listen to these warnings:\n\t * ```ts\n\t * hashery.on('warn', (message) => console.log(message));\n\t * ```\n\t *\n\t * @param data - The data to hash (will be stringified before hashing)\n\t * @param options - Optional configuration object\n\t * @param options.algorithm - The hash algorithm to use (defaults to 'djb2')\n\t * @param options.maxLength - Optional maximum length for the hash output\n\t * @returns The hexadecimal string representation of the hash\n\t *\n\t * @throws {Error} If the specified algorithm does not support synchronous hashing\n\t * @throws {Error} If the default algorithm is not found\n\t *\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * const hash = hashery.toHashSync({ name: 'John', age: 30 });\n\t * console.log(hash); // \"7c9df5ea...\" (djb2 hash)\n\t *\n\t * // Using a different algorithm\n\t * const hashFnv1 = hashery.toHashSync({ name: 'John' }, { algorithm: 'fnv1' });\n\t * ```\n\t */\n\tpublic toHashSync(data: unknown, options?: HasheryToHashSyncOptions): string {\n\t\t// Before hook - allows modification of input data and algorithm (synchronous/blocking)\n\t\tconst context = {\n\t\t\tdata,\n\t\t\talgorithm: options?.algorithm ?? this._defaultAlgorithmSync,\n\t\t\tmaxLength: options?.maxLength,\n\t\t};\n\t\tthis.hookSync(\"before:toHashSync\", context);\n\n\t\t// Get algorithm from context (may have been modified by hook)\n\t\tconst algorithm = context.algorithm;\n\n\t\t// Stringify the data using the configured stringify function\n\t\tconst stringified = this._stringify(context.data);\n\n\t\t// Check cache first\n\t\tconst cacheKey = `${algorithm}:${stringified}`;\n\t\tif (this._cache.enabled) {\n\t\t\tconst cached = this._cache.get(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tlet cachedHash = cached;\n\t\t\t\t// Apply maxLength if specified\n\t\t\t\tif (options?.maxLength && cachedHash.length > options.maxLength) {\n\t\t\t\t\tcachedHash = cachedHash.substring(0, options.maxLength);\n\t\t\t\t}\n\n\t\t\t\t// After hook - run even on cache hits for consistent behavior\n\t\t\t\tconst result = {\n\t\t\t\t\thash: cachedHash,\n\t\t\t\t\tdata: context.data,\n\t\t\t\t\talgorithm,\n\t\t\t\t};\n\t\t\t\tthis.hookSync(\"after:toHashSync\", result);\n\n\t\t\t\treturn result.hash;\n\t\t\t}\n\t\t}\n\n\t\t// Convert the string to a Uint8Array\n\t\tconst encoder = new TextEncoder();\n\t\tconst dataBuffer = encoder.encode(stringified);\n\n\t\t// Get the provider for the specified algorithm\n\t\tlet provider = this._providers.get(algorithm);\n\t\tif (!provider) {\n\t\t\t// Emit warning for invalid algorithm\n\t\t\tthis.emit(\n\t\t\t\t\"warn\",\n\t\t\t\t`Invalid algorithm '${algorithm}' not found. Falling back to default algorithm '${this._defaultAlgorithmSync}'.`,\n\t\t\t);\n\n\t\t\t// Fallback to default sync algorithm\n\t\t\tprovider = this._providers.get(this._defaultAlgorithmSync);\n\n\t\t\t// If default algorithm is also not found, throw error\n\t\t\tif (!provider) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Hash provider '${this._defaultAlgorithmSync}' (default) not found`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Check if provider supports synchronous hashing\n\t\tif (!provider.toHashSync) {\n\t\t\tthrow new Error(\n\t\t\t\t`Hash provider '${algorithm}' does not support synchronous hashing. Use toHash() instead or choose a different algorithm (djb2, fnv1, murmur, crc32).`,\n\t\t\t);\n\t\t}\n\n\t\t// Use the provider to hash the data synchronously\n\t\tlet hash = provider.toHashSync(dataBuffer);\n\n\t\t// Store the full hash in cache before truncation\n\t\tif (this._cache.enabled) {\n\t\t\tthis._cache.set(cacheKey, hash);\n\t\t}\n\n\t\t// if there is a max then change the hash\n\t\tif (options?.maxLength && hash.length > options?.maxLength) {\n\t\t\thash = hash.substring(0, options.maxLength);\n\t\t}\n\n\t\t// After hook - allows modification/logging of result (synchronous/blocking)\n\t\tconst result = { hash, data: context.data, algorithm: context.algorithm };\n\t\tthis.hookSync(\"after:toHashSync\", result);\n\n\t\treturn result.hash;\n\t}\n\n\t/**\n\t * Generates a deterministic number within a specified range based on the hash of the provided data synchronously.\n\t * This method uses the toHashSync function to create a consistent hash, then maps it to a number\n\t * between min and max (inclusive).\n\t *\n\t * Note: This method only works with synchronous hash providers (djb2, fnv1, murmur, crc32).\n\t *\n\t * @param data - The data to hash (will be stringified before hashing)\n\t * @param options - Configuration options (optional, defaults to min: 0, max: 100)\n\t * @param options.min - The minimum value of the range (inclusive, defaults to 0)\n\t * @param options.max - The maximum value of the range (inclusive, defaults to 100)\n\t * @param options.algorithm - The hash algorithm to use (defaults to 'djb2')\n\t * @param options.hashLength - Number of characters from hash to use for conversion (defaults to 16)\n\t * @returns A number between min and max (inclusive)\n\t *\n\t * @throws {Error} If the specified algorithm does not support synchronous hashing\n\t * @throws {Error} If min is greater than max\n\t *\n\t * @example\n\t * ```ts\n\t * const hashery = new Hashery();\n\t * const num = hashery.toNumberSync({ user: 'john' }); // Uses default min: 0, max: 100\n\t * console.log(num); // Always returns the same number for the same input, e.g., 42\n\t *\n\t * // Using custom range\n\t * const num2 = hashery.toNumberSync({ user: 'john' }, { min: 1, max: 100 });\n\t *\n\t * // Using a different algorithm\n\t * const numFnv1 = hashery.toNumberSync({ user: 'john' }, { min: 0, max: 255, algorithm: 'fnv1' });\n\t * ```\n\t */\n\tpublic toNumberSync(\n\t\tdata: unknown,\n\t\toptions: HasheryToNumberSyncOptions = {},\n\t): number {\n\t\tconst {\n\t\t\tmin = 0,\n\t\t\tmax = 100,\n\t\t\talgorithm = this._defaultAlgorithmSync,\n\t\t\thashLength = 16,\n\t\t} = options;\n\n\t\tif (min > max) {\n\t\t\tthrow new Error(\"min cannot be greater than max\");\n\t\t}\n\n\t\t// Get the hash as a hex string\n\t\t// Take the first hashLength characters of the hash to convert to a number\n\t\t// This provides good distribution while avoiding precision issues with JavaScript numbers\n\t\tconst hash = this.toHashSync(data, { algorithm, maxLength: hashLength });\n\n\t\t// Convert hex to a number\n\t\tconst hashNumber = Number.parseInt(hash, 16);\n\n\t\t// Map the hash number to the desired range\n\t\tconst range = max - min + 1;\n\t\tconst mapped = min + (hashNumber % range);\n\n\t\treturn mapped;\n\t}\n\n\tpublic loadProviders(\n\t\tproviders?: Array<HashProvider>,\n\t\toptions: HasheryLoadProviderOptions = { includeBase: true },\n\t): void {\n\t\tif (providers) {\n\t\t\tfor (const provider of providers) {\n\t\t\t\tthis._providers.add(provider);\n\t\t\t}\n\t\t}\n\n\t\t// load all the providers\n\t\tif (options.includeBase) {\n\t\t\tthis.providers.add(new WebCrypto({ algorithm: \"SHA-256\" }));\n\t\t\tthis.providers.add(new WebCrypto({ algorithm: \"SHA-384\" }));\n\t\t\tthis.providers.add(new WebCrypto({ algorithm: \"SHA-512\" }));\n\t\t\tthis.providers.add(new CRC());\n\t\t\tthis.providers.add(new DJB2());\n\t\t\tthis.providers.add(new FNV1());\n\t\t\tthis.providers.add(new Murmur());\n\t\t}\n\t}\n}\n\n// Types\nexport type { CacheOptions } from \"./cache.js\";\n// Classes\nexport { Cache } from \"./cache.js\";\nexport { CRC } from \"./providers/crc.js\";\nexport type { WebCryptoOptions } from \"./providers/crypto.js\";\nexport { WebCrypto } from \"./providers/crypto.js\";\nexport { DJB2 } from \"./providers/djb2.js\";\nexport { FNV1 } from \"./providers/fnv1.js\";\nexport { Murmur } from \"./providers/murmur.js\";\nexport { HashProviders } from \"./providers.js\";\nexport type {\n\tHashAlgorithm,\n\tHasheryLoadProviderOptions,\n\tHasheryOptions,\n\tHasheryToHashOptions,\n\tHasheryToHashSyncOptions,\n\tHasheryToNumberOptions,\n\tHasheryToNumberSyncOptions,\n\tHashProvider,\n\tHashProvidersGetOptions,\n\tHashProvidersOptions,\n\tParseFn,\n\tStringifyFn,\n\tWebCryptoHashAlgorithm,\n} from \"./types.js\";\n","/**\n * Configuration options for the Cache class.\n */\nexport type CacheOptions = {\n\t/**\n\t * Enable or disable the cache.\n\t * Defaults to true (enabled).\n\t */\n\tenabled?: boolean;\n\n\t/**\n\t * Maximum number of items to store in the cache.\n\t * Defaults to 4000. When limit is reached, oldest entries are evicted (FIFO).\n\t *\n\t * Note: JavaScript Map can hold up to 2^24 (~16.7 million) entries in most\n\t * environments, but practical limits depend on available memory and key/value sizes.\n\t * For hash caching, 4000-10000 entries is typically sufficient for most use cases.\n\t */\n\tmaxSize?: number;\n};\n\n/**\n * A simple FIFO (First In, First Out) cache for storing hash values.\n * When the cache reaches its maximum size, the oldest entries are evicted.\n *\n * The cache uses a JavaScript Map internally, which can theoretically hold up to\n * 2^24 (~16.7 million) entries. However, practical limits depend on available memory\n * and the size of cached keys/values. The default maxSize of 4000 provides a good\n * balance between performance and memory usage for typical hash caching scenarios.\n */\nexport class Cache {\n\tprivate _enabled = true;\n\tprivate _maxSize = 4000;\n\tprivate _store = new Map<string, string>();\n\tprivate _keys: string[] = [];\n\n\tconstructor(options?: CacheOptions) {\n\t\tif (options?.enabled !== undefined) {\n\t\t\tthis._enabled = options.enabled;\n\t\t}\n\n\t\tif (options?.maxSize !== undefined) {\n\t\t\tthis._maxSize = options.maxSize;\n\t\t}\n\t}\n\n\t/**\n\t * Gets whether the cache is enabled.\n\t */\n\tpublic get enabled(): boolean {\n\t\treturn this._enabled;\n\t}\n\n\t/**\n\t * Sets whether the cache is enabled.\n\t */\n\tpublic set enabled(value: boolean) {\n\t\tthis._enabled = value;\n\t}\n\n\t/**\n\t * Gets the maximum number of items the cache can hold.\n\t */\n\tpublic get maxSize(): number {\n\t\treturn this._maxSize;\n\t}\n\n\t/**\n\t * Sets the maximum number of items the cache can hold.\n\t */\n\tpublic set maxSize(value: number) {\n\t\tthis._maxSize = value;\n\t}\n\n\t/**\n\t * Gets the underlying Map store.\n\t */\n\tpublic get store(): Map<string, string> {\n\t\treturn this._store;\n\t}\n\n\t/**\n\t * Gets the current number of items in the cache.\n\t */\n\tpublic get size(): number {\n\t\treturn this._store.size;\n\t}\n\n\t/**\n\t * Gets a value from the cache.\n\t * @param key - The cache key\n\t * @returns The cached value, or undefined if not found\n\t */\n\tpublic get(key: string): string | undefined {\n\t\treturn this._store.get(key);\n\t}\n\n\t/**\n\t * Sets a value in the cache with FIFO eviction.\n\t * If the cache is disabled, this method does nothing.\n\t * If the cache is at capacity, the oldest entry is removed before adding the new one.\n\t * @param key - The cache key\n\t * @param value - The value to cache\n\t */\n\tpublic set(key: string, value: string): void {\n\t\tif (!this._enabled) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If key already exists, just update the value\n\t\tif (this._store.has(key)) {\n\t\t\tthis._store.set(key, value);\n\t\t\treturn;\n\t\t}\n\n\t\t// If at capacity, remove oldest (FIFO)\n\t\tif (this._store.size >= this._maxSize) {\n\t\t\tconst oldestKey = this._keys.shift();\n\t\t\t/* v8 ignore next -- @preserve */\n\t\t\tif (oldestKey) {\n\t\t\t\tthis._store.delete(oldestKey);\n\t\t\t}\n\t\t}\n\n\t\t// Add new entry\n\t\tthis._keys.push(key);\n\t\tthis._store.set(key, value);\n\t}\n\n\t/**\n\t * Checks if a key exists in the cache.\n\t * @param key - The cache key\n\t * @returns True if the key exists, false otherwise\n\t */\n\tpublic has(key: string): boolean {\n\t\treturn this._store.has(key);\n\t}\n\n\t/**\n\t * Clears all entries from the cache.\n\t */\n\tpublic clear(): void {\n\t\tthis._store.clear();\n\t\tthis._keys = [];\n\t}\n}\n","import type { HashProvider } from \"../types.ts\";\n\nexport class CRC implements HashProvider {\n    public get name(): string {\n        return \"crc32\";\n    }\n\n    public toHashSync(data: BufferSource): string {\n        // Convert BufferSource to Uint8Array\n        let bytes: Uint8Array;\n\n        if (data instanceof Uint8Array) {\n            bytes = data;\n        } else if (data instanceof ArrayBuffer) {\n            bytes = new Uint8Array(data);\n        } else if (data instanceof DataView) {\n            bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n        } else {\n            const view = data as ArrayBufferView;\n            bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n        }\n\n        // CRC-32 algorithm (IEEE 802.3 polynomial)\n        // This is the same algorithm used by PHP's crc32() function\n        const CRC32_POLYNOMIAL = 0xEDB88320;\n        let crc = 0xFFFFFFFF;\n\n        for (let i = 0; i < bytes.length; i++) {\n            crc = crc ^ bytes[i];\n            for (let j = 0; j < 8; j++) {\n                crc = (crc >>> 1) ^ (CRC32_POLYNOMIAL & -(crc & 1));\n            }\n        }\n\n        // Finalize CRC\n        crc = (crc ^ 0xFFFFFFFF) >>> 0;\n\n        // Convert to hexadecimal string (8 characters, zero-padded)\n        const hashHex = crc.toString(16).padStart(8, \"0\");\n        return hashHex;\n    }\n\n    public async toHash(data: BufferSource): Promise<string> {\n        return this.toHashSync(data);\n    }\n}\n","import type { WebCryptoHashAlgorithm, HashProvider } from \"../types.js\";\n\n\nexport type WebCryptoOptions = {\n\talgorithm?: WebCryptoHashAlgorithm\n}\n\nexport class WebCrypto implements HashProvider {\n\tprivate _algorithm: WebCryptoHashAlgorithm = \"SHA-256\";\n\tconstructor(options?: WebCryptoOptions) {\n\t\tif(options?.algorithm) {\n\t\t\tthis._algorithm = options?.algorithm;\n\t\t}\n\n\t}\n\n\tpublic get name(): string {\n\t\treturn this._algorithm;\n\t}\n\n\tpublic async toHash(data: BufferSource): Promise<string> {\n\t\t// Hash the data using Web Crypto API\n\t\tconst hashBuffer = await crypto.subtle.digest(this._algorithm, data);\n\n\t\t// Convert the hash to a hexadecimal string\n\t\tconst hashArray = Array.from(new Uint8Array(hashBuffer));\n\t\tconst hashHex = hashArray\n\t\t\t.map((byte) => byte.toString(16).padStart(2, \"0\"))\n\t\t\t.join(\"\");\n\n\t\treturn hashHex;\n\t}\n}","import type { HashProvider } from \"../types.ts\";\n\n/**\n * DJB2 hash algorithm implementation.\n *\n * DJB2 is a non-cryptographic hash function created by Daniel J. Bernstein.\n * It produces a 32-bit hash value, making it suitable for hash tables and checksums,\n * but NOT for cryptographic purposes.\n *\n * Algorithm: hash = hash * 33 + c (where c is each byte)\n * Initial value: 5381\n *\n * @example\n * ```typescript\n * import { Hashery } from 'hashery';\n * import { DJB2 } from 'hashery/providers/djb2';\n *\n * const hashery = new Hashery();\n * hashery.providers.add(new DJB2());\n *\n * const hash = await hashery.toHash({ data: 'hello' }, 'djb2');\n * console.log(hash); // \"7c9df5ea\"\n * ```\n */\nexport class DJB2 implements HashProvider {\n\t/**\n\t * The name identifier for this hash provider.\n\t */\n\tpublic get name(): string {\n\t\treturn \"djb2\";\n\t}\n\n\t/**\n\t * Computes the DJB2 hash of the provided data synchronously.\n\t *\n\t * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n\t * @returns An 8-character lowercase hexadecimal string\n\t *\n\t * @example\n\t * ```typescript\n\t * const djb2 = new DJB2();\n\t * const data = new TextEncoder().encode('hello');\n\t * const hash = djb2.toHashSync(data);\n\t * console.log(hash); // \"7c9df5ea\"\n\t * ```\n\t */\n\tpublic toHashSync(data: BufferSource): string {\n\t\t// Convert BufferSource to Uint8Array for consistent processing\n\t\tlet bytes: Uint8Array;\n\n\t\tif (data instanceof Uint8Array) {\n\t\t\tbytes = data;\n\t\t} else if (data instanceof ArrayBuffer) {\n\t\t\tbytes = new Uint8Array(data);\n\t\t} else if (data instanceof DataView) {\n\t\t\tbytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\t\t} else {\n\t\t\t// Fallback for other ArrayBufferView types (e.g., Int8Array, Uint16Array, etc.)\n\t\t\tconst view = data as ArrayBufferView;\n\t\t\tbytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n\t\t}\n\n\t\t// DJB2 algorithm\n\t\t// Initial hash value: 5381\n\t\tlet hash = 5381;\n\n\t\t// Process each byte: hash = hash * 33 + byte\n\t\tfor (let i = 0; i < bytes.length; i++) {\n\t\t\thash = ((hash << 5) + hash) + bytes[i]; // hash * 33 + c\n\t\t\t// Keep it as a 32-bit unsigned integer\n\t\t\thash = hash >>> 0;\n\t\t}\n\n\t\t// Convert to 8-character lowercase hexadecimal string\n\t\tconst hashHex = hash.toString(16).padStart(8, \"0\");\n\n\t\treturn hashHex;\n\t}\n\n\t/**\n\t * Computes the DJB2 hash of the provided data.\n\t *\n\t * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n\t * @returns A Promise resolving to an 8-character lowercase hexadecimal string\n\t *\n\t * @example\n\t * ```typescript\n\t * const djb2 = new DJB2();\n\t * const data = new TextEncoder().encode('hello');\n\t * const hash = await djb2.toHash(data);\n\t * console.log(hash); // \"7c9df5ea\"\n\t * ```\n\t */\n\tpublic async toHash(data: BufferSource): Promise<string> {\n\t\treturn this.toHashSync(data);\n\t}\n}\n","import type { HashProvider } from \"../types.ts\";\n\n/**\n * FNV-1 (Fowler-Noll-Vo) hash algorithm implementation.\n *\n * FNV-1 is a non-cryptographic hash function created by Glenn Fowler, Landon Curt Noll,\n * and Kiem-Phong Vo. It produces a 32-bit hash value, making it suitable for hash tables\n * and checksums, but NOT for cryptographic purposes.\n *\n * Algorithm: hash = (hash * FNV_prime) XOR octet_of_data\n * FNV-1 32-bit offset basis: 2166136261\n * FNV-1 32-bit prime: 16777619\n */\nexport class FNV1 implements HashProvider {\n    /**\n     * The name identifier for this hash provider.\n     */\n    public get name(): string {\n        return \"fnv1\";\n    }\n\n    /**\n     * Computes the FNV-1 hash of the provided data synchronously.\n     *\n     * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n     * @returns An 8-character lowercase hexadecimal string\n     */\n    public toHashSync(data: BufferSource): string {\n        // Convert BufferSource to Uint8Array for consistent processing\n        let bytes: Uint8Array;\n\n        if (data instanceof Uint8Array) {\n            bytes = data;\n        } else if (data instanceof ArrayBuffer) {\n            bytes = new Uint8Array(data);\n        } else if (data instanceof DataView) {\n            bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n        } else {\n            // Fallback for other ArrayBufferView types (e.g., Int8Array, Uint16Array, etc.)\n            const view = data as ArrayBufferView;\n            bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n        }\n\n        // FNV-1 algorithm constants\n        const FNV_OFFSET_BASIS = 2166136261; // 32-bit offset basis\n        const FNV_PRIME = 16777619; // 32-bit FNV prime\n\n        // Initialize hash with FNV offset basis\n        let hash = FNV_OFFSET_BASIS;\n\n        // Process each byte: hash = (hash * FNV_prime) XOR byte\n        for (let i = 0; i < bytes.length; i++) {\n            hash = hash * FNV_PRIME;\n            hash = hash ^ bytes[i];\n            // Keep it as a 32-bit unsigned integer\n            hash = hash >>> 0;\n        }\n\n        // Convert to 8-character lowercase hexadecimal string\n        const hashHex = hash.toString(16).padStart(8, \"0\");\n\n        return hashHex;\n    }\n\n    /**\n     * Computes the FNV-1 hash of the provided data.\n     *\n     * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n     * @returns A Promise resolving to an 8-character lowercase hexadecimal string\n     */\n    public async toHash(data: BufferSource): Promise<string> {\n        return this.toHashSync(data);\n    }\n}\n","import type { HashProvider } from \"../types.ts\";\n\n/**\n * Murmur 32-bit hash algorithm implementation.\n *\n * Murmur is a non-cryptographic hash function based on MurmurHash3 by Austin Appleby.\n * It produces a 32-bit hash value with excellent distribution and performance,\n * making it suitable for hash tables, bloom filters, and checksums,\n * but NOT for cryptographic purposes.\n *\n * This implementation uses the MurmurHash3_x86_32 variant.\n *\n * @example\n * ```typescript\n * import { Hashery } from 'hashery';\n * import { Murmur } from 'hashery/providers/murmur';\n *\n * const hashery = new Hashery();\n * hashery.providers.add(new Murmur());\n *\n * const hash = await hashery.toHash({ data: 'hello' }, 'murmur');\n * console.log(hash); // \"248bfa47\"\n * ```\n */\nexport class Murmur implements HashProvider {\n\tprivate _seed: number;\n\n\t/**\n\t * Creates a new Murmur instance.\n\t *\n\t * @param seed - Optional seed value for the hash (default: 0)\n\t */\n\tconstructor(seed: number = 0) {\n\t\tthis._seed = seed >>> 0; // Ensure it's a 32-bit unsigned integer\n\t}\n\n\t/**\n\t * The name identifier for this hash provider.\n\t */\n\tpublic get name(): string {\n\t\treturn \"murmur\";\n\t}\n\n\t/**\n\t * Gets the current seed value used for hashing.\n\t */\n\tpublic get seed(): number {\n\t\treturn this._seed;\n\t}\n\n\t/**\n\t * Computes the Murmur 32-bit hash of the provided data synchronously.\n\t *\n\t * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n\t * @returns An 8-character lowercase hexadecimal string\n\t *\n\t * @example\n\t * ```typescript\n\t * const murmur = new Murmur();\n\t * const data = new TextEncoder().encode('hello');\n\t * const hash = murmur.toHashSync(data);\n\t * console.log(hash); // \"248bfa47\"\n\t * ```\n\t */\n\tpublic toHashSync(data: BufferSource): string {\n\t\t// Convert BufferSource to Uint8Array for consistent processing\n\t\tlet bytes: Uint8Array;\n\n\t\tif (data instanceof Uint8Array) {\n\t\t\tbytes = data;\n\t\t} else if (data instanceof ArrayBuffer) {\n\t\t\tbytes = new Uint8Array(data);\n\t\t} else if (data instanceof DataView) {\n\t\t\tbytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\t\t} else {\n\t\t\t// Fallback for other ArrayBufferView types (e.g., Int8Array, Uint16Array, etc.)\n\t\t\tconst view = data as ArrayBufferView;\n\t\t\tbytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);\n\t\t}\n\n\t\t// MurmurHash3_x86_32 algorithm\n\t\tconst c1 = 0xcc9e2d51;\n\t\tconst c2 = 0x1b873593;\n\t\tconst length = bytes.length;\n\t\tconst nblocks = Math.floor(length / 4);\n\n\t\tlet h1 = this._seed;\n\n\t\t// Process 4-byte blocks\n\t\tfor (let i = 0; i < nblocks; i++) {\n\t\t\tconst index = i * 4;\n\t\t\tlet k1 =\n\t\t\t\t(bytes[index] & 0xff) |\n\t\t\t\t((bytes[index + 1] & 0xff) << 8) |\n\t\t\t\t((bytes[index + 2] & 0xff) << 16) |\n\t\t\t\t((bytes[index + 3] & 0xff) << 24);\n\n\t\t\tk1 = this._imul(k1, c1);\n\t\t\tk1 = this._rotl32(k1, 15);\n\t\t\tk1 = this._imul(k1, c2);\n\n\t\t\th1 ^= k1;\n\t\t\th1 = this._rotl32(h1, 13);\n\t\t\th1 = this._imul(h1, 5) + 0xe6546b64;\n\t\t}\n\n\t\t// Process remaining bytes\n\t\tconst tail = nblocks * 4;\n\t\tlet k1 = 0;\n\n\t\tswitch (length & 3) {\n\t\t\tcase 3:\n\t\t\t\tk1 ^= (bytes[tail + 2] & 0xff) << 16;\n\t\t\t// fallthrough\n\t\t\tcase 2:\n\t\t\t\tk1 ^= (bytes[tail + 1] & 0xff) << 8;\n\t\t\t// fallthrough\n\t\t\tcase 1:\n\t\t\t\tk1 ^= bytes[tail] & 0xff;\n\t\t\t\tk1 = this._imul(k1, c1);\n\t\t\t\tk1 = this._rotl32(k1, 15);\n\t\t\t\tk1 = this._imul(k1, c2);\n\t\t\t\th1 ^= k1;\n\t\t}\n\n\t\t// Finalization\n\t\th1 ^= length;\n\n\t\th1 ^= h1 >>> 16;\n\t\th1 = this._imul(h1, 0x85ebca6b);\n\t\th1 ^= h1 >>> 13;\n\t\th1 = this._imul(h1, 0xc2b2ae35);\n\t\th1 ^= h1 >>> 16;\n\n\t\t// Convert to unsigned 32-bit integer\n\t\th1 = h1 >>> 0;\n\n\t\t// Convert to 8-character lowercase hexadecimal string\n\t\tconst hashHex = h1.toString(16).padStart(8, \"0\");\n\n\t\treturn hashHex;\n\t}\n\n\t/**\n\t * Computes the Murmur 32-bit hash of the provided data.\n\t *\n\t * @param data - The data to hash (Uint8Array, ArrayBuffer, or DataView)\n\t * @returns A Promise resolving to an 8-character lowercase hexadecimal string\n\t *\n\t * @example\n\t * ```typescript\n\t * const murmur = new Murmur();\n\t * const data = new TextEncoder().encode('hello');\n\t * const hash = await murmur.toHash(data);\n\t * console.log(hash); // \"248bfa47\"\n\t * ```\n\t */\n\tpublic async toHash(data: BufferSource): Promise<string> {\n\t\treturn this.toHashSync(data);\n\t}\n\n\t/**\n\t * 32-bit integer multiplication with proper overflow handling.\n\t * @private\n\t */\n\tprivate _imul(a: number, b: number): number {\n\t\t// Use Math.imul if available, otherwise fallback to manual implementation\n\t\t/* v8 ignore next -- @preserve */\n\t\tif (Math.imul) {\n\t\t\treturn Math.imul(a, b);\n\t\t}\n\n\t\t// Manual 32-bit multiplication\n\t\t/* v8 ignore next -- @preserve */\n\t\tconst ah = (a >>> 16) & 0xffff;\n\t\t/* v8 ignore next -- @preserve */\n\t\tconst al = a & 0xffff;\n\t\t/* v8 ignore next -- @preserve */\n\t\tconst bh = (b >>> 16) & 0xffff;\n\t\t/* v8 ignore next -- @preserve */\n\t\tconst bl = b & 0xffff;\n\n\t\t/* v8 ignore next -- @preserve */\n\t\treturn ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)) | 0;\n\t}\n\n\t/**\n\t * Left rotate a 32-bit integer.\n\t * @private\n\t */\n\tprivate _rotl32(x: number, r: number): number {\n\t\treturn (x << r) | (x >>> (32 - r));\n\t}\n}\n","import type {\n\tHashProvider,\n\tHashProvidersGetOptions,\n\tHashProvidersOptions,\n} from \"./types.js\";\n\n/**\n * Manages a collection of hash providers for the Hashery system.\n * Provides methods to add, remove, and load multiple hash providers.\n */\nexport class HashProviders {\n\tprivate _providers: Map<string, HashProvider> = new Map();\n\tprivate _getFuzzy = true;\n\n\t/**\n\t * Creates a new HashProviders instance.\n\t * @param options - Optional configuration including initial providers to load\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders({\n\t *   providers: [{ name: 'custom', toHash: async (data) => '...' }]\n\t * });\n\t * ```\n\t */\n\tconstructor(options?: HashProvidersOptions) {\n\t\tif (options?.providers) {\n\t\t\tthis.loadProviders(options?.providers);\n\t\t}\n\n\t\tif (options?.getFuzzy !== undefined) {\n\t\t\tthis._getFuzzy = Boolean(options?.getFuzzy);\n\t\t}\n\t}\n\n\t/**\n\t * Loads multiple hash providers at once.\n\t * Each provider is added to the internal map using its name as the key.\n\t * @param providers - Array of HashProvider objects to load\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders();\n\t * providers.loadProviders([\n\t *   { name: 'md5', toHash: async (data) => '...' },\n\t *   { name: 'sha1', toHash: async (data) => '...' }\n\t * ]);\n\t * ```\n\t */\n\tpublic loadProviders(providers: Array<HashProvider>) {\n\t\tfor (const provider of providers) {\n\t\t\tthis._providers.set(provider.name, provider);\n\t\t}\n\t}\n\n\t/**\n\t * Gets the internal Map of all registered hash providers.\n\t * @returns Map of provider names to HashProvider objects\n\t */\n\tpublic get providers(): Map<string, HashProvider> {\n\t\treturn this._providers;\n\t}\n\n\t/**\n\t * Sets the internal Map of hash providers, replacing all existing providers.\n\t * @param providers - Map of provider names to HashProvider objects\n\t */\n\tpublic set providers(providers: Map<string, HashProvider>) {\n\t\tthis._providers = providers;\n\t}\n\n\t/**\n\t * Gets an array of all provider names.\n\t * @returns Array of provider names\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders();\n\t * providers.add({ name: 'sha256', toHash: async (data) => '...' });\n\t * providers.add({ name: 'md5', toHash: async (data) => '...' });\n\t * console.log(providers.names); // ['sha256', 'md5']\n\t * ```\n\t */\n\tpublic get names(): Array<string> {\n\t\treturn Array.from(this._providers.keys());\n\t}\n\n\t/**\n\t * Gets a hash provider by name with optional fuzzy matching.\n\t *\n\t * Fuzzy matching (enabled by default) attempts to find providers by:\n\t * 1. Exact match (after trimming whitespace)\n\t * 2. Case-insensitive match (lowercase)\n\t * 3. Dash-removed match (e.g., \"SHA-256\" matches \"sha256\")\n\t *\n\t * @param name - The name of the provider to retrieve\n\t * @param options - Optional configuration for the get operation\n\t * @param options.fuzzy - Enable/disable fuzzy matching (overrides constructor setting)\n\t * @returns The HashProvider if found, undefined otherwise\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders();\n\t * providers.add({ name: 'sha256', toHash: async (data) => '...' });\n\t *\n\t * // Exact match\n\t * const provider = providers.get('sha256');\n\t *\n\t * // Fuzzy match (case-insensitive)\n\t * const provider2 = providers.get('SHA256');\n\t *\n\t * // Fuzzy match (with dash)\n\t * const provider3 = providers.get('SHA-256');\n\t *\n\t * // Disable fuzzy matching\n\t * const provider4 = providers.get('SHA256', { fuzzy: false }); // returns undefined\n\t * ```\n\t */\n\tpublic get(\n\t\tname: string,\n\t\toptions?: HashProvidersGetOptions,\n\t): HashProvider | undefined {\n\t\t// set the options\n\t\tconst getFuzzy = options?.fuzzy ?? this._getFuzzy;\n\n\t\t// do the trim\n\t\tname = name.trim();\n\n\t\tlet result = this._providers.get(name);\n\n\t\t// try with lower case\n\t\tif (result === undefined && getFuzzy === true) {\n\t\t\tname = name.toLowerCase();\n\t\t\tresult = this._providers.get(name);\n\t\t}\n\n\t\t// try removing dash\n\t\tif (result === undefined && getFuzzy === true) {\n\t\t\tname = name.replaceAll(\"-\", \"\");\n\t\t\tresult = this._providers.get(name);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Adds a single hash provider to the collection.\n\t * If a provider with the same name already exists, it will be replaced.\n\t * @param provider - The HashProvider object to add\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders();\n\t * providers.add({\n\t *   name: 'custom-hash',\n\t *   toHash: async (data) => {\n\t *     // Custom hashing logic\n\t *     return 'hash-result';\n\t *   }\n\t * });\n\t * ```\n\t */\n\tpublic add(provider: HashProvider): void {\n\t\tthis._providers.set(provider.name, provider);\n\t}\n\n\t/**\n\t * Removes a hash provider from the collection by name.\n\t * @param name - The name of the provider to remove\n\t * @returns true if the provider was found and removed, false otherwise\n\t * @example\n\t * ```ts\n\t * const providers = new HashProviders();\n\t * providers.add({ name: 'custom', toHash: async (data) => '...' });\n\t * const removed = providers.remove('custom'); // returns true\n\t * const removed2 = providers.remove('nonexistent'); // returns false\n\t * ```\n\t */\n\tpublic remove(name: string): boolean {\n\t\treturn this._providers.delete(name);\n\t}\n}\n"],"mappings":"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","names":["Hookified","Cache","options","__publicField","value","key","oldestKey","CRC","data","bytes","view","CRC32_POLYNOMIAL","crc","i","j","WebCrypto","options","__publicField","data","hashBuffer","byte","DJB2","data","bytes","view","hash","i","FNV1","data","bytes","view","FNV_OFFSET_BASIS","FNV_PRIME","hash","i","Murmur","seed","__publicField","data","bytes","view","c1","c2","length","nblocks","h1","i","index","k1","tail","a","b","ah","al","bh","bl","x","r","HashProviders","options","__publicField","providers","provider","name","getFuzzy","result","Hashery","Hookified","options","__publicField","HashProviders","Cache","value","data","context","stringified","cacheKey","cached","cachedHash","result","dataBuffer","provider","WebCrypto","hash","min","max","algorithm","hashLength","hashNumber","range","providers","CRC","DJB2","FNV1","Murmur"]}