{"version":3,"sources":["../src/vercel-kv.ts"],"names":["defaultKv"],"mappings":"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","file":"vercel-kv.cjs","sourcesContent":["/**\n * Vercel KV adapters — drop-in `SubscriptionStateAdapter`,\n * `OAuthTokenStore`, and `IdempotencyCache` implementations backed by\n * [Vercel KV](https://vercel.com/docs/storage/vercel-kv) (Upstash Redis).\n *\n * # Why a separate subpath?\n *\n * `@vercel/kv` is a peer dependency — only consumers who actually use Vercel\n * KV install it. Importing from `@ar-agents/mercadopago/vercel-kv` is\n * lazy: the main `@ar-agents/mercadopago` bundle stays tiny for callers who\n * use the in-memory adapters or a different store.\n *\n * # Setup\n *\n * 1. Create a KV store at https://vercel.com/dashboard/stores\n * 2. Connect it to your project — Vercel auto-injects `KV_*` env vars\n * 3. `pnpm add @vercel/kv`\n * 4. Wire the adapters:\n *\n *    ```ts\n *    import { mercadoPagoTools, MercadoPagoClient } from \"@ar-agents/mercadopago\";\n *    import {\n *      VercelKVSubscriptionStateAdapter,\n *      VercelKVOAuthTokenStore,\n *    } from \"@ar-agents/mercadopago/vercel-kv\";\n *\n *    const tools = mercadoPagoTools(client, {\n *      state: new VercelKVSubscriptionStateAdapter(),\n *      backUrl: \"https://mysite.com/done\",\n *      // ... oauth, webhookSecret, etc.\n *    });\n *\n *    // For marketplace flows, also wire the OAuth token store:\n *    const oauthStore = new VercelKVOAuthTokenStore();\n *    await oauthStore.set(token.user_id, {\n *      user_id: token.user_id,\n *      access_token: token.access_token,\n *      refresh_token: token.refresh_token!,\n *      expires_at: Date.now() + (token.expires_in ?? 21600) * 1000,\n *    });\n *    ```\n *\n * # Edge Runtime\n *\n * `@vercel/kv` works in Vercel Edge Runtime, Node.js, and any environment\n * with `fetch` (it's a thin REST client over Upstash). All adapters here\n * are async and Edge-safe.\n *\n * # Key namespacing\n *\n * Each adapter uses its own prefix so multiple adapters can share the same\n * KV store without collisions:\n * - Subscriptions: `mp:sub:{id}`\n * - OAuth tokens:  `mp:oauth:{userId}`\n * - Idempotency:   `mp:idem:{key}`\n *\n * Pass a custom prefix via the constructor if you need to share the store\n * with other apps.\n */\n\nimport { kv as defaultKv } from \"@vercel/kv\";\nimport type { VercelKV } from \"@vercel/kv\";\nimport type { AuditEntry, AuditLogAdapter, AuditOperation } from \"./audit\";\nimport type {\n  IdempotencyCache,\n  OAuthTokenRecord,\n  OAuthTokenStore,\n  SubscriptionStateAdapter,\n  SubscriptionStateRecord,\n} from \"./state\";\n\nconst DEFAULT_SUBSCRIPTION_PREFIX = \"mp:sub:\";\nconst DEFAULT_OAUTH_PREFIX = \"mp:oauth:\";\nconst DEFAULT_IDEMPOTENCY_PREFIX = \"mp:idem:\";\nconst DEFAULT_AUDIT_PREFIX = \"mp:audit:\";\n\ninterface VercelKVAdapterOptions {\n  /**\n   * Custom KV client. If omitted, uses the default `kv` export from\n   * `@vercel/kv` (which reads `KV_REST_API_URL` + `KV_REST_API_TOKEN` from\n   * env — auto-injected when you connect a KV store to your Vercel project).\n   */\n  kv?: VercelKV;\n  /** Override the key prefix. */\n  prefix?: string;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SubscriptionStateAdapter\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class VercelKVSubscriptionStateAdapter\n  implements SubscriptionStateAdapter\n{\n  private readonly kv: VercelKV;\n  private readonly prefix: string;\n  private readonly indexKey: string;\n\n  constructor(options: VercelKVAdapterOptions = {}) {\n    this.kv = options.kv ?? defaultKv;\n    this.prefix = options.prefix ?? DEFAULT_SUBSCRIPTION_PREFIX;\n    this.indexKey = `${this.prefix}__index`;\n  }\n\n  private key(id: string): string {\n    return `${this.prefix}${id}`;\n  }\n\n  async set(\n    id: string,\n    state: Partial<SubscriptionStateRecord>,\n  ): Promise<void> {\n    const existing = (await this.kv.get<SubscriptionStateRecord>(this.key(id))) ?? {};\n    await this.kv.set(this.key(id), { ...existing, ...state });\n    await this.kv.sadd(this.indexKey, id);\n  }\n\n  async get(id: string): Promise<SubscriptionStateRecord | null> {\n    return (await this.kv.get<SubscriptionStateRecord>(this.key(id))) ?? null;\n  }\n\n  async list(): Promise<string[]> {\n    const ids = await this.kv.smembers(this.indexKey);\n    return ids.map(String);\n  }\n\n  /** Forget a subscription record. NOT part of the adapter interface. */\n  async delete(id: string): Promise<void> {\n    await this.kv.del(this.key(id));\n    await this.kv.srem(this.indexKey, id);\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OAuthTokenStore (per-seller marketplace token persistence)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class VercelKVOAuthTokenStore implements OAuthTokenStore {\n  private readonly kv: VercelKV;\n  private readonly prefix: string;\n  private readonly indexKey: string;\n\n  constructor(options: VercelKVAdapterOptions = {}) {\n    this.kv = options.kv ?? defaultKv;\n    this.prefix = options.prefix ?? DEFAULT_OAUTH_PREFIX;\n    this.indexKey = `${this.prefix}__index`;\n  }\n\n  private key(userId: string): string {\n    return `${this.prefix}${userId}`;\n  }\n\n  async set(userId: string, token: OAuthTokenRecord): Promise<void> {\n    await this.kv.set(this.key(userId), token);\n    await this.kv.sadd(this.indexKey, userId);\n  }\n\n  async get(userId: string): Promise<OAuthTokenRecord | null> {\n    return (await this.kv.get<OAuthTokenRecord>(this.key(userId))) ?? null;\n  }\n\n  async delete(userId: string): Promise<void> {\n    await this.kv.del(this.key(userId));\n    await this.kv.srem(this.indexKey, userId);\n  }\n\n  async list(): Promise<string[]> {\n    const ids = await this.kv.smembers(this.indexKey);\n    return ids.map(String);\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Distributed Token Bucket Rate Limiter (KV-backed)\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst DEFAULT_RATELIMIT_PREFIX = \"mp:rl:\";\n\n/**\n * Distributed token bucket rate limiter backed by Vercel KV.\n *\n * # Why distributed\n *\n * The default in-memory `TokenBucketRateLimiter` is per-process. In\n * serverless (Vercel Functions, Lambda, Cloudflare Workers), each cold\n * start gets its own bucket — meaning N concurrent instances effectively\n * have N×capacity. For multi-region deployments or marketplace setups\n * with shared MP rate budget, that's a footgun.\n *\n * This adapter uses a single Vercel KV (Upstash Redis) bucket per `key`,\n * shared across all instances. Two instances acquiring at the same time\n * decrement the same counter atomically — the rate limit holds globally.\n *\n * # Algorithm\n *\n * Standard token bucket with lazy refill. Each `acquire()` / `tryAcquire()`\n * runs a single server-side Lua script ({@link LUA_CONSUME}) that, in one\n * atomic Redis execution:\n * 1. Reads `{ tokens, lastRefill }` from KV\n * 2. Computes refill since `lastRefill`\n * 3. If tokens >= 1: decrements and writes back\n * 4. Otherwise: returns the refilled count so the caller can compute its wait\n *\n * Because the refill → check → decrement → write happens inside one Lua\n * script, the decrement is atomic across all instances: concurrent callers can\n * never both consume the same token, so the global limit holds exactly (no\n * over-spend window). `learnFromHeaders` uses the same atomic primitive.\n *\n * # Usage — wire via `withRateLimit` middleware\n *\n * `MercadoPagoClient` does not accept a rate limiter directly. Apply the\n * limiter at the tool layer using `withRateLimit` from the middleware\n * module, which works for both the in-memory `TokenBucketRateLimiter` and\n * this distributed variant.\n *\n * ```ts\n * import {\n *   MercadoPagoClient,\n *   mercadoPagoTools,\n *   InMemoryStateAdapter,\n *   applyToAllTools,\n *   withRateLimit,\n * } from \"@ar-agents/mercadopago\";\n * import { VercelKVRateLimiter } from \"@ar-agents/mercadopago/vercel-kv\";\n *\n * // ONE distributed bucket shared across all serverless instances of this app:\n * const limiter = new VercelKVRateLimiter({\n *   key: \"mp-account-prod\",\n *   capacity: 50,\n *   refillPerSecond: 25,\n * });\n *\n * const client = new MercadoPagoClient({ accessToken: process.env.MP_ACCESS_TOKEN! });\n * const tools = applyToAllTools(\n *   mercadoPagoTools(client, { state: new InMemoryStateAdapter(), backUrl: \"...\" }),\n *   withRateLimit(limiter),\n * );\n * ```\n *\n * # Concurrency\n *\n * Token consumption is atomic (one Upstash `EVAL` Lua script per acquire), so\n * the configured limit holds exactly across all serverless instances even\n * under heavy concurrent contention — there is no over-spend window. The\n * `acquire()` retry loop still applies randomized jitter (±30%) to spread\n * waiting acquirers across refill windows, mitigating the thundering-herd that\n * would otherwise hit Upstash the instant a bucket refills.\n *\n * Note this caps **count** of calls, not monetary spend. For a hard money\n * budget, enforce it at the payment layer (amount checks + idempotency), not\n * with a request-rate limiter.\n *\n * # Marketplace setups (per-seller rate limit)\n *\n * Use the seller's MP user_id as part of the `key`:\n *\n * ```ts\n * function makeLimiter(sellerUserId: string) {\n *   return new VercelKVRateLimiter({\n *     key: `mp-seller-${sellerUserId}`,\n *     capacity: 10,\n *     refillPerSecond: 5,\n *   });\n * }\n * ```\n *\n * Each seller now has their own globally-distributed bucket.\n */\nexport interface VercelKVRateLimiterOptions extends VercelKVAdapterOptions {\n  /**\n   * Unique key for this bucket. Use distinct keys per logical \"rate-limit\n   * scope\" (per-environment, per-seller, per-region, etc.). Required.\n   */\n  key: string;\n  /** Bucket capacity (max burst). Default 50. */\n  capacity?: number;\n  /** Refill rate in tokens per second. Default 25. */\n  refillPerSecond?: number;\n  /**\n   * Hard cap on how long `acquire()` will wait. If the bucket can't\n   * refill in this time, `acquire()` throws. Default 30s.\n   */\n  acquireTimeoutMs?: number;\n  /**\n   * If true, `learnFromHeaders` syncs the bucket with MP's stated\n   * `x-rate-limit-remaining`. Default true.\n   */\n  adaptive?: boolean;\n}\n\ninterface BucketState {\n  tokens: number;\n  lastRefillMs: number;\n}\n\n/** Bucket TTL (seconds). Long-idle buckets are GC'd; capacity rebuilds. */\nconst RATELIMIT_TTL_SECONDS = 3600;\n\n/**\n * Atomic token-bucket consume, executed server-side as a single Redis Lua\n * script so the read → refill → check → decrement → write sequence cannot\n * interleave across concurrent callers (the previous JS-side read-modify-write\n * let N concurrent acquirers all observe the same lone token and each succeed).\n *\n * KEYS[1] = bucket key.\n * ARGV    = [capacity, refillPerSecond, nowMs, cost, ttlSeconds].\n * Returns [allowed (0|1), tokensRemaining (string)]. Persists ONLY on success\n * (a denied attempt leaves lastRefill untouched, so accrual stays continuous).\n *\n * State is a JSON string compatible with `@upstash/redis`'s auto (de)serializer\n * — `cjson` is available in Upstash's Lua runtime.\n */\nconst LUA_CONSUME = `-- @op:consume\nlocal raw = redis.call('GET', KEYS[1])\nlocal capacity = tonumber(ARGV[1])\nlocal refillPerSecond = tonumber(ARGV[2])\nlocal now = tonumber(ARGV[3])\nlocal cost = tonumber(ARGV[4])\nlocal ttl = tonumber(ARGV[5])\nlocal tokens = capacity\nlocal lastRefill = now\nif raw then\n  local ok, data = pcall(cjson.decode, raw)\n  if ok and type(data) == 'table' and type(data.tokens) == 'number' and type(data.lastRefillMs) == 'number' then\n    tokens = data.tokens\n    lastRefill = data.lastRefillMs\n  end\nend\nlocal elapsed = now - lastRefill\nif elapsed < 0 then elapsed = 0 end\ntokens = math.min(capacity, tokens + (elapsed / 1000.0) * refillPerSecond)\nlocal allowed = 0\nif tokens >= cost then\n  tokens = tokens - cost\n  allowed = 1\n  redis.call('SET', KEYS[1], cjson.encode({tokens = tokens, lastRefillMs = now}), 'EX', ttl)\nend\nreturn {allowed, tostring(tokens)}`;\n\n/**\n * Atomic adaptive clamp for `learnFromHeaders`: refill, then lower the bucket\n * to MP's stated remaining if that is smaller. Same atomicity guarantee as\n * {@link LUA_CONSUME} so a concurrent acquire can't race the clamp.\n *\n * KEYS[1] = bucket key.\n * ARGV    = [capacity, refillPerSecond, nowMs, remaining, ttlSeconds].\n * Returns tokensRemaining (string).\n */\nconst LUA_CLAMP = `-- @op:clamp\nlocal raw = redis.call('GET', KEYS[1])\nlocal capacity = tonumber(ARGV[1])\nlocal refillPerSecond = tonumber(ARGV[2])\nlocal now = tonumber(ARGV[3])\nlocal remaining = tonumber(ARGV[4])\nlocal ttl = tonumber(ARGV[5])\nlocal tokens = capacity\nlocal lastRefill = now\nif raw then\n  local ok, data = pcall(cjson.decode, raw)\n  if ok and type(data) == 'table' and type(data.tokens) == 'number' and type(data.lastRefillMs) == 'number' then\n    tokens = data.tokens\n    lastRefill = data.lastRefillMs\n  end\nend\nlocal elapsed = now - lastRefill\nif elapsed < 0 then elapsed = 0 end\ntokens = math.min(capacity, tokens + (elapsed / 1000.0) * refillPerSecond)\nif remaining < tokens then\n  if remaining < 0 then remaining = 0 end\n  tokens = remaining\nend\nredis.call('SET', KEYS[1], cjson.encode({tokens = tokens, lastRefillMs = now}), 'EX', ttl)\nreturn tostring(tokens)`;\n\nexport class VercelKVRateLimiter {\n  private readonly kv: VercelKV;\n  private readonly prefix: string;\n  private readonly key: string;\n  private readonly capacity: number;\n  private readonly refillPerSecond: number;\n  private readonly acquireTimeoutMs: number;\n  private readonly adaptive: boolean;\n\n  constructor(options: VercelKVRateLimiterOptions) {\n    if (!options.key) {\n      throw new Error(\n        \"VercelKVRateLimiter requires a `key` (use distinct keys per rate-limit scope, e.g., per-environment or per-seller).\",\n      );\n    }\n    this.kv = options.kv ?? defaultKv;\n    this.prefix = options.prefix ?? DEFAULT_RATELIMIT_PREFIX;\n    this.key = options.key;\n    this.capacity = options.capacity ?? 50;\n    this.refillPerSecond = options.refillPerSecond ?? 25;\n    this.acquireTimeoutMs = options.acquireTimeoutMs ?? 30_000;\n    this.adaptive = options.adaptive ?? true;\n  }\n\n  private fullKey(): string {\n    return `${this.prefix}${this.key}`;\n  }\n\n  private async readState(): Promise<BucketState> {\n    const stored = await this.kv.get<BucketState>(this.fullKey());\n    if (stored && typeof stored.tokens === \"number\" && typeof stored.lastRefillMs === \"number\") {\n      return stored;\n    }\n    return { tokens: this.capacity, lastRefillMs: Date.now() };\n  }\n\n  private refill(state: BucketState, nowMs: number): BucketState {\n    const elapsedMs = Math.max(0, nowMs - state.lastRefillMs);\n    const refilled = Math.min(\n      this.capacity,\n      state.tokens + (elapsedMs / 1000) * this.refillPerSecond,\n    );\n    return { tokens: refilled, lastRefillMs: nowMs };\n  }\n\n  private async writeState(state: BucketState): Promise<void> {\n    // TTL = 1h. Long-idle buckets get garbage-collected, capacity rebuilds\n    // from initial state on next acquire (which is fine — at the right rate).\n    await this.kv.set(this.fullKey(), state, { ex: RATELIMIT_TTL_SECONDS });\n  }\n\n  /**\n   * Atomically refill + conditionally consume `cost` tokens via a single\n   * server-side Lua script ({@link LUA_CONSUME}). This is the enforcement\n   * primitive: because Redis runs the script atomically, concurrent callers\n   * can never both consume the same token.\n   */\n  private async consume(\n    cost: number,\n  ): Promise<{ allowed: boolean; tokens: number }> {\n    const now = Date.now();\n    const res = (await this.kv.eval(\n      LUA_CONSUME,\n      [this.fullKey()],\n      [this.capacity, this.refillPerSecond, now, cost, RATELIMIT_TTL_SECONDS],\n    )) as [number | string, number | string];\n    return { allowed: Number(res[0]) === 1, tokens: Number(res[1]) };\n  }\n\n  /**\n   * Acquire a token. Resolves immediately if the distributed bucket has\n   * one available; otherwise waits until refilled. Throws if the wait\n   * exceeds `acquireTimeoutMs` or if the retry cap is reached.\n   *\n   * Each attempt consumes via the atomic {@link LUA_CONSUME} script, so the\n   * limit holds globally even under heavy concurrent contention.\n   *\n   * Caps retries at 8 iterations so a misconfigured bucket (capacity too\n   * low for traffic) fails fast for the agent layer to surface, instead\n   * of silently burning serverless compute time.\n   */\n  async acquire(): Promise<void> {\n    const start = Date.now();\n    const MAX_RETRIES = 8;\n    let attempt = 0;\n    while (attempt < MAX_RETRIES) {\n      const { allowed, tokens } = await this.consume(1);\n      if (allowed) return;\n\n      // Compute wait time until next token. Cap at remaining timeout budget.\n      const tokensNeeded = 1 - tokens;\n      const baseWaitMs = Math.ceil((tokensNeeded / this.refillPerSecond) * 1000);\n      // Randomized jitter (±30%) prevents thundering herd: without it, all\n      // concurrent acquirers compute identical waitMs, sleep identical\n      // duration, and wake at the same wall-clock instant — then all hit\n      // KV simultaneously. Jitter spreads them across the refill window.\n      const jitterFactor = 0.7 + Math.random() * 0.6; // 0.7–1.3\n      const waitMs = Math.ceil(baseWaitMs * jitterFactor);\n      const elapsed = Date.now() - start;\n      if (elapsed + waitMs > this.acquireTimeoutMs) {\n        throw new Error(\n          `VercelKVRateLimiter acquire timed out after ${elapsed + waitMs}ms (key=${this.key}).`,\n        );\n      }\n      await new Promise((resolve) => setTimeout(resolve, waitMs));\n      attempt += 1;\n    }\n    throw new Error(\n      `VercelKVRateLimiter exhausted ${MAX_RETRIES} retries (key=${this.key}). ` +\n        `Bucket likely undersized for traffic — increase capacity or refillPerSecond.`,\n    );\n  }\n\n  /** Best-effort acquire — returns true if a token was available, false otherwise. */\n  async tryAcquire(): Promise<boolean> {\n    const { allowed } = await this.consume(1);\n    return allowed;\n  }\n\n  /**\n   * Adaptive learning — call after each MP API response. If MP's stated\n   * `x-rate-limit-remaining` is lower than our local count, trust MP and\n   * drop the bucket to match (prevents over-spending). Applied atomically via\n   * {@link LUA_CLAMP} so it can't race a concurrent acquire.\n   */\n  async learnFromHeaders(headers: {\n    remaining: number | null;\n    resetSeconds: number | null;\n  }): Promise<void> {\n    if (!this.adaptive) return;\n    if (headers.remaining === null) return;\n    await this.kv.eval(\n      LUA_CLAMP,\n      [this.fullKey()],\n      [\n        this.capacity,\n        this.refillPerSecond,\n        Date.now(),\n        headers.remaining,\n        RATELIMIT_TTL_SECONDS,\n      ],\n    );\n  }\n\n  /** Inspect bucket state. */\n  async getStats(): Promise<{ tokens: number; capacity: number; refillPerSecond: number }> {\n    const state = this.refill(await this.readState(), Date.now());\n    return {\n      tokens: state.tokens,\n      capacity: this.capacity,\n      refillPerSecond: this.refillPerSecond,\n    };\n  }\n\n  /** Reset the bucket to full. Use sparingly (e.g., after a known-clean window). */\n  async reset(): Promise<void> {\n    await this.writeState({ tokens: this.capacity, lastRefillMs: Date.now() });\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// IdempotencyCache (KV-backed dedup of agent retries)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class VercelKVIdempotencyCache implements IdempotencyCache {\n  private readonly kv: VercelKV;\n  private readonly prefix: string;\n\n  constructor(options: VercelKVAdapterOptions = {}) {\n    this.kv = options.kv ?? defaultKv;\n    this.prefix = options.prefix ?? DEFAULT_IDEMPOTENCY_PREFIX;\n  }\n\n  private key(k: string): string {\n    return `${this.prefix}${k}`;\n  }\n\n  async get<T>(key: string): Promise<T | null> {\n    return (await this.kv.get<T>(this.key(key))) ?? null;\n  }\n\n  async set<T>(key: string, value: T, ttlSeconds = 86_400): Promise<void> {\n    // Vercel KV's `set` supports a TTL in seconds via the `ex` option.\n    await this.kv.set(this.key(key), value, { ex: ttlSeconds });\n  }\n\n  async delete(key: string): Promise<void> {\n    await this.kv.del(this.key(key));\n  }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// AuditLogAdapter — production audit trail with daily-bucket indexing\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Vercel KV–backed audit log adapter. Stores each entry under\n * `mp:audit:entry:{id}` AND adds the id to a daily index sorted set\n * `mp:audit:day:{YYYY-MM-DD}` (score = timestamp ms). This gives O(log N)\n * time-range queries (\"all entries from May 1 to May 5\") without scanning\n * the entire log.\n *\n * # Storage layout\n *\n * - `mp:audit:entry:{id}` → the full entry JSON\n * - `mp:audit:day:{YYYY-MM-DD}` → ZSET of entry ids by timestamp (ms)\n * - `mp:audit:actor:{actor}` → ZSET of entry ids by timestamp (for \"all\n *   entries by actor X\")\n * - `mp:audit:tenant:{tenantId}` → same, by tenant\n *\n * # Cost considerations\n *\n * Each `append()` does 1-3 KV writes (entry + 1-2 indexes). For high-traffic\n * deployments (>10/s sustained), batch via your own queue (e.g., Vercel\n * Queues with daily flush) and provide a custom adapter that batches.\n */\nexport class VercelKVAuditLog implements AuditLogAdapter {\n  private readonly kv: VercelKV;\n  private readonly prefix: string;\n\n  constructor(options: VercelKVAdapterOptions = {}) {\n    this.kv = options.kv ?? defaultKv;\n    this.prefix = options.prefix ?? DEFAULT_AUDIT_PREFIX;\n  }\n\n  async append(entry: AuditEntry): Promise<void> {\n    const ts = new Date(entry.timestamp).getTime();\n    const day = entry.timestamp.slice(0, 10); // YYYY-MM-DD\n    await Promise.all([\n      this.kv.set(`${this.prefix}entry:${entry.id}`, entry),\n      this.kv.zadd(`${this.prefix}day:${day}`, { score: ts, member: entry.id }),\n      this.kv.zadd(`${this.prefix}actor:${entry.actor}`, { score: ts, member: entry.id }),\n      ...(entry.tenantId\n        ? [\n            this.kv.zadd(`${this.prefix}tenant:${entry.tenantId}`, {\n              score: ts,\n              member: entry.id,\n            }),\n          ]\n        : []),\n    ]);\n  }\n\n  async query(filter: {\n    actor?: string;\n    operation?: AuditOperation;\n    tenantId?: string;\n    from?: string;\n    to?: string;\n    limit?: number;\n  }): Promise<AuditEntry[]> {\n    const limit = filter.limit ?? 100;\n    let ids: string[];\n\n    // Pick the most selective index available\n    if (filter.actor) {\n      ids = await this.zrangeByScore(\n        `${this.prefix}actor:${filter.actor}`,\n        filter.from,\n        filter.to,\n        limit,\n      );\n    } else if (filter.tenantId) {\n      ids = await this.zrangeByScore(\n        `${this.prefix}tenant:${filter.tenantId}`,\n        filter.from,\n        filter.to,\n        limit,\n      );\n    } else if (filter.from || filter.to) {\n      // Walk daily buckets for the date range\n      const fromDate = filter.from?.slice(0, 10) ?? \"0000-00-00\";\n      const toDate = filter.to?.slice(0, 10) ?? \"9999-99-99\";\n      ids = [];\n      // Cap walk to ~1 year max to avoid runaway\n      const fromTs = new Date(fromDate).getTime();\n      const toTs = new Date(toDate).getTime();\n      for (let d = fromTs; d <= toTs && ids.length < limit; d += 86_400_000) {\n        const day = new Date(d).toISOString().slice(0, 10);\n        const dayIds = await this.zrangeByScore(\n          `${this.prefix}day:${day}`,\n          filter.from,\n          filter.to,\n          limit - ids.length,\n        );\n        ids.push(...dayIds);\n      }\n    } else {\n      // No filter — bail (full scan would be unbounded)\n      return [];\n    }\n\n    // Load entries\n    const entries: AuditEntry[] = [];\n    for (const id of ids) {\n      const entry = await this.kv.get<AuditEntry>(`${this.prefix}entry:${id}`);\n      if (!entry) continue;\n      if (filter.operation && entry.operation !== filter.operation) continue;\n      entries.push(entry);\n    }\n    return entries;\n  }\n\n  private async zrangeByScore(\n    key: string,\n    from?: string,\n    to?: string,\n    limit?: number,\n  ): Promise<string[]> {\n    const min = from ? new Date(from).getTime() : 0;\n    const max = to ? new Date(to).getTime() : Number.MAX_SAFE_INTEGER;\n    const opts = {\n      byScore: true as const,\n      offset: 0,\n      ...(limit !== undefined ? { count: limit } : { count: 100 }),\n    };\n    const ids = await this.kv.zrange(key, min, max, opts);\n    return ids.map(String);\n  }\n}\n"]}