{"version":3,"file":"cache_event_handler.mjs","sources":["../../../src/private/utils/cache_event_handler.ts"],"sourcesContent":["/**\n * Process-wide registration + dispatch for the relation-cache EVENT hook\n * (`onRelationsCacheEvent`). The relation cache emits lifecycle events\n * (hit/miss/store/force/bypass/evict); the host decides what to do with them —\n * write to `@nhtio/logger` or Adonis' logger, push metrics, trace, or nothing.\n *\n * Defaults to a **no-op** so the package stays dependency-neutral: lucid-resourceful\n * never imports a logger of its own, and never bakes in an observability shape.\n *\n * @module @nhtio/lucid-resourceful/private/utils/cache_event_handler\n */\n\nimport type { LucidModel } from '@adonisjs/lucid/types/model'\n\n/**\n * A relation-cache lifecycle event:\n * - `hit` — a related row was served from cache (no DB query).\n * - `miss` — a cache miss; the row was loaded from the DB.\n * - `store` — a freshly-loaded row was written back to the cache.\n * - `force` — a `forceLoad` bypassed the read and refreshed the entry.\n * - `bypass` — caching was skipped (filtering callback / uncacheable relation).\n * - `evict` — a write-through eviction (`deleteByTag`) ran on a target's write.\n *\n * @public\n */\nexport type RelationCacheEvent = 'hit' | 'miss' | 'store' | 'force' | 'bypass' | 'evict'\n\n/**\n * Structured context for a relation-cache event. Fields are populated per event\n * (e.g. `tag`/`ttl` only on `store`, `tag` only on `evict`).\n *\n * @public\n */\nexport interface RelationCacheEventContext {\n  /** Canonical identity name of the model the event concerns. */\n  model: string\n  /** The relation name, when the event is tied to a specific relation load. */\n  relation?: string\n  /** The cache lookup key, when applicable. */\n  key?: string | null\n  /** The store / eviction tag, when applicable. */\n  tag?: string | null\n  /** The entry TTL forwarded on a `store`, when configured. */\n  ttl?: unknown\n}\n\n/**\n * Host-supplied observer for relation-cache lifecycle events. Observe-only: its\n * return value is ignored and a throw from it is swallowed.\n *\n * @public\n */\nexport type RelationsCacheEventHandler = (\n  event: RelationCacheEvent,\n  context: RelationCacheEventContext\n) => void\n\n/**\n * Module-scoped holder for the process-wide default event handler. A plain\n * function reference — nothing to memoize.\n * @internal\n */\nlet defaultRelationsCacheEventHandler: RelationsCacheEventHandler | null = null\n\n/**\n * Registers (or clears) the process-wide default relation-cache event handler.\n *\n * The host calls this once at boot; passing `null` clears it (used by tests).\n * Absent any handler the event is simply dropped — the package never logs on its\n * own.\n *\n * @param handler - The default event handler, or `null` to clear it.\n * @public\n */\nexport const setDefaultOnRelationsCacheEvent = (\n  handler: RelationsCacheEventHandler | null\n): void => {\n  defaultRelationsCacheEventHandler = handler\n}\n\n/**\n * Reads the currently-registered default event handler. Exposed for completeness;\n * prefer {@link reportRelationCacheEvent}.\n *\n * @returns The default handler, or `null` when none is registered.\n * @internal\n */\nexport const getDefaultOnRelationsCacheEvent = (): RelationsCacheEventHandler | null =>\n  defaultRelationsCacheEventHandler\n\n/**\n * Clears the module-scoped default event handler. Test-only hook: hosts must not\n * call this at runtime. Mirrors `resetRelationCacheTargets`.\n *\n * @public\n */\nexport const resetDefaultOnRelationsCacheEvent = (): void => {\n  defaultRelationsCacheEventHandler = null\n}\n\n/**\n * Dispatches a relation-cache event to the effective handler — the model's own\n * `$resourcefulOnRelationsCacheEvent` → the process-wide default → no-op.\n *\n * Invoked SYNCHRONOUSLY inside a guard (a throwing handler is swallowed) and\n * never awaited, so a host observer can neither break nor delay a cache op. When\n * no handler resolves, this returns immediately (no logger, no allocation).\n *\n * @param model - The model whose handler should be consulted.\n * @param event - The lifecycle event that occurred.\n * @param context - Structured context for the event.\n */\nexport const reportRelationCacheEvent = (\n  model: LucidModel,\n  event: RelationCacheEvent,\n  context: RelationCacheEventContext\n): void => {\n  const perModelHandler = (\n    model as LucidModel & { $resourcefulOnRelationsCacheEvent?: RelationsCacheEventHandler }\n  ).$resourcefulOnRelationsCacheEvent\n  const handler = perModelHandler ?? defaultRelationsCacheEventHandler\n  if (!handler) {\n    return\n  }\n  try {\n    handler(event, context)\n  } catch {\n    // Observe-only: a throwing event handler must never affect a cache op.\n  }\n}\n"],"names":[],"mappings":"AA8DA,IAAI,oCAAuE;AAYpE,MAAM,kCAAkC,CAC7C,YACS;AACT,sCAAoC;AACtC;AASO,MAAM,kCAAkC,MAC7C;AAQK,MAAM,oCAAoC,MAAY;AAC3D,sCAAoC;AACtC;AAcO,MAAM,2BAA2B,CACtC,OACA,OACA,YACS;AACT,QAAM,kBACJ,MACA;AACF,QAAM,UAAU,mBAAmB;AACnC,MAAI,CAAC,SAAS;AACZ;AAAA,EACF;AACA,MAAI;AACF,YAAQ,OAAO,OAAO;AAAA,EACxB,QAAQ;AAAA,EAER;AACF;"}