{"version":3,"sources":["jsdelivr-header.js","/npm/src/CacheEventEmitter.ts","/npm/src/serialize.ts","/npm/src/utils.ts","/npm/src/Cache.ts","/npm/src/maxArgs.ts","/npm/src/expires.ts","/npm/src/stats.ts","/npm/src/index.ts","/npm/src/forceUpdate.ts"],"names":[],"mappings":"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","file":"/npm/micro-memoize@5.1.0/dist/umd/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/micro-memoize@5.1.0/dist/umd/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","import type { Cache } from './Cache.js';\nimport type { CacheEventListener, CacheEventType, CacheNode } from './internalTypes.js';\n\ntype ListenerMap<Fn extends (...args: any[]) => any> = Partial<\n  Record<string, Set<CacheEventListener<CacheEventType, Fn>>>\n>;\n\nexport class CacheEventEmitter<Fn extends (...args: any[]) => any> {\n  /**\n   * The [c]ache the emitter is associated with.\n   */\n  private c: Cache<Fn>;\n  /**\n   * The list of [l]isteners for the given [t]ype.\n   */\n  private l: ListenerMap<Fn> = {};\n\n  constructor(cache: Cache<Fn>) {\n    this.c = cache;\n  }\n\n  /**\n   * Expose the listeners for testing only.\n   */\n  get listeners(): ListenerMap<Fn> {\n    return this.l;\n  }\n\n  /**\n   * Method to [a]dd a listener for the given cache change event.\n   */\n  a<Type extends CacheEventType>(type: Type, listener: CacheEventListener<Type, Fn>): void {\n    const listeners = this.l[type];\n\n    if (!listeners) {\n      this.l[type] = new Set([listener]);\n    } else if (!listeners.has(listener)) {\n      listeners.add(listener);\n    }\n  }\n\n  /**\n   * Method to [n]otify all listeners for the given cache change event.\n   */\n  n(type: CacheEventType, node: CacheNode<Fn>, reason?: string): void {\n    const listeners = this.l[type];\n\n    if (!listeners) {\n      return;\n    }\n\n    listeners.forEach((listener) => {\n      listener({\n        cache: this.c,\n        key: node.k,\n        reason,\n        value: node.v,\n        type,\n      });\n    });\n  }\n\n  /**\n   * Method to [r]emove a listener for the given cache change event.\n   */\n  r<Type extends CacheEventType>(type: Type, listener: CacheEventListener<Type, Fn>): void {\n    const listeners = this.l[type];\n\n    if (!listeners) {\n      return;\n    }\n\n    listeners.delete(listener);\n\n    if (!listeners.size) {\n      this.l[type] = undefined;\n    }\n  }\n}\n","import { stringify } from 'fast-stringify';\nimport type { Key } from './internalTypes.js';\n\n/**\n * Default replacer used when stringifying to ensure values that would normally be\n * ignored are respected.\n */\nfunction replacer(key: string, value: any) {\n  const type = typeof value;\n\n  return type === 'function' || type === 'symbol' ? value.toString() : value;\n}\n\n/**\n * Default serializer used when `serialize` option set to `true`.\n */\nexport function transformKeySerialized<Fn extends (...args: any[]) => any>(args: Parameters<Fn>) {\n  return [stringify(args, { replacer })];\n}\n\n/**\n * Determines whether the serialized keys are equal to one another.\n */\nexport function isSerializedKeyEqual(prevKey: Key, nextKey: Key) {\n  return prevKey[0] === nextKey[0];\n}\n","import type { Memoized, Options } from './internalTypes.js';\n\n/**\n * Whether the value passed is a memoized function via `micro-memoize`.\n */\nexport function isMemoized<Fn extends (...args: any) => any, Opts extends Options<Fn>>(\n  fn: any,\n): fn is Memoized<Fn, Opts> {\n  return typeof fn === 'function' && fn.isMemoized;\n}\n\n/**\n * Determine whether the value passed is a numeric value for usage in common contexts.\n * This is a positive, finite integer.\n */\nexport function isNumericValueValid(value: any): value is number {\n  return typeof value === 'number' && value >= 0 && Number.isFinite(value);\n}\n","import { deepEqual, shallowEqual } from 'fast-equals';\nimport { CacheEventEmitter } from './CacheEventEmitter.js';\nimport type {\n  CacheEntry,\n  CacheEventType,\n  CacheEventListener,\n  CacheNode,\n  CacheSnapshot,\n  IsKeyItemEqual,\n  Key,\n  Options,\n  IsKeyEqual,\n  TransformKey,\n} from './internalTypes.js';\nimport { getMaxArgsTransformKey } from './maxArgs.js';\nimport { isSerializedKeyEqual, transformKeySerialized } from './serialize.js';\nimport { isNumericValueValid } from './utils.js';\n\nexport class Cache<Fn extends (...args: any[]) => any> {\n  /**\n   * The current [c]ount of entries in the cache.\n   */\n  c = 0;\n  /**\n   * The [h]ead of the cache linked list.\n   */\n  h: CacheNode<Fn> | undefined;\n  /**\n   * Whether the individual argument passed [i]s equal to the same argument in order\n   * for a key in cache.\n   */\n  i: IsKeyItemEqual;\n  /**\n   * The transformer for the [k]ey stored in cache.\n   */\n  k: Options<Fn>['transformKey'] | undefined;\n  /**\n   * Whether the entire key [m]atches an existing key in cache.\n   */\n  m: IsKeyEqual;\n  /**\n   * Event emitter for `[o]`n events.\n   */\n  o: CacheEventEmitter<Fn> | undefined;\n  /**\n   * Whether to await the [p]romise returned by the function.\n   */\n  p: Options<Fn>['async'];\n  /**\n   * The maximum [s]ize of the cache.\n   */\n  s: number;\n  /**\n   * The [t]ail of the cache linked list.\n   */\n  t: CacheNode<Fn> | undefined;\n\n  constructor(options: Options<Fn>) {\n    const { async, isKeyEqual, isKeyItemEqual, maxSize, serialize } = options;\n\n    this.i =\n      typeof isKeyItemEqual === 'function'\n        ? isKeyItemEqual\n        : isKeyItemEqual === 'deep'\n          ? deepEqual\n          : isKeyItemEqual === 'shallow'\n            ? shallowEqual\n            : Object.is;\n    this.m =\n      typeof isKeyEqual === 'function'\n        ? isKeyEqual\n        : serialize\n          ? isSerializedKeyEqual\n          : // eslint-disable-next-line @typescript-eslint/unbound-method\n            this.e;\n\n    this.p = typeof async === 'boolean' && async;\n    this.s = isNumericValueValid(maxSize) ? maxSize : 1;\n\n    this.k = getTransformKey(options);\n  }\n\n  /**\n   * The size of the populated cache.\n   */\n  get size(): number {\n    return this.c;\n  }\n\n  /**\n   * The [key, value] pairs for the existing entries in cache.\n   */\n  get snapshot(): CacheSnapshot<Fn> {\n    const entries: Array<CacheEntry<Fn>> = [];\n    const keys: Key[] = [];\n    const values: Array<ReturnType<Fn>> = [];\n\n    let node = this.h;\n    let size = 0;\n\n    while (node != null) {\n      keys.push(node.k);\n      values.push(node.v);\n      entries.push([node.k, node.v]);\n      ++size;\n\n      node = node.n;\n    }\n\n    return { entries, keys, size, values };\n  }\n\n  /**\n   * Clear the cache.\n   */\n  clear(reason = 'explicit clear'): void {\n    if (!this.h) {\n      return;\n    }\n\n    const emitter = this.o;\n\n    let nodes: Array<CacheNode<Fn>> | undefined;\n\n    if (emitter) {\n      nodes = [];\n\n      let node: CacheNode<Fn> | undefined = this.h;\n\n      while (node != null) {\n        nodes.push(node);\n        node = node.n;\n      }\n    }\n\n    this.h = this.t = undefined;\n    this.c = 0;\n\n    if (emitter && nodes) {\n      for (let index = 0; index < nodes.length; ++index) {\n        emitter.n('delete', nodes[index]!, reason);\n      }\n    }\n  }\n\n  /**\n   * Delete the entry for the given `key` in cache.\n   */\n  delete(key: Parameters<Fn>, reason = 'explicit delete'): boolean {\n    const node = this.k ? this.gt(key) : this.g(key);\n\n    if (node) {\n      this.d(node);\n      this.o && this.o.n('delete', node, reason);\n\n      return true;\n    }\n\n    return false;\n  }\n\n  /**\n   * Get the value in cache based on the given `key`.\n   */\n  get(key: Parameters<Fn>, reason = 'explicit get'): ReturnType<Fn> | undefined {\n    const node = this.k ? this.gt(key) : this.g(key);\n\n    if (node) {\n      if (node !== this.h) {\n        this.u(node);\n\n        this.o && this.o.n('hit', node, reason);\n        this.o && this.o.n('update', node, reason);\n      } else if (this.o) {\n        this.o.n('hit', node, reason);\n      }\n\n      return node.v;\n    }\n  }\n\n  /**\n   * Determine whether the given `key` has a related entry in the cache.\n   */\n  has(key: Parameters<Fn>): boolean {\n    return !!(this.k ? this.gt(key) : this.g(key));\n  }\n\n  /**\n   * Remove the given `listener` for the given `type` of cache event.\n   */\n  off<Type extends CacheEventType>(type: Type, listener: CacheEventListener<Type, Fn>): void {\n    this.o && this.o.r(type, listener);\n  }\n\n  /**\n   * Add the given `listener` for the given `type` of cache event.\n   */\n  on<Type extends CacheEventType>(type: Type, listener: CacheEventListener<Type, Fn>): void {\n    if (!this.o) {\n      this.o = new CacheEventEmitter<Fn>(this);\n    }\n\n    this.o.a(type, listener);\n  }\n\n  /**\n   * Add or update the cache entry for the given `key`.\n   */\n  set(key: Parameters<Fn>, value: ReturnType<Fn>, reason = 'explicit set'): void {\n    const normalizedKey = this.k ? this.k(key) : key;\n\n    let node = this.g(normalizedKey);\n\n    if (node) {\n      const prevValue = node.v;\n\n      node.v = value;\n\n      if (this.p && value !== prevValue) {\n        node.v = this.w(node);\n      }\n\n      node !== this.h && this.u(node);\n\n      this.o && this.o.n('update', node, reason);\n    } else {\n      node = this.n(normalizedKey, value);\n\n      this.o && this.o.n('add', node, reason);\n    }\n  }\n\n  /**\n   * Method to [d]elete the given `node` from the cache.\n   */\n  d(node: CacheNode<Fn>): void {\n    const next = node.n;\n    const prev = node.p;\n\n    if (next) {\n      next.p = prev;\n    } else {\n      this.t = prev;\n    }\n\n    if (prev) {\n      prev.n = next;\n    } else {\n      this.h = next;\n    }\n\n    --this.c;\n\n    node.r = true;\n  }\n\n  /**\n   * Method to determine if the next key is [e]qual to an existing key in cache.\n   */\n  e(prevKey: Key, nextKey: Key): boolean {\n    const length = nextKey.length;\n\n    if (prevKey.length !== length) {\n      return false;\n    }\n\n    if (length === 1) {\n      return this.i(prevKey[0], nextKey[0], 0);\n    }\n\n    for (let index = 0; index < length; ++index) {\n      if (!this.i(prevKey[index], nextKey[index], index)) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  /**\n   * Method to [g]et an existing node from cache based on the given `key`.\n   */\n  g(key: Key): CacheNode<Fn> | undefined {\n    let node = this.h;\n\n    if (!node || node.r) {\n      return;\n    }\n\n    if (this.m(node.k, key)) {\n      return node;\n    }\n\n    if (this.h === this.t) {\n      return;\n    }\n\n    node = node.n;\n\n    while (node) {\n      if (node.r) {\n        return;\n      }\n\n      if (this.m(node.k, key)) {\n        return node;\n      }\n\n      node = node.n;\n    }\n  }\n\n  /**\n   * Method to [g]et an existing node from cache based on the [t]ransformed `key`.\n   */\n  gt(key: Parameters<Fn>): CacheNode<Fn> | undefined {\n    return this.g(this.k ? this.k(key) : key);\n  }\n\n  /**\n   * Method to create a new [n]ode and set it at the head of the linked list.\n   */\n  n(key: Key, value: ReturnType<Fn>): CacheNode<Fn> {\n    const prevHead = this.h;\n    const prevTail = this.t;\n    const node = { k: key, n: prevHead, p: undefined, v: value };\n\n    if (this.p) {\n      node.v = this.w(node);\n    }\n\n    this.h = node;\n\n    if (prevHead) {\n      prevHead.p = node;\n    } else {\n      this.t = node;\n    }\n\n    if (++this.c > this.s && prevTail) {\n      this.d(prevTail);\n      this.o && this.o.n('delete', prevTail, 'evicted');\n    }\n\n    return node;\n  }\n\n  /**\n   * Method to [u]date the location of the given `node` in cache.\n   */\n  u(node: CacheNode<Fn>): void {\n    const next = node.n;\n    const prev = node.p;\n\n    if (next) {\n      next.p = prev;\n    }\n\n    if (prev) {\n      prev.n = next;\n    }\n\n    if (this.h) {\n      this.h.p = node;\n    }\n\n    node.n = this.h;\n    node.p = undefined;\n\n    this.h = node;\n\n    if (node === this.t) {\n      this.t = prev;\n    }\n  }\n\n  /**\n   * Method to [w]rap the promise in a handler to automatically delete the\n   * entry if it rejects.\n   */\n  w(node: CacheNode<Fn>): ReturnType<Fn> {\n    const { v: value } = node;\n\n    // If the method does not return a promise for some reason, just keep the\n    // original value.\n    if (value == null || typeof value.then !== 'function') {\n      return value;\n    }\n\n    return value.then(\n      (value: any) => {\n        if (!node.r && this.o) {\n          this.o.n('update', node, 'resolved');\n        }\n\n        return value;\n      },\n      (error: unknown) => {\n        if (!node.r) {\n          this.d(node);\n          this.o && this.o.n('delete', node, 'rejected');\n        }\n\n        throw error;\n      },\n    );\n  }\n}\n\n/**\n * Get the `transformKey` option based on the options provided.\n */\nexport function getTransformKey<Fn extends (...args: any[]) => any>(\n  options: Options<Fn>,\n): TransformKey<Fn> | undefined {\n  const { maxArgs, serialize, transformKey } = options;\n\n  const transformers: Array<(...args: any[]) => any> = [];\n\n  if (serialize) {\n    const transformer = typeof serialize === 'function' ? serialize : transformKeySerialized;\n\n    transformers.push(transformer);\n  }\n\n  if (isNumericValueValid(maxArgs)) {\n    const transformer = getMaxArgsTransformKey(maxArgs);\n\n    if (transformer) {\n      transformers.push(transformer);\n    }\n  }\n\n  if (typeof transformKey === 'function') {\n    transformers.push(transformKey);\n  }\n\n  return transformers.length\n    ? transformers.reduce(\n        (f, g) =>\n          (...args) =>\n            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n            f(g(...args)),\n      )\n    : undefined;\n}\n","import type { Key, TransformKey } from './internalTypes.js';\n\n/**\n * Create a method that takes the first N number of items from the array (faster than slice).\n */\nexport function getMaxArgsTransformKey<Fn extends (...args: any[]) => any>(\n  maxArgs: number,\n): TransformKey<Fn> | undefined {\n  if (maxArgs === 1) {\n    return (args: Key) => (maxArgs >= args.length ? args : [args[0]]);\n  }\n\n  if (maxArgs === 2) {\n    return (args: Key) => (maxArgs >= args.length ? args : [args[0], args[1]]);\n  }\n\n  return (args: Key) => {\n    if (maxArgs >= args.length) {\n      return args;\n    }\n\n    const clone = new Array(maxArgs);\n\n    for (let index = 0; index < maxArgs; ++index) {\n      clone[index] = args[index];\n    }\n\n    return clone;\n  };\n}\n","import type { Cache } from './Cache.js';\nimport type {\n  CacheEventListener,\n  GetExpires,\n  Key,\n  Options,\n  ShouldPersist,\n  ShouldRemoveOnExpire,\n} from './internalTypes.js';\nimport { isNumericValueValid } from './utils.js';\n\nexport class ExpirationManager<Fn extends (...args: any[]) => any> {\n  /**\n   * The [c]ache being monitored.\n   */\n  c: Cache<Fn>;\n  /**\n   * Map of [e]xpiration timeouts.\n   */\n  e = new Map<Key, ReturnType<typeof setTimeout>>();\n  /**\n   * Whether the entry in cache should [p]ersist, and therefore not\n   * have any expiration.\n   */\n  p: ShouldPersist<Fn> | undefined;\n  /**\n   * Whether the entry in cache should be [r]emoved on expiration.\n   */\n  r: ShouldRemoveOnExpire<Fn> | undefined;\n  /**\n   * The [t]ime to wait before expiring, or a method that determines that time.\n   */\n  t: number | GetExpires<Fn>;\n  /**\n   * Whether the expiration should [u]pdate when the cache entry is hit.\n   */\n  u: boolean;\n\n  constructor(cache: Cache<Fn>, expires: Required<Options<Fn>>['expires']) {\n    this.c = cache;\n\n    if (typeof expires === 'object') {\n      this.t = expires.after;\n      this.p = expires.shouldPersist;\n      this.r = expires.shouldRemove;\n      this.u = !!expires.update;\n    } else {\n      this.t = expires;\n      this.u = false;\n    }\n\n    this.c.on('add', ({ key, value }) => {\n      this.a(key, value) && this.s(key, value);\n    });\n\n    if (this.u) {\n      // Set up a `hit` listener if we care about updating the expiration.\n      this.c.on('hit', ({ key, value }) => {\n        this.a(key, value) && this.s(key, value);\n      });\n\n      if (this.c.p) {\n        const onResolved: CacheEventListener<'update', Fn> = ({ key, reason, value }) => {\n          if (reason === 'resolved' && this.a(key, value)) {\n            this.s(key, value);\n            // Automatically remove the listener to avoid unnecessary work on updates after\n            // the item is resolved, as that can only ever happen once.\n            this.c.off('update', onResolved);\n          }\n        };\n\n        // If the method is also async, then when the value resolved update the expiration cache.\n        this.c.on('update', onResolved);\n      }\n    }\n\n    this.c.on('delete', ({ key }) => {\n      this.e.has(key) && this.d(key);\n    });\n  }\n\n  get size(): number {\n    return this.e.size;\n  }\n\n  /**\n   * Whether the cache expiration should be set [a]gain, generally after some cache change.\n   */\n  a(key: Key, value: ReturnType<Fn>): boolean {\n    return !!(this.c.g(key) && !this.p?.(key, value, this.c));\n  }\n\n  /**\n   * Method to [d]elete the expiration.\n   */\n  d(key: Key): void {\n    const expiration = this.e.get(key);\n\n    if (expiration) {\n      clearTimeout(expiration);\n      this.e.delete(key);\n    }\n  }\n\n  /**\n   * Method to [s]et the new expiration. If one is present for the given `key`, it will delete\n   * the existing expiration before creating the new one.\n   */\n  s(key: Key, value: ReturnType<Fn>): void {\n    if (this.e.has(key)) {\n      this.d(key);\n    }\n\n    const cache = this.c;\n    const time = typeof this.t === 'function' ? this.t(key, value, cache) : this.t;\n\n    if (!isNumericValueValid(time)) {\n      throw new TypeError(`The expiration time must be a finite, non-negative number; received ${time as string}`);\n    }\n\n    const timeout = setTimeout(() => {\n      this.d(key);\n\n      const node = cache.g(key);\n\n      if (!node) {\n        return;\n      }\n\n      if (typeof this.r === 'function' && !this.r(key, node.v, time, cache)) {\n        node !== cache.h && cache.u(node);\n        cache.o && cache.o.n('update', node, 'expiration reset');\n\n        this.s(key, node.v);\n      } else {\n        cache.d(node);\n        cache.o && cache.o.n('delete', node, 'expired');\n      }\n    }, time);\n\n    if (typeof timeout.unref === 'function') {\n      // If done in NodeJS, the timeout should have its reference removed to avoid\n      // hanging timers if collected while running.\n      timeout.unref();\n    }\n\n    this.e.set(key, timeout);\n  }\n}\n\nexport function getExpirationManager<Fn extends (...args: any[]) => any>(\n  cache: Cache<Fn>,\n  options: Options<Fn>,\n): ExpirationManager<Fn> | undefined {\n  if (options.expires != null) {\n    return new ExpirationManager(cache, options.expires);\n  }\n}\n","import { Cache } from './Cache.js';\nimport type { GlobalStats, Options, ProfileStats } from './internalTypes.js';\n\ninterface ProfileCounts {\n  c: number;\n  h: number;\n}\n\nconst nameToProfile = new Map<string, StatsManager<any>>();\n\nlet active = false;\n\nexport class StatsManager<Fn extends (...args: any[]) => any> {\n  /**\n   * The [c]ache listened to when collecting counts.\n   */\n  c: Cache<Fn>;\n  /**\n   * Method to [d]elete existing cache listeners.\n   */\n  d: (() => void) | undefined;\n  /**\n   * The [n]ame of the profile to manage in stats.\n   */\n  n: string;\n  /**\n   * The counts for the stats [p]rofile.\n   */\n  p: ProfileCounts = { c: 0, h: 0 };\n\n  constructor(cache: Cache<Fn>, statsName: string) {\n    this.c = cache;\n    this.n = statsName;\n\n    nameToProfile.set(statsName, this);\n\n    if (active) {\n      this.s();\n    }\n  }\n\n  /**\n   * Method to compute the [m]etrics for the profile stats.\n   */\n  m(): ProfileStats {\n    const { c: calls, h: hits } = this.p;\n    const usage = calls ? `${((hits / calls) * 100).toFixed(4)}%` : '0.0000%';\n\n    return { calls, hits, name: this.n, usage };\n  }\n\n  /**\n   * Method to [r]eset the counts.\n   */\n  r() {\n    this.p = { c: 0, h: 0 };\n  }\n\n  /**\n   * Method to [s]tart the collection of stats for the given profile.\n   */\n  s() {\n    const onAdd = () => {\n      ++this.p.c;\n    };\n    const onHit = () => {\n      ++this.p.c;\n      ++this.p.h;\n    };\n\n    this.d = () => {\n      this.c.off('add', onAdd);\n      this.c.off('hit', onHit);\n\n      this.d = undefined;\n\n      this.p.c = this.p.h = 0;\n    };\n\n    this.c.on('add', onAdd);\n    this.c.on('hit', onHit);\n  }\n}\n\n/**\n * Clear all existing stats stored, either of the specific profile whose name is passed,\n * or globally if no name is passed.\n */\nexport function clearStats(statsName?: string) {\n  if (!active) {\n    return;\n  }\n\n  if (statsName) {\n    const statsManager = nameToProfile.get(statsName);\n\n    if (statsManager) {\n      statsManager.r();\n    }\n  } else {\n    nameToProfile.clear();\n  }\n}\n\n/**\n * Get the stats of a given profile, or global stats if no `statsName` is given.\n */\nexport function getStats<Name extends string | undefined>(\n  statsName?: Name,\n): undefined extends Name ? GlobalStats | undefined : ProfileStats | undefined {\n  if (!active) {\n    console.warn('Stats are not being collected; please run \"startCollectingStats()\" to collect them.');\n    return;\n  }\n\n  if (statsName != null) {\n    const statsManager = nameToProfile.get(statsName);\n\n    const profileStats: ProfileStats = statsManager?.p.c\n      ? statsManager.m()\n      : {\n          calls: 0,\n          hits: 0,\n          name: statsName,\n          usage: getUsagePercentage(0, 0),\n        };\n    // @ts-expect-error - Conditional returns can be tricky.\n    return profileStats;\n  }\n\n  let calls = 0;\n  let hits = 0;\n\n  const profiles: Record<string, ProfileStats> = {};\n\n  nameToProfile.forEach((profile, statsName) => {\n    profiles[statsName] = profile.m();\n\n    calls += profile.p.c;\n    hits += profile.p.h;\n  });\n\n  const globalStats: GlobalStats = {\n    calls,\n    hits,\n    profiles,\n    usage: getUsagePercentage(calls, hits),\n  };\n\n  // @ts-expect-error - Conditional returns can be tricky.\n  return globalStats;\n}\n\n/**\n * Get the stats manager for the given moized function.\n */\nexport function getStatsManager<Fn extends (...args: any[]) => any>(\n  cache: Cache<Fn>,\n  options: Options<Fn>,\n): StatsManager<Fn> | undefined {\n  if (options.statsName) {\n    return new StatsManager(cache, options.statsName);\n  }\n}\n\n/**\n * Get the usage percentage based on the number of hits and total calls.\n */\nfunction getUsagePercentage(calls: number, hits: number) {\n  return calls ? `${((hits / calls) * 100).toFixed(4)}%` : '0.0000%';\n}\n\n/**\n * Whether stats are currently being collected.\n */\nexport function isCollectingStats(): boolean {\n  return active;\n}\n\n/**\n * Start collecting stats.\n */\nexport function startCollectingStats(): void {\n  if (!active) {\n    active = true;\n\n    nameToProfile.forEach((profile) => {\n      profile.s();\n    });\n  }\n}\n\n/**\n * Stop collecting stats.\n */\nexport function stopCollectingStats(): void {\n  if (active) {\n    nameToProfile.forEach((profile) => {\n      profile.d?.();\n    });\n\n    active = false;\n  }\n}\n","import { Cache } from './Cache.js';\nimport { getExpirationManager } from './expires.js';\nimport { getWrappedForceUpdateMoize } from './forceUpdate.js';\nimport type { Key, Memoize, Memoized, Options } from './internalTypes.js';\nimport { getStatsManager } from './stats.js';\nimport { isMemoized } from './utils.js';\n\nexport type * from './internalTypes.js';\n\nexport const memoize: Memoize = function memoize<Fn extends (...args: any[]) => any, Opts extends Options<Fn>>(\n  fn: Fn | Memoized<Fn, Opts>,\n  options: Opts = {} as Opts,\n): Memoized<Fn, Opts> {\n  if (isMemoized(fn)) {\n    return memoize(fn.fn, Object.assign({}, fn.options, options));\n  }\n\n  if (typeof fn !== 'function') {\n    throw new TypeError(`Expected first parameter to be function; received ${typeof fn}`);\n  }\n\n  const cache = new Cache(options);\n\n  const memoized = function memoized(this: any, ...args: Parameters<Fn>) {\n    const key: Key = cache.k ? cache.k(args) : args;\n\n    let node = cache.g(key);\n\n    if (!node) {\n      node = cache.n(key, fn.apply(this, args) as ReturnType<Fn>);\n\n      cache.o && cache.o.n('add', node);\n    } else if (node !== cache.h) {\n      cache.u(node);\n\n      if (cache.o) {\n        cache.o.n('hit', node);\n        cache.o.n('update', node);\n      }\n    } else if (cache.o) {\n      cache.o.n('hit', node);\n    }\n\n    return node.v;\n  } as Memoized<Fn, Opts>;\n\n  memoized.cache = cache;\n  memoized.expirationManager = getExpirationManager(cache, options);\n  memoized.fn = fn;\n  memoized.isMemoized = true;\n  memoized.options = options;\n  memoized.statsManager = getStatsManager(cache, options);\n\n  return typeof options.forceUpdate === 'function'\n    ? getWrappedForceUpdateMoize(memoized, options.forceUpdate)\n    : memoized;\n};\n\nexport { clearStats, isCollectingStats, getStats, startCollectingStats, stopCollectingStats } from './stats.js';\n","import type { ForceUpdate, Memoized, Options } from './internalTypes.js';\n\n/**\n * Create a wrapped memoized method that will conditionally update the cache based on\n * the result of the option passed.\n */\nexport function getWrappedForceUpdateMoize<Fn extends (...args: any[]) => any, Opts extends Options<Fn>>(\n  memoized: Memoized<Fn, Opts>,\n  forceUpdate: ForceUpdate<Fn>,\n): Memoized<Fn, Opts> {\n  const { cache } = memoized;\n\n  return Object.assign(function (this: any, ...args: Parameters<Fn>) {\n    if (!forceUpdate(args) || !cache.has(args)) {\n      return memoized.apply(this, args);\n    }\n\n    const value = memoized.fn.apply(this, args) as ReturnType<Fn>;\n\n    memoized.cache.set(args, value, 'forced');\n\n    return value;\n  }, memoized) as Memoized<Fn, Opts>;\n}\n"]}