/** * Redis-compatible store. Works with any client that exposes: * - `eval(script, numkeys, ...args)` → number | string * - `pttl(key)` → number (ms; -2 missing, -1 no ttl) * - `get(key)` → string | null * - `set(key, value, 'PX', ms)` → 'OK' * - `del(key)` → number * * Verified compat: `ioredis`, `node-redis` (v4+), `@upstash/redis` (HTTP, * works on Cloudflare Workers / Vercel Edge / Deno Deploy). * * Atomicity: * - `incr` runs a single Lua script that INCR's the key and PEXPIRE's it * only when the key is fresh (count == 1). TTL anchors to the first * increment in the window — correct for fixed / token-bucket. * - `read` runs a Lua script (GET + PTTL) so the snapshot is consistent * even under contention. * * Optimization: when the client is `ioredis` (detected via `defineCommand`), * both scripts are registered once as named commands. Subsequent calls go * out as `EVALSHA`, saving the script body on every request. * * Namespacing: every key is prefixed with `rl:` by default so this adapter * doesn't collide with your application keys. Configurable via `prefix`. * * @param {object} client Redis-compatible client instance. * @param {{ prefix?: string }} [options] * @returns {import('../index.js').RateLimitStore} */ export function redisStore(client: object, options?: { prefix?: string; }): import("../index.js").RateLimitStore;