{"version":3,"sources":["../src/transformer.ts"],"sourcesContent":["import type { Transformer } from '@walkeros/core';\nimport { compileMatcher } from '@walkeros/core';\nimport type { RespondFn, RespondOptions } from '@walkeros/core';\nimport { createMemoryStore } from '@walkeros/store-memory';\nimport type {\n  CacheSettings,\n  CacheRule,\n  CacheEntry,\n  CacheEnv,\n  Types,\n} from './types';\n\ninterface CompiledRule {\n  matcher: (ingest: Record<string, unknown>) => boolean;\n  key: string[];\n  ttl: number;\n  headers?: Record<string, string>;\n}\n\nexport const transformerCache: Transformer.Init<Types> = (context) => {\n  const { config } = context;\n  const settings = (config.settings || {}) as Partial<CacheSettings>;\n  const rules: CacheRule[] = settings.rules || [];\n  const maxSize = settings.maxSize;\n\n  const store =\n    (context.env as CacheEnv).store ??\n    createMemoryStore<CacheEntry>({ maxSize });\n\n  // Pre-compile matchers\n  const compiledRules: CompiledRule[] = rules.map((rule) => ({\n    matcher: compileMatcher(rule.match),\n    key: rule.key,\n    ttl: rule.ttl,\n    headers: rule.headers,\n  }));\n\n  return {\n    type: 'cache',\n    config: config as Transformer.Config<Types>,\n\n    push(event, context) {\n      const { logger } = context;\n      const ingest = (context.ingest || {}) as Record<string, unknown>;\n      const envRespond = context.env.respond as RespondFn | undefined;\n\n      // Find first matching rule\n      const rule = compiledRules.find((r) => r.matcher(ingest));\n      if (!rule) return; // No match = passthrough\n\n      // Build cache key from ingest fields\n      const keyParts = rule.key.map((field) => String(ingest[field] ?? ''));\n      const keyValue = keyParts.join(':');\n\n      if (!keyValue || keyParts.every((p) => p === '')) {\n        logger.warn('Cache key is empty, skipping cache');\n        return;\n      }\n\n      // Check cache\n      const cached = store.get(keyValue) as CacheEntry | undefined;\n\n      if (cached) {\n        // HIT: respond directly and stop chain\n        envRespond?.({\n          body: cached.body,\n          status: cached.status as number | undefined,\n          headers: {\n            ...(cached.headers as Record<string, string> | undefined),\n            ...rule.headers,\n            'X-Cache': 'HIT',\n          },\n        });\n        return false;\n      }\n\n      // MISS: wrap respond to intercept and cache\n      const wrappedRespond: RespondFn = (options: RespondOptions = {}) => {\n        const entry: CacheEntry = {\n          body: options.body,\n          status: options.status,\n          headers: options.headers,\n        };\n        store.set(keyValue, entry, rule.ttl * 1000); // TTL: seconds → milliseconds\n\n        envRespond?.({\n          ...options,\n          headers: {\n            ...options.headers,\n            ...rule.headers,\n            'X-Cache': 'MISS',\n          },\n        });\n      };\n\n      return { respond: wrappedRespond };\n    },\n  };\n};\n"],"mappings":";AACA,SAAS,sBAAsB;AAE/B,SAAS,yBAAyB;AAgB3B,IAAM,mBAA4C,CAAC,YAAY;AAnBtE;AAoBE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAY,OAAO,YAAY,CAAC;AACtC,QAAM,QAAqB,SAAS,SAAS,CAAC;AAC9C,QAAM,UAAU,SAAS;AAEzB,QAAM,SACH,aAAQ,IAAiB,UAAzB,YACD,kBAA8B,EAAE,QAAQ,CAAC;AAG3C,QAAM,gBAAgC,MAAM,IAAI,CAAC,UAAU;AAAA,IACzD,SAAS,eAAe,KAAK,KAAK;AAAA,IAClC,KAAK,KAAK;AAAA,IACV,KAAK,KAAK;AAAA,IACV,SAAS,KAAK;AAAA,EAChB,EAAE;AAEF,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IAEA,KAAK,OAAOA,UAAS;AACnB,YAAM,EAAE,OAAO,IAAIA;AACnB,YAAM,SAAUA,SAAQ,UAAU,CAAC;AACnC,YAAM,aAAaA,SAAQ,IAAI;AAG/B,YAAM,OAAO,cAAc,KAAK,CAAC,MAAM,EAAE,QAAQ,MAAM,CAAC;AACxD,UAAI,CAAC,KAAM;AAGX,YAAM,WAAW,KAAK,IAAI,IAAI,CAAC,UAAO;AAnD5C,YAAAC;AAmD+C,uBAAOA,MAAA,OAAO,KAAK,MAAZ,OAAAA,MAAiB,EAAE;AAAA,OAAC;AACpE,YAAM,WAAW,SAAS,KAAK,GAAG;AAElC,UAAI,CAAC,YAAY,SAAS,MAAM,CAAC,MAAM,MAAM,EAAE,GAAG;AAChD,eAAO,KAAK,oCAAoC;AAChD;AAAA,MACF;AAGA,YAAM,SAAS,MAAM,IAAI,QAAQ;AAEjC,UAAI,QAAQ;AAEV,iDAAa;AAAA,UACX,MAAM,OAAO;AAAA,UACb,QAAQ,OAAO;AAAA,UACf,SAAS;AAAA,YACP,GAAI,OAAO;AAAA,YACX,GAAG,KAAK;AAAA,YACR,WAAW;AAAA,UACb;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAGA,YAAM,iBAA4B,CAAC,UAA0B,CAAC,MAAM;AAClE,cAAM,QAAoB;AAAA,UACxB,MAAM,QAAQ;AAAA,UACd,QAAQ,QAAQ;AAAA,UAChB,SAAS,QAAQ;AAAA,QACnB;AACA,cAAM,IAAI,UAAU,OAAO,KAAK,MAAM,GAAI;AAE1C,iDAAa;AAAA,UACX,GAAG;AAAA,UACH,SAAS;AAAA,YACP,GAAG,QAAQ;AAAA,YACX,GAAG,KAAK;AAAA,YACR,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAEA,aAAO,EAAE,SAAS,eAAe;AAAA,IACnC;AAAA,EACF;AACF;","names":["context","_a"]}