{"version":3,"sources":["../src/index.ts","../src/primary.ts","../src/messages.ts","../src/worker.ts","../src/l1.ts","../src/memoize.ts","../src/codec.ts"],"sourcesContent":["import cluster from 'node:cluster';\nimport { EventEmitter } from 'node:events';\nimport { LRUCache } from 'lru-cache';\nimport {\n  caches,\n  dispatchAndBroadcast,\n  getOrCreateCache,\n  getNamespaceVersion,\n  installClusterListener,\n  type ExecPayload,\n} from './primary.js';\nimport { getDefaultClient } from './worker.js';\nimport { SOURCE, type InvalidationPush, type SerializableLruOptions, type Stats } from './messages.js';\nimport { LocalL1Cache, encodeL1Key, type L1Stats } from './l1.js';\n\nif (cluster.isPrimary) installClusterListener();\n\nconst FETCH_POLL_MS = 5;\n\n// lru-cache@11 constrains generic K and V to non-nullish; mirror that locally\n// so the registry's stored type lines up with the public getCache() return.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype NonNullish = {};\n\ntype FetchClaimResult<T> = { kind: 'value'; value: T } | { kind: 'leader'; token: string } | { kind: 'follower' };\n\nexport interface WriteOptions {\n  ttl?: number;\n  size?: number;\n  updateL1?: boolean;\n}\n\nexport interface ReadOptions {\n  bypassL1?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport type MSetEntry<K extends {}, V extends {}> = [K, V] | [K, V, WriteOptions];\n\nexport interface FetchOptions extends WriteOptions {\n  forceRefresh?: boolean;\n  bypassL1?: boolean;\n}\n\nexport type LocalL1Options = {\n  enabled?: boolean;\n  max?: number;\n  maxSize?: number;\n  ttl?: number;\n  updateAgeOnGet?: boolean;\n  allowStale?: boolean;\n  cacheUndefined?: boolean;\n  invalidation?: 'broadcast' | 'ttl-only';\n  methods?: {\n    get?: boolean;\n    has?: boolean;\n    fetch?: boolean;\n  };\n  experimental?: boolean;\n};\n\nexport interface LRUCacheClusterOptions extends SerializableLruOptions {\n  namespace?: string;\n  timeout?: number;\n  failsafe?: 'resolve' | 'reject';\n  localL1?: false | LocalL1Options;\n}\n\ninterface InternalOptions {\n  noInit?: boolean;\n}\n\nconst DEFAULT_L1_TTL_MS = 5_000;\nconst DEFAULT_L1_MAX = 1_000;\n\ntype NormalizedL1 = {\n  max: number;\n  maxSize?: number;\n  ttl: number;\n  updateAgeOnGet: boolean;\n  allowStale: boolean;\n  cacheUndefined: boolean;\n  invalidation: 'broadcast' | 'ttl-only';\n  methods: { get: boolean; has: boolean; fetch: boolean };\n};\n\ntype L1InvalidationHandler = (msg: InvalidationPush) => void;\n\nconst localInvalidationSubscribers = new Map<string, Set<L1InvalidationHandler>>();\nconst LOCAL_BULK_INVALIDATION_OPS = new Set([\n  'destroy',\n  'clear',\n  'purgeStale',\n  'mSet',\n  'mDelete',\n  'load',\n  'max',\n  'ttl',\n]);\n\nfunction subscribeLocalInvalidations(namespace: string, handler: L1InvalidationHandler): () => void {\n  let set = localInvalidationSubscribers.get(namespace);\n  if (!set) {\n    set = new Set();\n    localInvalidationSubscribers.set(namespace, set);\n  }\n  set.add(handler);\n  return () => {\n    const current = localInvalidationSubscribers.get(namespace);\n    /* c8 ignore next -- unsubscribe closures are nulled after use; this only protects stale internal closures. */\n    if (!current) return;\n    current.delete(handler);\n    if (current.size === 0) localInvalidationSubscribers.delete(namespace);\n  };\n}\n\nfunction emitLocalInvalidation(msg: InvalidationPush, exclude?: L1InvalidationHandler): void {\n  const set = localInvalidationSubscribers.get(msg.namespace);\n  if (!set) return;\n  for (const handler of set) {\n    if (handler !== exclude) handler(msg);\n  }\n}\n\nfunction shouldEmitLocalInvalidation(payload: ExecPayload, value: unknown): boolean {\n  switch (payload.op) {\n    case 'set':\n    case 'mSet':\n    case 'mDelete':\n    case 'clear':\n    case 'load':\n    case 'incr':\n    case 'decr':\n      return true;\n    case 'delete':\n    case 'setIfAbsent':\n    case 'purgeStale':\n    case 'fetchStore':\n    case 'destroy':\n      return value === true;\n    case 'max':\n    case 'ttl':\n      return typeof payload.value === 'number';\n    default:\n      return false;\n  }\n}\n\nfunction buildLocalInvalidation(\n  namespace: string,\n  payload: ExecPayload,\n  version: number,\n  value: unknown,\n): InvalidationPush | undefined {\n  if (!shouldEmitLocalInvalidation(payload, value)) return undefined;\n  if (LOCAL_BULK_INVALIDATION_OPS.has(payload.op)) {\n    return { source: SOURCE, push: 'l1:invalidate-namespace', namespace, version };\n  }\n  const key = (payload as { key?: unknown }).key;\n  /* c8 ignore next -- all current local single-key invalidations validate a non-nullish key before this point. */\n  if (key === undefined || key === null) return undefined;\n  return { source: SOURCE, push: 'l1:invalidate', namespace, key, version };\n}\n\nfunction normalizeL1(\n  raw: false | LocalL1Options | undefined,\n  primary: SerializableLruOptions,\n): NormalizedL1 | undefined {\n  if (raw === undefined || raw === false) return undefined;\n  const opts: LocalL1Options = raw;\n  if (opts.enabled === false) return undefined;\n  if (!opts.experimental) {\n    throw new Error(\n      'localL1 is experimental in v2.1.0. Pass `localL1: { enabled: true, experimental: true }` to opt in.',\n    );\n  }\n\n  // Default L1 ttl: min(primaryTtl * 0.1, 5000), with 100ms floor.\n  // If primary ttl is unset, default to 5000.\n  // Hard cap: L1 ttl cannot exceed primary ttl.\n  const requestedTtl = opts.ttl ?? Math.min((primary.ttl ?? Infinity) * 0.1, DEFAULT_L1_TTL_MS);\n  const cappedTtl = primary.ttl !== undefined ? Math.min(requestedTtl, primary.ttl) : requestedTtl;\n  const ttl = Math.max(100, Math.floor(cappedTtl));\n\n  const methods =\n    opts.methods === undefined\n      ? { get: true, has: true, fetch: true }\n      : {\n          get: opts.methods.get === true,\n          has: opts.methods.has === true,\n          fetch: opts.methods.fetch === true,\n        };\n\n  return {\n    max: opts.max ?? DEFAULT_L1_MAX,\n    maxSize: opts.maxSize,\n    ttl,\n    updateAgeOnGet: opts.updateAgeOnGet ?? true,\n    allowStale: opts.allowStale ?? false,\n    cacheUndefined: false, // forced false for v1; spec section 6.2\n    invalidation: opts.invalidation ?? 'broadcast',\n    methods,\n  };\n}\n\nfunction encodeL1KeyOrUndefined(key: unknown): string | undefined {\n  if (key === undefined || key === null) return undefined;\n  try {\n    return encodeL1Key(key);\n  } catch {\n    return undefined;\n  }\n}\n\n// K and V are constrained to non-nullish to mirror lru-cache@11's own signature\n// (`class LRUCache<K extends {}, V extends {}>`), since the primary enforces\n// non-nullish at runtime via requireNonNullish(). Without the constraint, a\n// caller could write `cache.set(undefined, ...)` and TypeScript would accept it\n// only to fail at the IPC boundary. The {} default for V mirrors lru-cache's\n// own default and means \"any non-nullish value\".\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport class LRUCacheClustered<K extends {} = string, V extends {} = {}> {\n  readonly namespace: string;\n  readonly timeout: number;\n  readonly failsafe: 'resolve' | 'reject';\n  readonly ready: Promise<void>;\n  #lruOptions: SerializableLruOptions;\n  // Per-instance in-flight dedup for fetch(). Concurrent callers within the\n  // same instance piggyback locally before the primary-side single-flight lock\n  // engages across instances and workers.\n  readonly #inFlight = new Map<K, { promise: Promise<V> }>();\n  readonly #emitter = new EventEmitter();\n  readonly #l1?: LocalL1Cache<V & NonNullish>;\n  readonly #l1Methods: { get: boolean; has: boolean; fetch: boolean };\n  readonly #l1Invalidation: 'broadcast' | 'ttl-only';\n  // eslint-disable-next-line no-unused-private-class-members\n  readonly #l1CacheUndefined: boolean;\n  #l1InvalidationHandler?: L1InvalidationHandler;\n  #unsubscribeL1?: () => void;\n\n  constructor(options: LRUCacheClusterOptions & InternalOptions = {}) {\n    this.namespace = options.namespace ?? 'default';\n    this.timeout = options.timeout ?? 100;\n    this.failsafe = options.failsafe === 'reject' ? 'reject' : 'resolve';\n    const { namespace: _n, timeout: _t, failsafe: _f, noInit: _ni, localL1: _l1, ...lruOpts } = options;\n    void _n;\n    void _t;\n    void _f;\n    void _ni;\n    void _l1;\n    this.#lruOptions = lruOpts;\n\n    const l1Config = normalizeL1(options.localL1, lruOpts);\n    this.#l1Methods = l1Config?.methods ?? { get: false, has: false, fetch: false };\n    this.#l1Invalidation = l1Config?.invalidation ?? 'broadcast';\n    this.#l1CacheUndefined = l1Config?.cacheUndefined ?? false;\n    if (l1Config) {\n      this.#l1 = new LocalL1Cache<V & NonNullish>({\n        max: l1Config.max,\n        maxSize: l1Config.maxSize,\n        ttl: l1Config.ttl,\n        updateAgeOnGet: l1Config.updateAgeOnGet,\n        allowStale: l1Config.allowStale,\n        emit: (event, payload) => {\n          this.#emitter.emit(`l1:${event}`, { namespace: this.namespace, ...payload });\n        },\n      });\n    }\n\n    if (cluster.isPrimary) {\n      getOrCreateCache(this.namespace, this.#lruOptions);\n      if (this.#l1) {\n        this.#l1.advanceLatestSeen(getNamespaceVersion(this.namespace));\n        this.#installL1Subscription();\n      }\n      this.ready = Promise.resolve(undefined);\n    } else if (!options.noInit) {\n      // Swallow rejection so consumers can `await cache.ready` purely for\n      // ordering without unhandled-rejection noise.\n      this.ready = this.#dispatchWithMeta<{ namespace: string; isNew: boolean; max: number; version: number }>(\n        { op: 'init', options: this.#lruOptions },\n        'reject',\n      ).then(\n        (r) => {\n          if (this.#l1) {\n            this.#l1.advanceLatestSeen(r.value.version);\n            this.#installL1Subscription();\n          }\n        },\n        () => undefined,\n      );\n    } else {\n      this.ready = Promise.resolve(undefined);\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n  static async getInstance<K extends {} = string, V extends {} = {}>(\n    options: LRUCacheClusterOptions = {},\n  ): Promise<LRUCacheClustered<K, V>> {\n    const instance = new LRUCacheClustered<K, V>({\n      ...options,\n      noInit: true,\n    });\n    if (cluster.isWorker) {\n      const r = await instance.#dispatchWithMeta<{ namespace: string; isNew: boolean; max: number; version: number }>(\n        { op: 'init', options: instance.#lruOptions },\n        'reject',\n      );\n      if (instance.#l1) {\n        instance.#l1.advanceLatestSeen(r.value.version);\n        instance.#installL1Subscription();\n      }\n    }\n    return instance;\n  }\n\n  static bootstrap(): void {\n    if (cluster.isPrimary) installClusterListener();\n  }\n\n  static getAllCaches(): Map<string, LRUCache<NonNullish, NonNullish>> {\n    if (cluster.isWorker) {\n      throw new Error('LRUCacheClustered.getAllCaches() must not be called from a worker');\n    }\n    return caches;\n  }\n\n  getCache(): LRUCache<K & NonNullish, V & NonNullish> | undefined {\n    if (cluster.isWorker) {\n      throw new Error('LRUCacheClustered.getCache() must not be called from a worker');\n    }\n    return caches.get(this.namespace) as LRUCache<K & NonNullish, V & NonNullish> | undefined;\n  }\n\n  // Per-method API:\n  async get(key: K, opts?: ReadOptions): Promise<V | undefined> {\n    const useL1 = this.#l1 && this.#l1Methods.get && !opts?.bypassL1;\n    if (useL1) {\n      const hit = this.#getLocal(key);\n      if (hit !== undefined) return hit;\n    }\n    const r = await this.#dispatchWithMeta<V | undefined>({ op: 'get', key }, this.failsafe);\n    if (useL1 && r.value !== undefined) await this.#setLocalFromPrimary(key, r.value, r.version);\n    return r.value;\n  }\n  async set(key: K, value: V, opts?: WriteOptions): Promise<boolean> {\n    this.#deleteLocal(key);\n    const r = await this.#dispatchWithMeta<boolean>(\n      { op: 'set', key, value, ttl: opts?.ttl, size: opts?.size },\n      this.failsafe,\n    );\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    if (this.#l1 && opts?.updateL1 && r.value === true) {\n      await this.#setLocalFromPrimary(key, value, r.version);\n    }\n    return r.value;\n  }\n  async delete(key: K): Promise<boolean> {\n    this.#deleteLocal(key);\n    const r = await this.#dispatchWithMeta<boolean>({ op: 'delete', key }, this.failsafe);\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async has(key: K, opts?: ReadOptions): Promise<boolean> {\n    const useL1 = this.#l1 && this.#l1Methods.has && !opts?.bypassL1;\n    if (useL1) {\n      const hit = this.#getLocal(key);\n      if (hit !== undefined) return true;\n    }\n    const r = await this.#dispatchWithMeta<boolean>({ op: 'has', key }, this.failsafe);\n    return r.value;\n  }\n  async peek(key: K, opts?: ReadOptions): Promise<V | undefined> {\n    const useL1 = this.#l1 && this.#l1Methods.get && !opts?.bypassL1;\n    if (useL1) {\n      const hit = this.#getLocal(key);\n      if (hit !== undefined) return hit;\n    }\n    const r = await this.#dispatchWithMeta<V | undefined>({ op: 'peek', key }, this.failsafe);\n    if (useL1 && r.value !== undefined) await this.#setLocalFromPrimary(key, r.value, r.version);\n    return r.value;\n  }\n  async clear(): Promise<void> {\n    this.#l1?.clear();\n    const r = await this.#dispatchWithMeta<void>({ op: 'clear' }, this.failsafe);\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async purgeStale(): Promise<boolean> {\n    this.#l1?.clear();\n    const r = await this.#dispatchWithMeta<boolean>({ op: 'purgeStale' }, this.failsafe);\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n\n  async mGet(keys: K[], opts?: ReadOptions): Promise<Map<K, V | undefined>> {\n    const values = new Map<K, V | undefined>();\n    const useL1 = this.#l1 && this.#l1Methods.get && !opts?.bypassL1;\n    const remainingKeys: K[] = [];\n    if (useL1) {\n      for (const k of keys) {\n        const hit = this.#getLocal(k);\n        if (hit !== undefined) values.set(k, hit);\n        else remainingKeys.push(k);\n      }\n    } else {\n      remainingKeys.push(...keys);\n    }\n    if (remainingKeys.length === 0) {\n      const out = new Map<K, V | undefined>();\n      for (const k of keys) {\n        if (values.has(k)) out.set(k, values.get(k));\n      }\n      return out;\n    }\n\n    const r = await this.#dispatchWithMeta<Array<[K, V | undefined]> | undefined>(\n      { op: 'mGet', keys: remainingKeys },\n      this.failsafe,\n    );\n    // Default cluster IPC uses JSON serialization, which rewrites\n    // `undefined` inside arrays to `null`. Cache values are non-nullish, so\n    // a null on this wire can only mean \"the primary returned undefined for\n    // a missing key\". Normalize so the public Map<K, V | undefined> contract\n    // holds in both primary and worker mode. The `?? []` covers the\n    // failsafe='resolve' + IPC timeout case where dispatch resolves to\n    // undefined; matches the previous `new Map(undefined)` empty-Map result.\n    const l1Populates: Array<Promise<void>> = [];\n    for (const [k, v] of r.value ?? []) {\n      const value = v === null ? undefined : v;\n      values.set(k, value);\n      if (useL1 && value !== undefined) {\n        l1Populates.push(this.#setLocalFromPrimary(k, value, r.version));\n      }\n    }\n    await Promise.all(l1Populates);\n    const out = new Map<K, V | undefined>();\n    for (const k of keys) {\n      if (values.has(k)) out.set(k, values.get(k));\n    }\n    return out;\n  }\n  async mSet(entries: Iterable<MSetEntry<K, V>>, opts?: WriteOptions): Promise<void> {\n    this.#l1?.clear();\n    const arr = [...entries].map((entry) =>\n      entry.length === 3\n        ? ([entry[0], entry[1], entry[2]] as [unknown, unknown, WriteOptions])\n        : ([entry[0], entry[1]] as [unknown, unknown]),\n    );\n    const r = await this.#dispatchWithMeta<void>(\n      { op: 'mSet', entries: arr, ttl: opts?.ttl, size: opts?.size },\n      this.failsafe,\n    );\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async mDelete(keys: K[]): Promise<void> {\n    this.#l1?.clear();\n    const r = await this.#dispatchWithMeta<void>({ op: 'mDelete', keys }, this.failsafe);\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n\n  keys() {\n    return this.#dispatch<K[]>({ op: 'keys' });\n  }\n  values() {\n    return this.#dispatch<V[]>({ op: 'values' });\n  }\n  entries() {\n    return this.#dispatch<Array<[K, V]>>({ op: 'entries' });\n  }\n  dump() {\n    return this.#dispatch<Array<[K, LRUCache.Entry<V>]>>({ op: 'dump' });\n  }\n  size() {\n    return this.#dispatch<number>({ op: 'size' });\n  }\n\n  async incr(key: K, amount?: number, opts?: WriteOptions): Promise<number> {\n    this.#deleteLocal(key);\n    const r = await this.#dispatchWithMeta<number>(\n      { op: 'incr', key, amount, ttl: opts?.ttl, size: opts?.size },\n      this.failsafe,\n    );\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async decr(key: K, amount?: number, opts?: WriteOptions): Promise<number> {\n    this.#deleteLocal(key);\n    const r = await this.#dispatchWithMeta<number>(\n      { op: 'decr', key, amount, ttl: opts?.ttl, size: opts?.size },\n      this.failsafe,\n    );\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n\n  async allowStale(value?: boolean) {\n    const next = await this.#dispatch<boolean>({ op: 'allowStale', value });\n    this.#lruOptions.allowStale = next;\n    return next;\n  }\n  async max(value?: number) {\n    const next = await this.#dispatch<number>({ op: 'max', value });\n    this.#lruOptions.max = next;\n    if (value !== undefined) this.#l1?.clear();\n    return next;\n  }\n  async ttl(value?: number) {\n    const next = await this.#dispatch<number>({ op: 'ttl', value });\n    this.#lruOptions.ttl = next;\n    if (value !== undefined) this.#l1?.clear();\n    return next;\n  }\n\n  async getRemainingTTL(key: K): Promise<number> {\n    // Default cluster IPC uses JSON serialization, which rewrites `Infinity`\n    // (lru-cache@11's \"no TTL\" sentinel) to `null`. Missing keys return 0,\n    // and any active entry returns a positive number, so a null on this wire\n    // can only mean Infinity. Normalize so the public Promise<number>\n    // contract holds in both primary and worker mode. Strict `=== null` so\n    // failsafe='resolve' timeouts (which dispatch undefined) still propagate\n    // as undefined, matching the pattern for every other op under that mode.\n    const ttl = await this.#dispatch<number | null>({ op: 'getRemainingTTL', key });\n    return ttl === null ? Infinity : ttl;\n  }\n  async setIfAbsent(key: K, value: V, opts?: WriteOptions): Promise<boolean> {\n    this.#deleteLocal(key);\n    const r = await this.#dispatchWithMeta<boolean>(\n      { op: 'setIfAbsent', key, value, ttl: opts?.ttl, size: opts?.size },\n      this.failsafe,\n    );\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async load(entries: Array<[K, LRUCache.Entry<V>]>): Promise<void> {\n    this.#l1?.clear();\n    const r = await this.#dispatchWithMeta<void>({ op: 'load', entries }, this.failsafe);\n    if (this.#l1) this.#l1.advanceLatestSeen(r.version);\n    return r.value;\n  }\n  async destroy(): Promise<boolean> {\n    this.#inFlight.clear();\n    this.#unsubscribeL1?.();\n    this.#unsubscribeL1 = undefined;\n    this.#l1?.destroy();\n    return this.#dispatch<boolean>({ op: 'destroy' });\n  }\n  healthCheck() {\n    return this.#dispatchRequired<void>({ op: 'healthCheck' });\n  }\n  stats() {\n    return this.#dispatch<Stats>({ op: 'stats' });\n  }\n\n  localStats(): L1Stats | undefined {\n    return this.#l1?.stats();\n  }\n\n  on(event: string, listener: (...args: unknown[]) => void): this {\n    this.#emitter.on(event, listener);\n    return this;\n  }\n\n  off(event: string, listener: (...args: unknown[]) => void): this {\n    this.#emitter.off(event, listener);\n    return this;\n  }\n\n  once(event: string, listener: (...args: unknown[]) => void): this {\n    this.#emitter.once(event, listener);\n    return this;\n  }\n\n  clearLocal(): void {\n    this.#l1?.clear();\n  }\n\n  invalidateLocal(key: K): void {\n    this.#deleteLocal(key);\n  }\n\n  // Returns a proxy that shares all state with this instance but forces\n  // bypassL1: true on every L1-eligible read. Write methods pass through to\n  // the real instance so set/delete/etc still self-invalidate the underlying\n  // L1. Calling withoutLocal() on the returned proxy is idempotent - it\n  // returns the same proxy object.\n  //\n  // Implementation note: all method calls are routed through the Proxy target\n  // (the real instance) because private fields (#l1, etc.) are inaccessible\n  // on objects that are not genuine class instances. The Proxy get trap returns\n  // either a bypassL1-injecting override for read methods or the real\n  // instance's method bound to itself for everything else.\n  withoutLocal(): LRUCacheClustered<K, V> {\n    // Using `t` (the Proxy target = the real instance) inside the trap avoids\n    // a no-this-alias violation. All calls go through `t` so private fields\n    // (#l1, etc.) remain accessible on the real instance.\n    let wrapper: LRUCacheClustered<K, V>;\n    wrapper = new Proxy(this, {\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      get(t, prop): any {\n        if (prop === 'withoutLocal') return () => wrapper;\n        if (prop === 'get') {\n          return (key: K, opts?: { bypassL1?: boolean }) => t.get(key, { ...opts, bypassL1: true });\n        }\n        if (prop === 'has') {\n          return (key: K, opts?: { bypassL1?: boolean }) => t.has(key, { ...opts, bypassL1: true });\n        }\n        if (prop === 'peek') {\n          return (key: K, opts?: ReadOptions) => t.peek(key, { ...opts, bypassL1: true });\n        }\n        if (prop === 'mGet') {\n          return (keys: K[], opts?: ReadOptions) => t.mGet(keys, { ...opts, bypassL1: true });\n        }\n        if (prop === 'fetch') {\n          return (key: K, fetcher: (k: K) => V | Promise<V>, opts?: FetchOptions) =>\n            t.fetch(key, fetcher, { ...opts, bypassL1: true });\n        }\n        // All other properties: reflect from the real instance bound to it so\n        // private fields remain accessible.\n        const v = Reflect.get(t, prop, t);\n        return typeof v === 'function' ? (v as (...a: unknown[]) => unknown).bind(t) : v;\n      },\n    });\n    return wrapper;\n  }\n\n  // Materializes the full entries array up front, then yields — simpler than\n  // streaming over IPC at the cost of a single large payload per iteration.\n  async *[Symbol.asyncIterator](): AsyncIterableIterator<[K, V]> {\n    const all = await this.entries();\n    for (const pair of all) yield pair;\n  }\n\n  async fetch(key: K, fetcher: (key: K) => Promise<V> | V, opts?: FetchOptions): Promise<V> {\n    const useFetchL1 = this.#l1 && this.#l1Methods.fetch && !opts?.bypassL1;\n    if (!opts?.forceRefresh) {\n      if (useFetchL1) {\n        const cachedLocal = this.#getLocal(key);\n        if (cachedLocal !== undefined) return cachedLocal;\n      }\n\n      const existing = this.#inFlight.get(key);\n      if (existing) return existing.promise;\n    }\n\n    let slot!: { promise: Promise<V> };\n    const run = async (): Promise<V> => {\n      if (!opts?.forceRefresh) {\n        if (useFetchL1) {\n          const cached = await this.#dispatchWithMeta<V | undefined>({ op: 'get', key }, this.failsafe);\n          if (cached.value !== undefined) {\n            await this.#setLocalFromPrimary(key, cached.value, cached.version);\n            return cached.value;\n          }\n        } else {\n          const cached = await this.get(key, { bypassL1: true });\n          if (cached !== undefined) return cached;\n        }\n      }\n\n      let forceRefresh = opts?.forceRefresh === true;\n\n      while (true) {\n        const claim = await this.#dispatchRequired<FetchClaimResult<V>>({\n          op: 'fetchClaim',\n          key,\n          forceRefresh,\n        });\n\n        if (claim.kind === 'value') return claim.value;\n        if (claim.kind === 'leader') {\n          try {\n            const v = (await fetcher(key)) as V;\n            const stored = await this.#dispatchWithMeta<boolean>(\n              {\n                op: 'fetchStore',\n                key,\n                token: claim.token,\n                value: v,\n                ttl: opts?.ttl,\n                size: opts?.size,\n              },\n              'reject',\n            );\n            if (!stored.value) {\n              return (await this.get(key, { bypassL1: true })) as V;\n            }\n            // Populate the leader's L1 with the fresh value and the version\n            // returned by fetchStore. bypassL1 skips the populate so the caller\n            // sees the fresh L2 result without repopulating their L1.\n            if (useFetchL1) {\n              await this.#setLocalFromPrimary(key, v, stored.version);\n            }\n            if (this.#l1) this.#l1.advanceLatestSeen(stored.version);\n            return v;\n          } catch (error) {\n            try {\n              await this.#dispatchRequired<boolean>({\n                op: 'fetchAbort',\n                key,\n                token: claim.token,\n              });\n            } catch {\n              // Ignore cleanup failures and preserve the fetcher's error.\n            }\n            throw error;\n          }\n        }\n\n        const observed = await this.peek(key, { bypassL1: !useFetchL1 });\n        if (observed === undefined) {\n          forceRefresh = false;\n          await new Promise((resolve) => setTimeout(resolve, FETCH_POLL_MS));\n          continue;\n        }\n\n        return observed;\n      }\n    };\n\n    slot = { promise: run() };\n    this.#inFlight.set(key, slot);\n    try {\n      return await slot.promise;\n    } finally {\n      // Identity check — a newer forceRefresh fetch may have replaced our\n      // slot. Only clear if this slot is still current.\n      if (this.#inFlight.get(key) === slot) this.#inFlight.delete(key);\n    }\n  }\n\n  #installL1Subscription(): void {\n    if (!this.#l1 || this.#l1Invalidation !== 'broadcast' || this.#unsubscribeL1) return;\n    const handle = (msg: InvalidationPush) => this.#applyL1Invalidation(msg);\n    this.#l1InvalidationHandler = handle;\n    const unsubscribeLocal = subscribeLocalInvalidations(this.namespace, handle);\n    const unsubscribeIpc = cluster.isPrimary\n      ? undefined\n      : getDefaultClient().subscribeInvalidations(this.namespace, handle);\n    this.#unsubscribeL1 = () => {\n      unsubscribeLocal();\n      unsubscribeIpc?.();\n      this.#l1InvalidationHandler = undefined;\n    };\n  }\n\n  #applyL1Invalidation(msg: InvalidationPush): void {\n    this.#l1!.advanceLatestSeen(msg.version);\n    // Emit broadcast-reason event before the L1 mutation so listeners can\n    // distinguish broadcast-driven invalidations from local-write ones.\n    this.#emitter.emit('l1:invalidate', {\n      namespace: this.namespace,\n      key: msg.push === 'l1:invalidate' ? msg.key : '*',\n      reason: 'broadcast',\n    });\n    if (msg.push === 'l1:invalidate') {\n      try {\n        this.#l1!.delete(encodeL1Key(msg.key as NonNullish), msg.key, false);\n      } catch {\n        // Symbol or unencodable key: no-op\n      }\n    } else {\n      this.#l1!.clear(false);\n    }\n  }\n\n  async #setLocalFromPrimary(key: K, value: V, version: number): Promise<void> {\n    const enc = encodeL1KeyOrUndefined(key);\n    if (enc === undefined) return;\n    const ttl = await this.#remainingLocalTTL(key);\n    if (ttl === null) return;\n    this.#l1!.set(enc, value, version, ttl, key);\n  }\n\n  #getLocal(key: K): V | undefined {\n    const enc = encodeL1KeyOrUndefined(key);\n    return enc === undefined ? undefined : this.#l1!.get(enc, key);\n  }\n\n  #deleteLocal(key: K): void {\n    if (!this.#l1) return;\n    const enc = encodeL1KeyOrUndefined(key);\n    if (enc !== undefined) this.#l1.delete(enc, key);\n  }\n\n  async #remainingLocalTTL(key: K): Promise<number | undefined | null> {\n    try {\n      const ttl = await this.getRemainingTTL(key);\n      if (typeof ttl !== 'number' || ttl <= 0) return null;\n      return Number.isFinite(ttl) ? ttl : undefined;\n    } catch {\n      return null;\n    }\n  }\n\n  #emitLocalInvalidation(payload: ExecPayload, value: unknown, version: number): void {\n    const msg = buildLocalInvalidation(this.namespace, payload, version, value);\n    if (msg) emitLocalInvalidation(msg, this.#l1InvalidationHandler);\n  }\n\n  #dispatch<T>(payload: ExecPayload): Promise<T> {\n    return this.#dispatchWithMeta<T>(payload, this.failsafe).then((r) => r.value);\n  }\n\n  #dispatchRequired<T>(payload: ExecPayload): Promise<T> {\n    return this.#dispatchWithMeta<T>(payload, 'reject').then((r) => r.value);\n  }\n\n  async #dispatchWithMeta<T>(\n    payload: ExecPayload,\n    failsafe: 'resolve' | 'reject',\n  ): Promise<{ value: T; version: number }> {\n    const request = { ...payload, cacheOptions: this.#lruOptions } as ExecPayload;\n    if (cluster.isPrimary) {\n      try {\n        const r = dispatchAndBroadcast(this.namespace, request);\n        this.#emitLocalInvalidation(request, r.value, r.version);\n        return { value: r.value as T, version: r.version };\n      } catch (e) {\n        // Primary-mode errors always reject; failsafe only applies to IPC\n        // timeouts in worker mode.\n        throw e instanceof Error ? e : new Error(String(e));\n      }\n    }\n    const r = await getDefaultClient().sendToPrimaryWithMeta<T>(\n      { namespace: this.namespace, timeout: this.timeout, failsafe },\n      request,\n    );\n    this.#emitLocalInvalidation(request, r.value, r.version);\n    return r;\n  }\n}\n\n// Backward-compatible alias — `LRUCacheClustered` is the canonical name.\nexport { LRUCacheClustered as LRUCacheForClustersAsPromised };\n\nexport { memoize, type MemoizeOptions } from './memoize.js';\nexport { wrap, type Codec, type WrappedCache } from './codec.js';\n\nexport default LRUCacheClustered;\n","import cluster from 'node:cluster';\nimport type { Worker } from 'node:cluster';\nimport Debug from 'debug';\nimport { LRUCache } from 'lru-cache';\nimport {\n  DEBUG_PREFIX,\n  SOURCE,\n  serializeError,\n  type Request,\n  type Response,\n  type SerializableLruOptions,\n  type Stats,\n  type InvalidationPush,\n} from './messages.js';\n\n// Distributive Omit so each member of the Request union keeps its own shape.\ntype DistributiveOmit<T, K extends keyof never> = T extends unknown ? Omit<T, K> : never;\nexport type ExecPayload = DistributiveOmit<Request, 'id' | 'namespace' | 'source'>;\n\nconst debug = Debug(`${DEBUG_PREFIX}-primary`);\nconst messagesDebug = Debug(`${DEBUG_PREFIX}-messages`);\n\n// Public registry: namespace -> LRUCache. Keys/values constrained to non-nullish\n// per lru-cache@11 signature; we operate on `unknown` at the IPC boundary and\n// trust the runtime to filter undefined/null inputs.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype NonNullish = {};\ntype AnyCache = LRUCache<NonNullish, NonNullish>;\n\ntype DispatchContext = {\n  workerId?: number;\n};\n\ntype FetchLock = {\n  token: string;\n  ownerWorkerId?: number;\n  claimedAt: number;\n};\n\n// Lease window for a fetch claim. If the leader hasn't called fetchStore\n// or fetchAbort within this many ms, a new fetchClaim will overwrite the\n// stale lock and become the new leader. Bounds tail latency when a leader\n// hangs without process exit (which would otherwise be released by the\n// cluster.on('exit') handler). 30s is generous for typical user fetchers\n// and short enough that hung-leader incidents do not park requests forever.\nconst FETCH_LEASE_MS = 30_000;\n\ntype PrimaryState = {\n  caches: Map<string, AnyCache>;\n  stats: Map<string, Stats>;\n  fetchLocks: Map<string, Map<NonNullish, FetchLock>>;\n  versions: Map<string, number>;\n  clusterListenerInstalled: boolean;\n  nextFetchToken: number;\n};\n\n// The scoped and legacy package names can coexist during the migration window.\n// Share primary-side state process-wide so both names use one IPC listener and\n// one namespace registry when they are installed together.\nconst STATE_KEY = Symbol.for('lru-cache-clustered.primary');\nconst primaryState = ((globalThis as Record<PropertyKey, unknown>)[STATE_KEY] ??= {\n  caches: new Map<string, AnyCache>(),\n  stats: new Map<string, Stats>(),\n  fetchLocks: new Map<string, Map<NonNullish, FetchLock>>(),\n  versions: new Map<string, number>(),\n  clusterListenerInstalled: false,\n  nextFetchToken: 0,\n}) as PrimaryState;\n\nexport const caches = primaryState.caches;\nexport const stats = primaryState.stats;\nexport const versions = primaryState.versions;\nconst fetchLocks = primaryState.fetchLocks;\n\nexport function getNamespaceVersion(namespace: string): number {\n  return primaryState.versions.get(namespace) ?? 0;\n}\n\nfunction bumpNamespaceVersion(namespace: string): number {\n  const next = (primaryState.versions.get(namespace) ?? 0) + 1;\n  primaryState.versions.set(namespace, next);\n  return next;\n}\n\nfunction freshStats(namespace: string): Stats {\n  return { namespace, hits: 0, misses: 0, sets: 0, deletes: 0, evictions: 0, size: 0 };\n}\n\nfunction getStats(namespace: string): Stats {\n  let s = stats.get(namespace);\n  if (!s) {\n    s = freshStats(namespace);\n    stats.set(namespace, s);\n  }\n  return s;\n}\n\n// Capture the runtime-readable SerializableLruOptions off an existing cache.\n// Used by the `max` rebuild so the new instance keeps every tunable the old\n// one had — not just `ttl` and `allowStale`. lru-cache@11 exposes these as\n// instance properties; we go through `as unknown as ...` rather than typing\n// the full LRUCache interface here.\nfunction readOptions(cache: AnyCache): SerializableLruOptions {\n  const c = cache as unknown as {\n    max: number;\n    maxSize: number;\n    maxEntrySize: number;\n    ttl: number;\n    allowStale: boolean;\n    updateAgeOnGet: boolean;\n    updateAgeOnHas: boolean;\n    noDeleteOnStaleGet: boolean;\n    ttlAutopurge: boolean;\n  };\n  return {\n    max: c.max,\n    maxSize: c.maxSize,\n    maxEntrySize: c.maxEntrySize,\n    ttl: c.ttl,\n    allowStale: c.allowStale,\n    updateAgeOnGet: c.updateAgeOnGet,\n    updateAgeOnHas: c.updateAgeOnHas,\n    noDeleteOnStaleGet: c.noDeleteOnStaleGet,\n    ttlAutopurge: c.ttlAutopurge,\n  };\n}\n\nfunction getCacheForPayload(namespace: string, payload: ExecPayload): AnyCache {\n  const existing = caches.get(namespace);\n  if (existing) return existing;\n  return getOrCreateCache(namespace, payload.cacheOptions);\n}\n\nfunction assertOptionsCompatible(namespace: string, cache: AnyCache, options?: SerializableLruOptions): void {\n  if (!options) return;\n\n  const current = readOptions(cache);\n  const mismatches: string[] = [];\n\n  for (const [key, value] of Object.entries(options) as Array<\n    [keyof SerializableLruOptions, SerializableLruOptions[keyof SerializableLruOptions]]\n  >) {\n    if (value === undefined) continue;\n    if (current[key] !== value) {\n      mismatches.push(`${key}=${String(current[key])} (existing) != ${String(value)} (incoming)`);\n    }\n  }\n\n  if (mismatches.length > 0) {\n    throw new Error(`Conflicting options for namespace '${namespace}': ${mismatches.join(', ')}`);\n  }\n}\n\nfunction requireNonNullish(label: string, value: unknown): NonNullish {\n  if (value === null || value === undefined) {\n    throw new TypeError(`${label} must not be null or undefined`);\n  }\n  return value;\n}\n\nfunction buildSetOptions(opts: { ttl?: number; size?: number; noUpdateTTL?: boolean }):\n  | {\n      ttl?: number;\n      size?: number;\n      noUpdateTTL?: boolean;\n    }\n  | undefined {\n  const out: { ttl?: number; size?: number; noUpdateTTL?: boolean } = {};\n  if (opts.ttl !== undefined) out.ttl = opts.ttl;\n  if (opts.size !== undefined) out.size = opts.size;\n  if (opts.noUpdateTTL) out.noUpdateTTL = true;\n  return Object.keys(out).length > 0 ? out : undefined;\n}\n\nfunction readEntrySize(cache: AnyCache, key: NonNullish): number | undefined {\n  const info = (\n    cache as unknown as {\n      info: (key: NonNullish) => LRUCache.Entry<NonNullish> | undefined;\n    }\n  ).info(key);\n  return typeof info?.size === 'number' ? info.size : undefined;\n}\n\nfunction getFetchNamespaceLocks(namespace: string): Map<NonNullish, FetchLock> {\n  let locks = fetchLocks.get(namespace);\n  if (!locks) {\n    locks = new Map();\n    fetchLocks.set(namespace, locks);\n  }\n  return locks;\n}\n\nfunction cleanupFetchNamespaceLocks(namespace: string): void {\n  if (fetchLocks.get(namespace)?.size === 0) fetchLocks.delete(namespace);\n}\n\nfunction releaseFetchLocksForWorker(workerId: number): void {\n  for (const [namespace, locks] of fetchLocks) {\n    for (const [key, lock] of locks) {\n      if (lock.ownerWorkerId === workerId) {\n        locks.delete(key);\n      }\n    }\n    cleanupFetchNamespaceLocks(namespace);\n  }\n}\n\nfunction buildCache(options: SerializableLruOptions, s: Stats): AnyCache {\n  const cacheOptions = {\n    ...options,\n    dispose: (_value: NonNullish, _key: NonNullish, reason: LRUCache.DisposeReason) => {\n      if (reason === 'evict') s.evictions += 1;\n    },\n  } as SerializableLruOptions & {\n    dispose: (_value: NonNullish, _key: NonNullish, reason: LRUCache.DisposeReason) => void;\n  };\n  const defaultedOptions =\n    cacheOptions.max === undefined && cacheOptions.maxSize === undefined && cacheOptions.ttl === undefined\n      ? { ...cacheOptions, max: 1000 }\n      : cacheOptions;\n  return new LRUCache(defaultedOptions as ConstructorParameters<typeof LRUCache>[0]);\n}\n\nexport function getOrCreateCache(namespace: string, options?: SerializableLruOptions): AnyCache {\n  let cache = caches.get(namespace);\n  if (!cache) {\n    const s = freshStats(namespace);\n    stats.set(namespace, s);\n    cache = buildCache(options ?? {}, s);\n    caches.set(namespace, cache);\n    debug(`Created LRUCache for namespace '${namespace}'`);\n  } else {\n    assertOptionsCompatible(namespace, cache, options);\n  }\n  return cache;\n}\n\n// Pure dispatch: returns the value for the op or throws. Single source of truth\n// for op semantics; both `handleRequest` (IPC entry point) and the in-process\n// primary fast-path in `index.ts` call this. Avoids object/promise allocation\n// per call when no IPC is involved.\nexport function dispatchOp(namespace: string, payload: ExecPayload, context: DispatchContext = {}): unknown {\n  switch (payload.op) {\n    case 'init': {\n      const isNew = !caches.has(namespace);\n      const cache = getOrCreateCache(namespace, payload.options);\n      return { namespace, isNew, max: cache.max, version: getNamespaceVersion(namespace) };\n    }\n    case 'healthCheck':\n      getOrCreateCache(namespace, payload.cacheOptions);\n      return undefined;\n    case 'destroy': {\n      const cacheExisted = caches.delete(namespace);\n      const statsExisted = stats.delete(namespace);\n      const locksExisted = fetchLocks.delete(namespace);\n      const existed = cacheExisted || statsExisted || locksExisted;\n      if (existed) bumpNamespaceVersion(namespace);\n      return existed;\n    }\n    case 'get': {\n      const cache = getCacheForPayload(namespace, payload);\n      const value = cache.get(requireNonNullish('cache key', payload.key));\n      const s = getStats(namespace);\n      if (value !== undefined) s.hits += 1;\n      else s.misses += 1;\n      return value;\n    }\n    case 'set': {\n      const cache = getCacheForPayload(namespace, payload);\n      cache.set(\n        requireNonNullish('cache key', payload.key),\n        requireNonNullish('cache value', payload.value),\n        buildSetOptions({ ttl: payload.ttl, size: payload.size }),\n      );\n      getStats(namespace).sets += 1;\n      bumpNamespaceVersion(namespace);\n      return true;\n    }\n    case 'setIfAbsent': {\n      const cache = getCacheForPayload(namespace, payload);\n      const key = requireNonNullish('cache key', payload.key);\n      // peek() instead of has() so updateAgeOnHas does not extend the\n      // existing entry's TTL on a no-op setIfAbsent. Cache values are\n      // non-nullish, so undefined unambiguously means \"not present\".\n      if (cache.peek(key) !== undefined) return false;\n      cache.set(\n        key,\n        requireNonNullish('cache value', payload.value),\n        buildSetOptions({ ttl: payload.ttl, size: payload.size }),\n      );\n      getStats(namespace).sets += 1;\n      bumpNamespaceVersion(namespace);\n      return true;\n    }\n    case 'delete': {\n      const cache = getCacheForPayload(namespace, payload);\n      const deleted = cache.delete(requireNonNullish('cache key', payload.key));\n      if (deleted) {\n        getStats(namespace).deletes += 1;\n        bumpNamespaceVersion(namespace);\n      }\n      return deleted;\n    }\n    case 'has':\n      return getCacheForPayload(namespace, payload).has(requireNonNullish('cache key', payload.key));\n    case 'peek':\n      return getCacheForPayload(namespace, payload).peek(requireNonNullish('cache key', payload.key));\n    case 'getRemainingTTL':\n      return getCacheForPayload(namespace, payload).getRemainingTTL(requireNonNullish('cache key', payload.key));\n    case 'clear':\n      getCacheForPayload(namespace, payload).clear();\n      bumpNamespaceVersion(namespace);\n      return undefined;\n    case 'mGet': {\n      const cache = getCacheForPayload(namespace, payload);\n      const s = getStats(namespace);\n      return payload.keys.map((key) => {\n        const value = cache.get(requireNonNullish('cache key', key));\n        if (value !== undefined) s.hits += 1;\n        else s.misses += 1;\n        return [key, value] as [unknown, unknown];\n      });\n    }\n    case 'mSet': {\n      const cache = getCacheForPayload(namespace, payload);\n      const s = getStats(namespace);\n      const entries = payload.entries.map(([key, value, entryOpts]) => ({\n        key: requireNonNullish('cache key', key),\n        value: requireNonNullish('cache value', value),\n        entryOpts,\n      }));\n      for (const { key, value, entryOpts } of entries) {\n        cache.set(\n          key,\n          value,\n          buildSetOptions({\n            ttl: entryOpts?.ttl ?? payload.ttl,\n            size: entryOpts?.size ?? payload.size,\n          }),\n        );\n        s.sets += 1;\n      }\n      bumpNamespaceVersion(namespace);\n      return undefined;\n    }\n    case 'mDelete': {\n      const cache = getCacheForPayload(namespace, payload);\n      const s = getStats(namespace);\n      const keys = payload.keys.map((key) => requireNonNullish('cache key', key));\n      for (const key of keys) {\n        if (cache.delete(key)) s.deletes += 1;\n      }\n      bumpNamespaceVersion(namespace);\n      return undefined;\n    }\n    case 'keys':\n      return [...getCacheForPayload(namespace, payload).keys()];\n    case 'values':\n      return [...getCacheForPayload(namespace, payload).values()];\n    case 'entries':\n      return [...getCacheForPayload(namespace, payload).entries()];\n    case 'dump':\n      return getCacheForPayload(namespace, payload).dump();\n    case 'load': {\n      const cache = getCacheForPayload(namespace, payload);\n      const entries = payload.entries.map(([key, entry]) => {\n        const safeKey = requireNonNullish('cache key', key);\n        const safeEntry = entry as { value?: unknown };\n        requireNonNullish('cache value', safeEntry.value);\n        return [safeKey, entry] as [NonNullish, LRUCache.Entry<NonNullish>];\n      });\n      cache.load(entries);\n      bumpNamespaceVersion(namespace);\n      return undefined;\n    }\n    case 'size':\n      return getCacheForPayload(namespace, payload).size;\n    case 'stats': {\n      const cache = getCacheForPayload(namespace, payload);\n      const s = getStats(namespace);\n      s.size = cache.size;\n      return { ...s };\n    }\n    case 'purgeStale': {\n      const purged = getCacheForPayload(namespace, payload).purgeStale();\n      if (purged) bumpNamespaceVersion(namespace);\n      return purged;\n    }\n    case 'incr':\n    case 'decr': {\n      const cache = getCacheForPayload(namespace, payload);\n      const key = requireNonNullish('cache key', payload.key);\n      // peek() rather than has()/get() so updateAgeOnHas/updateAgeOnGet\n      // do not refresh the entry's age before the noUpdateTTL set below.\n      // Otherwise the rate-limiter \"ttl on first write only\" semantics\n      // would silently extend the original window on every increment.\n      const current = cache.peek(key);\n      const existed = current !== undefined;\n      const base = typeof current === 'number' ? current : 0;\n      const delta = (payload.amount ?? 1) * (payload.op === 'decr' ? -1 : 1);\n      const next = base + delta;\n      const size = payload.size ?? (existed ? readEntrySize(cache, key) : undefined);\n      // Rate-limiter semantics: ttl on first write only. For pre-existing\n      // keys, noUpdateTTL keeps the original expiration ticking; without it,\n      // cache.set(k, v) would reset to the cache's default ttl (or strip\n      // it entirely if the cache has none).\n      const setOpts = buildSetOptions(\n        existed\n          ? { size, noUpdateTTL: true }\n          : {\n              ttl: payload.ttl,\n              size,\n            },\n      );\n      cache.set(key, next, setOpts);\n      getStats(namespace).sets += 1;\n      bumpNamespaceVersion(namespace);\n      return next;\n    }\n    case 'fetchClaim': {\n      const cache = getCacheForPayload(namespace, payload);\n      const key = requireNonNullish('cache key', payload.key);\n      const locks = getFetchNamespaceLocks(namespace);\n      const now = Date.now();\n      if (!payload.forceRefresh) {\n        const value = cache.get(key);\n        if (value !== undefined) return { kind: 'value', value };\n        const existing = locks.get(key);\n        // Treat a stale lock as gone, so a new caller can take leadership\n        // and unstick followers when a previous leader hung without exiting.\n        if (existing && now - existing.claimedAt < FETCH_LEASE_MS) {\n          return { kind: 'follower' };\n        }\n      }\n      const token = `fetch-${++primaryState.nextFetchToken}`;\n      locks.set(key, { token, ownerWorkerId: context.workerId, claimedAt: now });\n      return { kind: 'leader', token };\n    }\n    case 'fetchStore': {\n      const cache = getCacheForPayload(namespace, payload);\n      const key = requireNonNullish('cache key', payload.key);\n      const locks = fetchLocks.get(namespace);\n      const lock = locks?.get(key);\n      if (!lock || lock.token !== payload.token) return false;\n      cache.set(\n        key,\n        requireNonNullish('cache value', payload.value),\n        buildSetOptions({ ttl: payload.ttl, size: payload.size }),\n      );\n      locks?.delete(key);\n      cleanupFetchNamespaceLocks(namespace);\n      getStats(namespace).sets += 1;\n      bumpNamespaceVersion(namespace);\n      return true;\n    }\n    case 'fetchAbort': {\n      const key = requireNonNullish('cache key', payload.key);\n      const locks = fetchLocks.get(namespace);\n      const lock = locks?.get(key);\n      if (!lock || lock.token !== payload.token) return false;\n      locks?.delete(key);\n      cleanupFetchNamespaceLocks(namespace);\n      return true;\n    }\n    case 'max': {\n      const cache = getCacheForPayload(namespace, payload);\n      if (typeof payload.value === 'number' && payload.value !== cache.max) {\n        // lru-cache@11 has no setter for max — rebuild. Two correctness points:\n        // (1) preserve every SerializableLruOptions field, not just ttl and\n        //     allowStale, so updateAgeOnGet/updateAgeOnHas/etc. survive;\n        // (2) preserve per-entry metadata such as remaining TTL. `dump()` /\n        //     `load()` keeps entry age data intact; replaying via plain `set()`\n        //     would silently refresh or strip expirations.\n        // Reuse the existing stats record so the new dispose hook keeps\n        // counting evictions for the same namespace.\n        const s = getStats(namespace);\n        const opts = { ...readOptions(cache), max: payload.value };\n        const replacement = buildCache(opts, s);\n        replacement.load(cache.dump());\n        caches.set(namespace, replacement);\n        bumpNamespaceVersion(namespace);\n        return replacement.max;\n      }\n      return cache.max;\n    }\n    case 'ttl': {\n      const cache = getCacheForPayload(namespace, payload);\n      const current = (cache as unknown as { ttl: number }).ttl;\n      if (typeof payload.value === 'number' && payload.value !== current) {\n        (cache as unknown as { ttl: number }).ttl = payload.value;\n        bumpNamespaceVersion(namespace);\n      }\n      return (cache as unknown as { ttl: number }).ttl;\n    }\n    case 'allowStale': {\n      const cache = getCacheForPayload(namespace, payload);\n      if (typeof payload.value === 'boolean') (cache as unknown as { allowStale: boolean }).allowStale = payload.value;\n      return (cache as unknown as { allowStale: boolean }).allowStale;\n    }\n    default: {\n      const op = (payload as { op: string }).op;\n      throw new Error(`unhandled op: ${op}`);\n    }\n  }\n}\n\n// Bulk ops broadcast a namespace-wide invalidate; single-key ops broadcast the\n// specific key. Reasoning in spec section 5.3.\nconst BULK_BROADCAST_OPS = new Set([\n  'destroy',\n  'clear',\n  'purgeStale',\n  'mSet',\n  'mDelete',\n  'load',\n  'max',\n  'ttl',\n] as const);\n\nfunction buildInvalidation(namespace: string, payload: ExecPayload, version: number): InvalidationPush | undefined {\n  if ((BULK_BROADCAST_OPS as Set<string>).has(payload.op)) {\n    return { source: SOURCE, push: 'l1:invalidate-namespace', namespace, version };\n  }\n  // Single-key mutating ops carry `key`. Read ops don't reach here because\n  // dispatchAndBroadcast checks the version-bump signal before invoking us.\n  const key = (payload as { key?: unknown }).key;\n  /* c8 ignore next -- all current version-bumping single-key ops validate a non-nullish key before this point. */\n  if (key === undefined || key === null) return undefined;\n  return { source: SOURCE, push: 'l1:invalidate', namespace, key, version };\n}\n\nfunction broadcastInvalidation(msg: InvalidationPush): void {\n  for (const worker of Object.values(cluster.workers ?? {})) {\n    if (!worker || !worker.isConnected()) continue;\n    try {\n      worker.send(msg);\n    } catch (err) {\n      debug(`l1 broadcast to worker ${worker.id} failed: %s`, err);\n    }\n  }\n}\n\nexport function dispatchAndBroadcast(\n  namespace: string,\n  payload: ExecPayload,\n  context: DispatchContext = {},\n): { value: unknown; version: number } {\n  const before = getNamespaceVersion(namespace);\n  const value = dispatchOp(namespace, payload, context);\n  const after = getNamespaceVersion(namespace);\n  if (after !== before) {\n    const msg = buildInvalidation(namespace, payload, after);\n    if (msg) broadcastInvalidation(msg);\n  }\n  return { value, version: after };\n}\n\nexport function handleRequest(request: Request, context: DispatchContext = {}): Response {\n  if (typeof request !== 'object' || request === null) {\n    return err(request, 'invalid request: not an object');\n  }\n  // Validate the full Request shape before dispatching. Without this guard,\n  // a malformed payload reaching handleRequest directly (the IPC entry point\n  // already filters via isOurRequest, but the function is exported and could\n  // be called from anywhere) would call dispatchOp with undefined fields and\n  // could mutate the namespace registry under non-string keys.\n  if (!isOurRequest(request)) {\n    return err(request, 'invalid request: missing required fields');\n  }\n  try {\n    const { value } = dispatchAndBroadcast(request.namespace, request, context);\n    return ok(request, value, getNamespaceVersion(request.namespace));\n  } catch (e) {\n    return err(request, e);\n  }\n}\n\nfunction ok(request: Request, value: unknown, version: number): Response {\n  return { id: request.id, source: SOURCE, ok: true, value, version };\n}\nfunction err(request: unknown, cause: unknown): Response {\n  const id =\n    typeof request === 'object' && request !== null && typeof (request as { id?: unknown }).id === 'string'\n      ? (request as { id: string }).id\n      : '';\n  return { id, source: SOURCE, ok: false, error: serializeError(cause) };\n}\n\n// Caller must check `cluster.isPrimary` — this only runs on the primary.\nexport function installClusterListener(): void {\n  if (primaryState.clusterListenerInstalled) return;\n  primaryState.clusterListenerInstalled = true;\n\n  cluster.on('exit', (worker: Worker) => {\n    releaseFetchLocksForWorker(worker.id);\n  });\n  cluster.on('fork', (worker: Worker) => {\n    attachWorkerHandler(worker);\n  });\n  // Cover workers that already exist when the listener is installed late\n  // (e.g. bootstrap() called after some forks). cluster.on('fork') only\n  // fires for future workers, so without this those would never get a\n  // message handler and their IPC requests would silently time out.\n  for (const worker of Object.values(cluster.workers ?? {})) {\n    if (worker) attachWorkerHandler(worker);\n  }\n}\n\nfunction attachWorkerHandler(worker: Worker): void {\n  worker.on('message', (raw: unknown) => {\n    if (!isOurRequest(raw)) return;\n    messagesDebug(`primary <- worker ${worker.id}`, raw);\n    const response = handleRequest(raw, { workerId: worker.id });\n    // The worker can disconnect between sending a request and us sending the\n    // response. send() in that window throws synchronously; left unhandled,\n    // it would propagate out of this listener and crash the primary, taking\n    // every other worker with it.\n    if (!worker.isConnected()) return;\n    try {\n      worker.send(response);\n    } catch (err) {\n      debug(`worker ${worker.id} send failed (likely disconnected): %s`, err);\n    }\n  });\n}\n\nfunction isOurRequest(value: unknown): value is Request {\n  return (\n    typeof value === 'object' &&\n    value !== null &&\n    (value as { source?: unknown }).source === SOURCE &&\n    typeof (value as { id?: unknown }).id === 'string' &&\n    typeof (value as { namespace?: unknown }).namespace === 'string' &&\n    typeof (value as { op?: unknown }).op === 'string'\n  );\n}\n","// Short sentinel for IPC payload filtering. Each request and response carries\n// this string so the listener can ignore foreign messages on the shared cluster\n// IPC channel. Kept short (6 bytes) to minimize wire overhead — at 10k ops/sec\n// the savings versus a long package-name string add up to ~500KB/sec.\nexport const SOURCE = 'lcfcap' as const;\ntype Source = typeof SOURCE;\n\n// Keep the debug namespace unscoped so it stays ergonomic in `DEBUG=...` and\n// stable across the canonical scoped package and the mirrored legacy publish.\nexport const DEBUG_PREFIX = 'lru-cache-clustered';\n\ntype RequestBase = {\n  id: string;\n  namespace: string;\n  source: Source;\n  cacheOptions?: SerializableLruOptions;\n};\n\nexport type Request = RequestBase &\n  (\n    | { op: 'init'; options: SerializableLruOptions }\n    | { op: 'healthCheck' }\n    | { op: 'destroy' }\n    | { op: 'get'; key: unknown }\n    | { op: 'set'; key: unknown; value: unknown; ttl?: number; size?: number }\n    | { op: 'setIfAbsent'; key: unknown; value: unknown; ttl?: number; size?: number }\n    | { op: 'delete'; key: unknown }\n    | { op: 'has'; key: unknown }\n    | { op: 'peek'; key: unknown }\n    | { op: 'getRemainingTTL'; key: unknown }\n    | { op: 'clear' }\n    | { op: 'purgeStale' }\n    | { op: 'mGet'; keys: unknown[] }\n    | {\n        op: 'mSet';\n        entries: Array<[unknown, unknown] | [unknown, unknown, { ttl?: number; size?: number }]>;\n        ttl?: number;\n        size?: number;\n      }\n    | { op: 'mDelete'; keys: unknown[] }\n    | { op: 'keys' }\n    | { op: 'values' }\n    | { op: 'entries' }\n    | { op: 'dump' }\n    | { op: 'load'; entries: Array<[unknown, unknown]> }\n    | { op: 'size' }\n    | { op: 'stats' }\n    | { op: 'incr'; key: unknown; amount?: number; ttl?: number; size?: number }\n    | { op: 'decr'; key: unknown; amount?: number; ttl?: number; size?: number }\n    | { op: 'fetchClaim'; key: unknown; forceRefresh?: boolean }\n    | { op: 'fetchStore'; key: unknown; token: string; value: unknown; ttl?: number; size?: number }\n    | { op: 'fetchAbort'; key: unknown; token: string }\n    | { op: 'allowStale'; value?: boolean }\n    | { op: 'max'; value?: number }\n    | { op: 'ttl'; value?: number }\n  );\n\n// Errors flow over IPC as a structured payload so consumers can branch on\n// `name`/`code`/`cause` instead of regex-matching a `message` string. Internal\n// to the wire format — workers receive a reconstructed `Error` via\n// `deserializeError`, never this raw shape.\ntype SerializedError = {\n  name: string;\n  message: string;\n  code?: string | number;\n  stack?: string;\n  cause?: SerializedError;\n};\n\nexport type Response = { id: string; source: Source } & (\n  | { ok: true; value: unknown; version?: number }\n  | { ok: false; error: SerializedError }\n);\n\n// Subset of LRUCache.Options that survives IPC structured-clone — no functions.\nexport type SerializableLruOptions = {\n  max?: number;\n  maxSize?: number;\n  maxEntrySize?: number;\n  ttl?: number;\n  allowStale?: boolean;\n  updateAgeOnGet?: boolean;\n  updateAgeOnHas?: boolean;\n  noDeleteOnStaleGet?: boolean;\n  ttlAutopurge?: boolean;\n};\n\nexport type Stats = {\n  namespace: string;\n  hits: number;\n  misses: number;\n  sets: number;\n  deletes: number;\n  evictions: number;\n  size: number;\n};\n\n// Cause chains are walked recursively. Cap depth and detect cycles so a\n// pathological error (self-referential cause, or a chain dozens deep)\n// cannot stack-overflow the primary's IPC message handler and crash the\n// cluster.\nconst SERIALIZE_CAUSE_MAX_DEPTH = 8;\n\nexport function serializeError(err: unknown): SerializedError {\n  return serializeErrorAt(err, 0, new Set());\n}\n\nfunction serializeErrorAt(err: unknown, depth: number, seen: Set<object>): SerializedError {\n  if (err instanceof Error) {\n    if (seen.has(err)) {\n      return { name: err.name, message: '[circular cause]' };\n    }\n    seen.add(err);\n    const out: SerializedError = { name: err.name, message: err.message };\n    if (err.stack) out.stack = err.stack;\n    const code = (err as { code?: unknown }).code;\n    if (typeof code === 'string' || typeof code === 'number') out.code = code;\n    const cause = (err as { cause?: unknown }).cause;\n    if (cause !== undefined) {\n      if (depth + 1 >= SERIALIZE_CAUSE_MAX_DEPTH) {\n        out.cause = { name: 'Error', message: '[cause chain truncated]' };\n      } else {\n        out.cause = serializeErrorAt(cause, depth + 1, seen);\n      }\n    }\n    return out;\n  }\n  return { name: 'Error', message: typeof err === 'string' ? err : String(err) };\n}\n\nexport function deserializeError(payload: SerializedError): Error {\n  const err = new Error(payload.message);\n  err.name = payload.name;\n  if (payload.stack) err.stack = payload.stack;\n  if (payload.code !== undefined) (err as { code?: unknown }).code = payload.code;\n  if (payload.cause !== undefined) (err as { cause?: unknown }).cause = deserializeError(payload.cause);\n  return err;\n}\n\n// Pushes are primary-to-worker fire-and-forget messages with no `id` and no\n// matching response. The wire layer recognises them by the `push` discriminator\n// (and the shared SOURCE filter); they never collide with `Request`/`Response`.\nexport type InvalidationPush =\n  | { source: Source; push: 'l1:invalidate'; namespace: string; key: unknown; version: number }\n  | { source: Source; push: 'l1:invalidate-namespace'; namespace: string; version: number };\n\nexport function isInvalidationPush(value: unknown): value is InvalidationPush {\n  if (\n    typeof value !== 'object' ||\n    value === null ||\n    (value as { source?: unknown }).source !== SOURCE ||\n    typeof (value as { namespace?: unknown }).namespace !== 'string' ||\n    typeof (value as { version?: unknown }).version !== 'number'\n  ) {\n    return false;\n  }\n  const push = (value as { push?: unknown }).push;\n  return push === 'l1:invalidate' || push === 'l1:invalidate-namespace';\n}\n","import { setTimeout, clearTimeout } from 'node:timers';\nimport Debug from 'debug';\nimport {\n  DEBUG_PREFIX,\n  SOURCE,\n  deserializeError,\n  isInvalidationPush,\n  type InvalidationPush,\n  type Request,\n  type Response,\n} from './messages.js';\n\nconst messagesDebug = Debug(`${DEBUG_PREFIX}-messages`);\n\n// Monotonic per-process request ID, shared across all IpcClient instances\n// in this worker. Uniqueness within the process is the only requirement —\n// the primary keys responses by id and only this worker reads them back.\n// Avoids randomUUID's ~1µs cost and keeps wire-format IDs short (1-10\n// chars vs UUID's 36).\nlet nextRequestId = 0;\n\ntype SendOptions = {\n  namespace: string;\n  timeout: number;\n  failsafe: 'resolve' | 'reject';\n};\n\ntype ProcessLike = {\n  send: (msg: unknown) => boolean | void;\n  on: (event: 'message', cb: (msg: unknown) => void) => void;\n};\n\n// Distributive Omit so each member of the Request discriminated union keeps its own shape.\ntype DistributiveOmit<T, K extends keyof never> = T extends unknown ? Omit<T, K> : never;\ntype RequestPayload = DistributiveOmit<Request, 'id' | 'namespace' | 'source'>;\n\ntype InvalidationHandler = (msg: InvalidationPush) => void;\n\ninterface IpcClient {\n  sendToPrimary: <T = unknown>(opts: SendOptions, payload: RequestPayload) => Promise<T>;\n  sendToPrimaryWithMeta: <T = unknown>(\n    opts: SendOptions,\n    payload: RequestPayload,\n  ) => Promise<{ value: T; version: number }>;\n  subscribeInvalidations: (namespace: string, handler: InvalidationHandler) => () => void;\n}\n\nexport function createIpcClient(proc: ProcessLike): IpcClient {\n  const callbacks = new Map<string, (response: Response) => void>();\n  const subscribers = new Map<string, Set<InvalidationHandler>>();\n\n  proc.on('message', (raw: unknown) => {\n    if (isOurResponse(raw)) {\n      const cb = callbacks.get(raw.id);\n      if (!cb) return;\n      callbacks.delete(raw.id);\n      cb(raw);\n      return;\n    }\n    if (isInvalidationPush(raw)) {\n      const set = subscribers.get(raw.namespace);\n      if (!set) return;\n      for (const handler of set) {\n        try {\n          handler(raw);\n        } catch (err) {\n          messagesDebug('invalidation handler threw: %o', err);\n        }\n      }\n      return;\n    }\n  });\n\n  function send<T>(opts: SendOptions, payload: RequestPayload): Promise<{ value: T; version: number }> {\n    const id = String(++nextRequestId);\n    const request = { id, namespace: opts.namespace, source: SOURCE, ...payload } as Request;\n\n    return new Promise((resolve, reject) => {\n      const timer = setTimeout(() => {\n        callbacks.delete(id);\n        if (opts.failsafe === 'reject') reject(new Error('IPC timeout'));\n        else resolve({ value: undefined as T, version: 0 });\n      }, opts.timeout);\n\n      callbacks.set(id, (response) => {\n        clearTimeout(timer);\n        if (response.ok) resolve({ value: response.value as T, version: response.version ?? 0 });\n        else reject(deserializeError(response.error));\n      });\n\n      messagesDebug('worker -> primary', request);\n      try {\n        // proc.send returns false when the IPC channel is full\n        // (backpressure). The message is silently dropped, so the response\n        // would never arrive and the caller would block until the timeout\n        // fires. Fast-fail here so backpressure surfaces immediately under\n        // the configured failsafe.\n        const sent = proc.send(request);\n        if (sent === false) {\n          clearTimeout(timer);\n          callbacks.delete(id);\n          if (opts.failsafe === 'reject') reject(new Error('IPC backpressure'));\n          else resolve({ value: undefined as T, version: 0 });\n        }\n      } catch (error) {\n        clearTimeout(timer);\n        callbacks.delete(id);\n        reject(error instanceof Error ? error : new Error(String(error)));\n      }\n    });\n  }\n\n  return {\n    async sendToPrimary<T>(opts: SendOptions, payload: RequestPayload): Promise<T> {\n      const r = await send<T>(opts, payload);\n      return r.value;\n    },\n    sendToPrimaryWithMeta: <T>(opts: SendOptions, payload: RequestPayload) => send<T>(opts, payload),\n    subscribeInvalidations(namespace: string, handler: InvalidationHandler): () => void {\n      let set = subscribers.get(namespace);\n      if (!set) {\n        set = new Set();\n        subscribers.set(namespace, set);\n      }\n      set.add(handler);\n      return () => {\n        const s = subscribers.get(namespace);\n        if (!s) return;\n        s.delete(handler);\n        if (s.size === 0) subscribers.delete(namespace);\n      };\n    },\n  };\n}\n\nfunction isOurResponse(value: unknown): value is Response {\n  if (\n    typeof value !== 'object' ||\n    value === null ||\n    (value as { source?: unknown }).source !== SOURCE ||\n    typeof (value as { id?: unknown }).id !== 'string' ||\n    typeof (value as { ok?: unknown }).ok !== 'boolean'\n  ) {\n    return false;\n  }\n  // When ok=false, validate the error payload shape too. Without this guard a\n  // malformed error from a misbehaving primary would crash the message\n  // listener in deserializeError(undefined) and take the worker down.\n  if ((value as { ok: boolean }).ok === false) {\n    const error = (value as { error?: unknown }).error;\n    if (\n      typeof error !== 'object' ||\n      error === null ||\n      typeof (error as { name?: unknown }).name !== 'string' ||\n      typeof (error as { message?: unknown }).message !== 'string'\n    ) {\n      return false;\n    }\n  }\n  return true;\n}\n\n// Lazy singleton for the actual worker process. Constructing the client\n// attaches a `process.on('message')` listener and captures `process.send`,\n// neither of which is meaningful in primary mode — so we defer creation\n// until a worker-side dispatch actually needs it.\nlet cachedDefaultClient: IpcClient | undefined;\n\nexport function getDefaultClient(): IpcClient {\n  if (!cachedDefaultClient) {\n    if (typeof process.send !== 'function') {\n      throw new Error(\n        'lru-cache-clustered: worker IPC client requested in a process without `process.send` (not a cluster worker).',\n      );\n    }\n    const send = process.send.bind(process);\n    cachedDefaultClient = createIpcClient({\n      send: (msg) => send(msg),\n      on: (event, cb) => process.on(event, cb),\n    });\n  }\n  return cachedDefaultClient;\n}\n","import { LRUCache } from 'lru-cache';\n\nexport type L1Stats = {\n  enabled: true;\n  hits: number;\n  misses: number;\n  sets: number;\n  invalidations: number;\n  evictions: number;\n  staleHits: number;\n  size: number;\n  ipcAvoided: number;\n};\n\ntype L1Envelope<V> = {\n  value: V;\n  version: number;\n  key: unknown;\n};\n\ntype L1EmitEvent = 'hit' | 'miss' | 'set' | 'invalidate' | 'evict' | 'stale-hit';\n\ntype L1EmitPayload = {\n  key?: unknown;\n  version?: number;\n  reason?: string;\n};\n\ntype L1EmitFn = (event: L1EmitEvent, payload: L1EmitPayload) => void;\n\ntype L1ConstructorOptions = {\n  max?: number;\n  maxSize?: number;\n  ttl?: number;\n  updateAgeOnGet?: boolean;\n  allowStale?: boolean;\n  emit?: L1EmitFn; // optional; defaults to no-op\n};\n\nconst objectKeyIds = new WeakMap<object, number>();\nlet nextObjectKeyId = 0;\n\nfunction objectKeyId(key: object): number {\n  let id = objectKeyIds.get(key);\n  if (id === undefined) {\n    id = ++nextObjectKeyId;\n    objectKeyIds.set(key, id);\n  }\n  return id;\n}\n\n// Encode arbitrary cache keys into a string the L1 LRUCache can index by.\n// Primitives use a typed prefix so 1 (number) and \"1\" (string) do not collide.\n// Objects and functions use WeakMap-backed identity IDs so L1 mirrors\n// lru-cache's SameValueZero key semantics instead of structural equality.\n// Symbol keys are rejected because Symbol.toString is not stable across realms\n// and the L1 would dedup by description, which is wrong.\n//\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport function encodeL1Key(key: {}): string {\n  switch (typeof key) {\n    case 'string':\n      return `s:${key}`;\n    case 'number':\n      return `n:${key}`;\n    case 'boolean':\n      return `b:${key}`;\n    case 'bigint':\n      return `i:${key.toString()}`;\n    case 'symbol':\n      throw new Error('L1 does not support symbol keys');\n    case 'function':\n      return `f:${objectKeyId(key)}`;\n    default:\n      return `o:${objectKeyId(key)}`;\n  }\n}\n\nconst FRESH_STATS = (): L1Stats => ({\n  enabled: true,\n  hits: 0,\n  misses: 0,\n  sets: 0,\n  invalidations: 0,\n  evictions: 0,\n  staleHits: 0,\n  size: 0,\n  ipcAvoided: 0,\n});\n\n// Per-instance L1 cache. One LocalL1Cache per LRUCacheClustered.\n// Stores L1Envelope<V> so we can stamp each entry with the namespace version\n// at the moment it was populated; later reads compare against the latest\n// invalidation version we've observed for the namespace.\n//\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport class LocalL1Cache<V extends {} = {}> {\n  readonly #cache: LRUCache<string, L1Envelope<V>>;\n  readonly #ttl?: number;\n  #latestSeen = 0;\n  readonly #stats = FRESH_STATS();\n  readonly #emit: L1EmitFn;\n\n  constructor(opts: L1ConstructorOptions) {\n    this.#emit = opts.emit ?? (() => undefined);\n    this.#ttl = opts.ttl;\n    const lruOpts = {\n      max: opts.max ?? 1000,\n      ttl: opts.ttl,\n      updateAgeOnGet: opts.updateAgeOnGet ?? true,\n      allowStale: opts.allowStale ?? false,\n      maxSize: opts.maxSize,\n      // sizeCalculation is required when maxSize is set, but for v1 we don't\n      // expose it in the public LocalL1Options. If a caller passes maxSize,\n      // we use a 1-per-entry calculation as a placeholder.\n      ...(opts.maxSize !== undefined ? { sizeCalculation: () => 1 } : {}),\n      dispose: (value: L1Envelope<V>, key: string, reason: LRUCache.DisposeReason) => {\n        if (reason === 'evict') {\n          this.#stats.evictions += 1;\n          this.#emit('evict', { key: value.key ?? key, reason: 'lru' });\n        }\n      },\n    } as ConstructorParameters<typeof LRUCache<string, L1Envelope<V>>>[0];\n    this.#cache = new LRUCache(lruOpts);\n  }\n\n  get(encodedKey: string, eventKey: unknown = encodedKey): V | undefined {\n    const status: { returnedStale?: true } = {};\n    const entry = this.#cache.get(encodedKey, { status });\n    if (!entry) {\n      this.#stats.misses += 1;\n      this.#emit('miss', { key: eventKey });\n      return undefined;\n    }\n    if (status.returnedStale) {\n      this.#stats.staleHits += 1;\n      this.#emit('stale-hit', { key: entry.key });\n    }\n    if (entry.version < this.#latestSeen) {\n      // Stamped before the latest invalidation; drop it.\n      this.#cache.delete(encodedKey);\n      this.#stats.misses += 1;\n      this.#stats.staleHits += 1;\n      this.#emit('stale-hit', { key: entry.key });\n      this.#emit('miss', { key: eventKey });\n      return undefined;\n    }\n    this.#stats.hits += 1;\n    this.#stats.ipcAvoided += 1;\n    this.#emit('hit', { key: entry.key });\n    return entry.value;\n  }\n\n  set(encodedKey: string, value: V, version: number, ttl?: number, eventKey: unknown = encodedKey): void {\n    if (version < this.#latestSeen) {\n      // Don't store an entry already known to be stale.\n      return;\n    }\n    const setOpts = this.#setOptions(ttl);\n    if (setOpts === false) return;\n    this.#cache.set(encodedKey, { value, version, key: eventKey }, setOpts);\n    this.#stats.sets += 1;\n    this.#emit('set', { key: eventKey, version });\n  }\n\n  delete(encodedKey: string, eventKey: unknown = encodedKey, emit = true): void {\n    if (this.#cache.delete(encodedKey)) {\n      this.#stats.invalidations += 1;\n      if (emit) this.#emit('invalidate', { key: eventKey, reason: 'self' });\n    }\n  }\n\n  clear(emit = true): void {\n    if (this.#cache.size > 0) this.#stats.invalidations += 1;\n    this.#cache.clear();\n    if (emit) this.#emit('invalidate', { key: '*', reason: 'clear' });\n  }\n\n  advanceLatestSeen(version: number): void {\n    if (version > this.#latestSeen) this.#latestSeen = version;\n  }\n\n  latestSeen(): number {\n    return this.#latestSeen;\n  }\n\n  stats(): L1Stats {\n    return { ...this.#stats, size: this.#cache.size };\n  }\n\n  // For tests / explicit teardown.\n  destroy(): void {\n    this.#cache.clear();\n  }\n\n  #setOptions(ttl: number | undefined): { ttl: number } | undefined | false {\n    if (ttl === undefined || !Number.isFinite(ttl)) return undefined;\n    const capped = this.#ttl === undefined ? ttl : Math.min(ttl, this.#ttl);\n    return capped > 0 ? { ttl: capped } : false;\n  }\n}\n","import type { FetchOptions, LRUCacheClustered } from './index.js';\n\nexport type MemoizeOptions = FetchOptions;\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport function memoize<Args extends unknown[], K extends {}, V extends {}>(\n  cache: LRUCacheClustered<K, V>,\n  fn: (...args: Args) => Promise<V> | V,\n  keyFn: (...args: Args) => K,\n  opts?: MemoizeOptions,\n): (...args: Args) => Promise<V> {\n  return async (...args: Args): Promise<V> => {\n    const key = keyFn(...args);\n    return cache.fetch(key, () => fn(...args), opts);\n  };\n}\n","import type { Stats } from './messages.js';\nimport type { FetchOptions, LRUCacheClustered, MSetEntry, ReadOptions, WriteOptions } from './index.js';\n\n// A codec is a symmetric encode/decode pair. Both directions may be sync or\n// async — gzip/brotli's sync flavours work fine, and so do MessagePack-style\n// libraries that return Buffers, or async streams. The library never inspects\n// or assumes anything about the encoded form beyond \"lru-cache@11 accepts it\",\n// which means non-nullish.\nexport interface Codec<V, U> {\n  encode(value: V): U | Promise<U>;\n  decode(raw: U): V | Promise<V>;\n}\n\n// Methods that operate on or return cache values are wrapped through the\n// codec; everything else (keys, lifecycle, metrics) passes through. We\n// deliberately omit `incr`/`decr` (numeric ops that would not survive most\n// codecs) and `dump`/`load` (which speak the raw stored form). Reach those\n// via `wrapped.cache` when needed.\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface WrappedCache<K extends {}, V extends {}> {\n  readonly cache: LRUCacheClustered<K, never>;\n  readonly namespace: string;\n  readonly ready: Promise<void>;\n\n  get(key: K, opts?: ReadOptions): Promise<V | undefined>;\n  set(key: K, value: V, opts?: WriteOptions): Promise<boolean>;\n  setIfAbsent(key: K, value: V, opts?: WriteOptions): Promise<boolean>;\n  has(key: K, opts?: ReadOptions): Promise<boolean>;\n  peek(key: K, opts?: ReadOptions): Promise<V | undefined>;\n  delete(key: K): Promise<boolean>;\n  getRemainingTTL(key: K): Promise<number>;\n\n  mGet(keys: K[], opts?: ReadOptions): Promise<Map<K, V | undefined>>;\n  mSet(entries: Iterable<MSetEntry<K, V>>, opts?: WriteOptions): Promise<void>;\n  mDelete(keys: K[]): Promise<void>;\n\n  keys(): Promise<K[]>;\n  values(): Promise<V[]>;\n  entries(): Promise<Array<[K, V]>>;\n  size(): Promise<number>;\n  [Symbol.asyncIterator](): AsyncIterableIterator<[K, V]>;\n\n  clear(): Promise<void>;\n  destroy(): Promise<boolean>;\n  healthCheck(): Promise<void>;\n  purgeStale(): Promise<boolean>;\n  stats(): Promise<Stats>;\n\n  fetch(key: K, fetcher: (key: K) => Promise<V> | V, opts?: FetchOptions): Promise<V>;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport function wrap<K extends {}, V extends {}, U extends {}>(\n  cache: LRUCacheClustered<K, U>,\n  codec: Codec<V, U>,\n): WrappedCache<K, V> {\n  const enc = (v: V): U | Promise<U> => codec.encode(v);\n  const dec = (u: U): V | Promise<V> => codec.decode(u);\n\n  // Cast once to a `never`-valued surface for the public `cache` field. Users\n  // who want to bypass the codec can drop in via `wrapped.cache as any` — we\n  // don't try to make that ergonomic, since doing so is the whole point of an\n  // escape hatch.\n  const underlying = cache as unknown as LRUCacheClustered<K, never>;\n\n  const wrapped: WrappedCache<K, V> = {\n    cache: underlying,\n    namespace: cache.namespace,\n    ready: cache.ready,\n\n    async get(key, opts) {\n      const raw = await cache.get(key, opts);\n      return raw === undefined ? undefined : await dec(raw);\n    },\n    async set(key, value, opts) {\n      return cache.set(key, await enc(value), opts);\n    },\n    async setIfAbsent(key, value, opts) {\n      return cache.setIfAbsent(key, await enc(value), opts);\n    },\n    has: (key, opts) => cache.has(key, opts),\n    async peek(key, opts) {\n      const raw = await cache.peek(key, opts);\n      return raw === undefined ? undefined : await dec(raw);\n    },\n    delete: (key) => cache.delete(key),\n    getRemainingTTL: (key) => cache.getRemainingTTL(key),\n\n    async mGet(keys, opts) {\n      const raw = await cache.mGet(keys, opts);\n      const out = new Map<K, V | undefined>();\n      for (const [k, v] of raw) out.set(k, v === undefined ? undefined : await dec(v));\n      return out;\n    },\n    async mSet(entries, opts) {\n      const encoded: Array<MSetEntry<K, U>> = [];\n      for (const entry of entries) {\n        const [k, v, entryOpts] = entry;\n        if (entryOpts === undefined) encoded.push([k, await enc(v)]);\n        else encoded.push([k, await enc(v), entryOpts]);\n      }\n      return cache.mSet(encoded, opts);\n    },\n    mDelete: (keys) => cache.mDelete(keys),\n\n    keys: () => cache.keys(),\n    async values() {\n      const raw = await cache.values();\n      const out: V[] = [];\n      for (const v of raw) out.push(await dec(v));\n      return out;\n    },\n    async entries() {\n      const raw = await cache.entries();\n      const out: Array<[K, V]> = [];\n      for (const [k, v] of raw) out.push([k, await dec(v)]);\n      return out;\n    },\n    size: () => cache.size(),\n    async *[Symbol.asyncIterator]() {\n      for (const [k, v] of await this.entries()) yield [k, v];\n    },\n\n    clear: () => cache.clear(),\n    destroy: () => cache.destroy(),\n    healthCheck: () => cache.healthCheck(),\n    purgeStale: () => cache.purgeStale(),\n    stats: () => cache.stats(),\n\n    async fetch(key, fetcher, opts) {\n      // Reuse the underlying cache.fetch single-flight path. Pass an inner\n      // fetcher that encodes the produced value — the cache stores and returns\n      // the encoded form, then we decode on the way out.\n      const raw = await cache.fetch(key, async (k) => await enc(await fetcher(k)), opts);\n      return await dec(raw);\n    },\n  };\n\n  return wrapped;\n}\n"],"mappings":"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","names":["index_exports","__export","LRUCacheClustered","index_default","memoize","wrap","__toCommonJS","import_node_cluster","import_node_events","import_node_cluster","import_debug","import_lru_cache","SOURCE","DEBUG_PREFIX","serializeError","err","serializeErrorAt","depth","seen","out","code","cause","deserializeError","payload","isInvalidationPush","value","SOURCE","push","debug","Debug","DEBUG_PREFIX","messagesDebug","FETCH_LEASE_MS","STATE_KEY","primaryState","caches","stats","versions","fetchLocks","getNamespaceVersion","namespace","bumpNamespaceVersion","next","freshStats","getStats","s","readOptions","cache","c","getCacheForPayload","payload","existing","getOrCreateCache","assertOptionsCompatible","options","current","mismatches","key","value","requireNonNullish","label","buildSetOptions","opts","out","readEntrySize","info","getFetchNamespaceLocks","locks","cleanupFetchNamespaceLocks","releaseFetchLocksForWorker","workerId","lock","buildCache","cacheOptions","_value","_key","reason","defaultedOptions","dispatchOp","context","isNew","cacheExisted","statsExisted","locksExisted","existed","deleted","entries","entryOpts","keys","entry","safeKey","purged","base","delta","size","setOpts","now","token","replacement","op","BULK_BROADCAST_OPS","buildInvalidation","version","SOURCE","broadcastInvalidation","msg","worker","cluster","err","dispatchAndBroadcast","before","after","handleRequest","request","isOurRequest","ok","e","cause","serializeError","installClusterListener","attachWorkerHandler","raw","response","import_node_timers","import_debug","messagesDebug","Debug","DEBUG_PREFIX","nextRequestId","createIpcClient","proc","callbacks","subscribers","raw","isOurResponse","cb","isInvalidationPush","set","handler","err","send","opts","payload","id","request","SOURCE","resolve","reject","timer","response","deserializeError","error","namespace","s","value","cachedDefaultClient","getDefaultClient","msg","event","import_lru_cache","objectKeyIds","nextObjectKeyId","objectKeyId","key","id","encodeL1Key","FRESH_STATS","LocalL1Cache","#cache","#ttl","#latestSeen","#stats","#emit","opts","lruOpts","value","reason","encodedKey","eventKey","status","entry","version","ttl","setOpts","#setOptions","emit","capped","memoize","cache","fn","keyFn","opts","args","key","wrap","cache","codec","enc","v","dec","u","key","opts","raw","value","keys","out","k","entries","encoded","entry","entryOpts","fetcher","cluster","installClusterListener","FETCH_POLL_MS","DEFAULT_L1_TTL_MS","DEFAULT_L1_MAX","localInvalidationSubscribers","LOCAL_BULK_INVALIDATION_OPS","subscribeLocalInvalidations","namespace","handler","set","current","emitLocalInvalidation","msg","exclude","shouldEmitLocalInvalidation","payload","value","buildLocalInvalidation","version","SOURCE","key","normalizeL1","raw","primary","opts","requestedTtl","cappedTtl","ttl","methods","encodeL1KeyOrUndefined","encodeL1Key","LRUCacheClustered","_LRUCacheClustered","#lruOptions","#inFlight","#emitter","#l1","#l1Methods","#l1Invalidation","#l1CacheUndefined","#l1InvalidationHandler","#unsubscribeL1","options","_n","_t","_f","_ni","_l1","lruOpts","l1Config","LocalL1Cache","event","getOrCreateCache","getNamespaceVersion","#installL1Subscription","#dispatchWithMeta","r","instance","caches","useL1","hit","#getLocal","#setLocalFromPrimary","#deleteLocal","keys","values","remainingKeys","k","out","l1Populates","v","entries","arr","entry","#dispatch","amount","next","#dispatchRequired","listener","wrapper","t","prop","fetcher","all","pair","useFetchL1","cachedLocal","existing","slot","cached","forceRefresh","claim","stored","error","observed","resolve","handle","#applyL1Invalidation","unsubscribeLocal","unsubscribeIpc","getDefaultClient","enc","#remainingLocalTTL","#emitLocalInvalidation","failsafe","request","dispatchAndBroadcast","e","index_default","LRUCacheClustered"]}