UNPKG

@safaricom-mxl/nextjs-turbo-redis-cache

Version:

Next.js redis cache handler

154 lines (150 loc) 5.72 kB
import { RedisClientOptions } from 'redis'; type CacheEntry = { value: unknown; lastModified: number; tags: string[]; }; type CreateRedisStringsHandlerOptions = { /** Redis redisUrl to use. * @default process.env.REDIS_URL? process.env.REDIS_URL : process.env.REDISHOST ? `redis://${process.env.REDISHOST}:${process.env.REDISPORT}` : 'redis://localhost:6379' */ redisUrl?: string; /** Redis database number to use. Uses DB 0 for production, DB 1 otherwise * @default process.env.VERCEL_ENV === 'production' ? 0 : 1 */ database?: number; /** Prefix added to all Redis keys * @default process.env.VERCEL_URL || 'UNDEFINED_URL_' */ keyPrefix?: string; /** Timeout in milliseconds for time critical Redis operations (during cache get, which blocks site rendering). * If redis get is not fulfilled within this time, the cache handler will return null so site rendering will * not be blocked further and site can fallback to re-render/re-fetch the content. * @default 500 */ getTimeoutMs?: number; /** Number of entries to query in one batch during full sync of shared tags hash map * @default 250 */ revalidateTagQuerySize?: number; /** Key used to store shared tags hash map in Redis * @default '__sharedTags__' */ sharedTagsKey?: string; /** Average interval in milliseconds between tag map full re-syncs * @default 3600000 (1 hour) */ avgResyncIntervalMs?: number; /** Enable deduplication of Redis get requests via internal in-memory cache * @default true */ redisGetDeduplication?: boolean; /** Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely * @default 10000 */ inMemoryCachingTime?: number; /** Default stale age in seconds for cached items * @default 1209600 (14 days) */ defaultStaleAge?: number; /** Function to calculate expire age (redis TTL value) from stale age * @default Production: staleAge * 2, Other: staleAge * 1.2 */ estimateExpireAge?: (staleAge: number) => number; /** Kill container on Redis client error if error threshold is reached * @default 0 (0 means no error threshold) */ killContainerOnErrorThreshold?: number; /** Additional Redis client socket options * @example { tls: true, rejectUnauthorized: false } */ socketOptions?: RedisClientOptions["socket"]; /** Additional Redis client options to be passed directly to createClient * @example { username: 'user', password: 'pass' } */ clientOptions?: Omit<RedisClientOptions, "url" | "database" | "socket">; }; declare class RedisStringsHandler { private client; private sharedTagsMap; private revalidatedTagsMap; private inMemoryDeduplicationCache; private getTimeoutMs; private redisGet; private redisDeduplicationHandler; private deduplicatedRedisGet; private keyPrefix; private redisGetDeduplication; private inMemoryCachingTime; private defaultStaleAge; private estimateExpireAge; private killContainerOnErrorThreshold; constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, }: CreateRedisStringsHandlerOptions); resetRequestCache(): void; close(): Promise<void>; private clientReadyCalls; private assertClientIsReady; get(key: string, ctx: { kind: "APP_ROUTE" | "APP_PAGE"; isRoutePPREnabled: boolean; isFallback: boolean; } | { kind: "FETCH"; revalidate: number; fetchUrl: string; fetchIdx: number; tags: string[]; softTags: string[]; isFallback: boolean; }): Promise<CacheEntry | null>; set(key: string, data: { kind: "APP_PAGE"; status: number; headers: { "x-nextjs-stale-time": string; "x-next-cache-tags": string; }; html: string; rscData: Buffer; segmentData: unknown; postboned: unknown; } | { kind: "APP_ROUTE"; status: number; headers: { "cache-control"?: string; "x-nextjs-stale-time": string; "x-next-cache-tags": string; }; body: Buffer; } | { kind: "FETCH"; data: { headers: Record<string, string>; body: string; status: number; url: string; }; revalidate: number | false; }, ctx: { isRoutePPREnabled: boolean; isFallback: boolean; tags?: string[]; revalidate?: number | false; cacheControl?: { revalidate: 5; expire: undefined; }; }): Promise<void>; revalidateTag(tagOrTags: string | string[], ...rest: any[]): Promise<void>; } declare class CachedHandler { constructor(options: CreateRedisStringsHandlerOptions); get(...args: Parameters<RedisStringsHandler["get"]>): ReturnType<RedisStringsHandler["get"]>; set(...args: Parameters<RedisStringsHandler["set"]>): ReturnType<RedisStringsHandler["set"]>; revalidateTag(...args: Parameters<RedisStringsHandler["revalidateTag"]>): ReturnType<RedisStringsHandler["revalidateTag"]>; resetRequestCache(...args: Parameters<RedisStringsHandler["resetRequestCache"]>): ReturnType<RedisStringsHandler["resetRequestCache"]>; } export { RedisStringsHandler, CachedHandler as default };