import { AsyncLocalStorage } from 'async_hooks'; import type { CacheStrategy } from '@nestjs-crud/core/cache'; export interface PrismaAccelerateContext { /** Accelerate's `cacheStrategy.ttl` is in **SECONDS** (per Accelerate API contract). */ cacheStrategy?: { ttl: number; }; } interface PrismaClientWithAccelerate { $accelerate?: { invalidate: (args: { tags: string[]; }) => Promise; }; } /** * Prisma Accelerate-backed `CacheStrategy`. * * Accelerate caches at the API gateway, not in process memory. Its * `cacheStrategy: { ttl }` option is passed PER-QUERY into `findMany`/`findFirst`, * not as a wrapper around the result. This strategy bridges the two worlds: * * `PrismaAccelerateCacheStrategy.wrap(key, fetchFn, ttl)` attaches * `{ cacheStrategy: { ttl: ttlSeconds } }` to a process-wide `AsyncLocalStorage` * context while `fetchFn()` runs. `PrismaFetchHelper` reads the context inside * its `executeMany`/`findOneOrFail` and merges `cacheStrategy: { ttl }` into the * Prisma delegate args before invoking the query. * * Concurrent requests do not bleed TTL into each other's args — `AsyncLocalStorage` * isolates per async-call-stack. * * **TTL units (FIX 1):** the unified `CacheStrategy.wrap(...)` contract takes * `ttl` in MILLISECONDS, but Accelerate's per-query `cacheStrategy: { ttl }` * option takes SECONDS. This strategy is the ONLY adapter strategy that * performs unit conversion — `ttlSeconds = Math.ceil(ttl / 1000)` — to bridge * the two contracts. Round-up via `Math.ceil` ensures we never under-cache * (e.g. `ttl=1500ms` rounds up to 2 seconds, not 1). * * `invalidate(prefix)` calls `$accelerate.invalidate({ tags: [prefix] })`. * Accelerate accepts up to 5 tags per call; we always pass exactly 1 (the * entity-name prefix), so the limit is never reached. * * Requires `@prisma/extension-accelerate@^3.0.0` (declared as an optional peer * on `@nestjs-crud/prisma` per FIX 10). The constructor throws if the consumer's * `PrismaClient` was not extended with `withAccelerate()` (no `$accelerate` * method present on the client). * * @since 2.2.0 */ export declare class PrismaAccelerateCacheStrategy implements CacheStrategy { private readonly prisma; /** * Per-async-stack context. `PrismaFetchHelper` reads `getStore()` to learn the * TTL the consumer asked for (in seconds), then merges into delegate args. */ static readonly currentContext: AsyncLocalStorage; constructor(prisma: PrismaClientWithAccelerate); wrap(_key: string, fetchFn: () => Promise, ttl: number): Promise; get(_key: string): Promise; set(_key: string, _value: T, _ttl: number): Promise; invalidate(prefix: string): Promise; } export {};