declare function applyFarmCacheInvalidations(keys: unknown): void; type RevalidateTagProfile = "max" | "default" | "seconds" | "minutes" | "hours" | "days" | "weeks" | "months" | { expire?: number; }; interface FarmCacheOptions { /** * Tag cached data so it can be invalidated with revalidateTag/updateTag. */ tags?: readonly string[]; /** * Path tags let revalidatePath invalidate data tied to a route. */ paths?: readonly string[]; /** * Time in seconds before the entry becomes stale. False means no TTL. */ revalidate?: number | false; } interface FarmCacheSetOptions extends FarmCacheOptions { createdAt?: number; } type RouteDataCacheKey = string | readonly unknown[]; type FarmCacheInvalidationTarget = { key: RouteDataCacheKey; } | { path: string; } | { tag: string; }; declare const FARM_DEFINED_CACHE_KEY_DATA: unique symbol; /** * A regular Farm cache key carrying the data shape stored under that key. * * The brand exists only in TypeScript. At runtime the value remains the * original string or structured array, so all existing cache APIs continue to * accept untyped keys. */ type DefinedCacheKey = TKey & { readonly [FARM_DEFINED_CACHE_KEY_DATA]: TData; }; type CacheKeyFactory = (...args: TArguments) => DefinedCacheKey; type InferCacheKeyData = TKey extends DefinedCacheKey ? TData : unknown; /** * Optionally add a data type to an existing string/array cache-key factory. * * This helper does not introduce a new runtime key representation. Calling the * returned factory produces the exact key returned by `factory`. */ declare function defineCacheKey(): (factory: (...args: TArguments) => TKey) => CacheKeyFactory; interface FarmCacheEntry { key: string; value: T; tags: readonly string[]; /** * Adapter tag versions captured before the cached value was produced. * A later version makes the entry stale across every server instance. */ tagVersions?: Readonly>; createdAt: number; createdVersion?: number; revalidate?: number | false; } /** * Asynchronous persistence contract used by distributed Farm caches. * * Implementations are responsible for serializing cache entries and making * tag version updates atomic when the backing service supports it. */ interface FarmCacheAdapter { readonly name?: string; get(key: string): Promise | null | undefined>; set(key: string, entry: FarmCacheEntry): Promise; delete(key: string): Promise; clear?(): Promise; getTagVersions?(tags: readonly string[]): Promise>>; invalidateTags?(tags: readonly string[]): Promise; /** Atomically acquire a short-lived regeneration lease. */ acquireLease?(key: string, ttlMs: number): Promise; /** Release the lease only when the supplied ownership token still matches. */ releaseLease?(key: string, token: string): Promise; } interface FarmClientCacheUserConfig { /** * Module path, relative to the project root, whose default export is a * client cache adapter (`defineClientCacheAdapter`). The module is bundled * into the browser entry; the server never imports it. */ adapter?: string; /** Extra version salt, typically a build or deploy id; entries persisted under another salt are dropped. */ version?: string; /** Debounce for persisted write-behind flushes, in milliseconds. */ flushDelayMs?: number; } interface FarmCacheUserConfig { /** Shared cache implementation, for example a Redis-backed adapter. */ adapter?: FarmCacheAdapter; /** Prefix isolating applications and deployments sharing one adapter. */ namespace?: string; /** Browser cache persistence; see the client cache adapter documentation. */ client?: FarmClientCacheUserConfig; /** * Coordinate cache fills across processes when the adapter implements * acquireLease/releaseLease. Set false to disable. */ lease?: false | { ttlMs?: number; waitTimeoutMs?: number; pollIntervalMs?: number; }; } interface FarmCacheStorage { getItem(key: string): Promise; setItem(key: string, value: T): Promise; removeItem(key: string): Promise; clear?(base?: string): Promise; } interface StorageFarmCacheAdapterOptions { /** Prefix used inside the supplied storage client. */ base?: string; } /** * Adapt a Farm/unstorage-compatible key-value client to the cache contract. * * This is a portable baseline adapter. Provider-specific adapters should use * their atomic increment/transaction primitives for tag invalidation. */ declare function storageCacheAdapter(storage: FarmCacheStorage, options?: StorageFarmCacheAdapterOptions): FarmCacheAdapter; interface GetFarmCacheEntryOptions { allowStale?: boolean; now?: number; } interface FarmCacheStaleEntry { tags: Iterable; createdAt: number; createdVersion?: number; revalidate?: number | false; } declare class FarmDataCache { private entries; private inflight; private invalidatedTagVersions; private version; private generation; private adapter?; private namespace; private local; private lease; constructor(config?: FarmCacheUserConfig); configure(config?: FarmCacheUserConfig): void; get adapterName(): string; get hasAdapter(): boolean; get size(): number; get(key: string, options?: GetFarmCacheEntryOptions): T | undefined; getEntry(key: string, options?: GetFarmCacheEntryOptions): FarmCacheEntry | undefined; getEntryAsync(key: string, options?: GetFarmCacheEntryOptions): Promise | undefined>; set(key: string, value: T, options?: FarmCacheSetOptions): FarmCacheEntry; setAsync(key: string, value: T, options?: FarmCacheSetOptions, tagVersions?: Readonly>): Promise>; private writeAsync; delete(key: string): boolean; deleteAsync(key: string): Promise; clear(): void; clearAsync(): Promise; isStale(entry: FarmCacheStaleEntry, now?: number): boolean; isStaleAsync(entry: FarmCacheEntry, now?: number): Promise; revalidateTag(tag: string, options?: { source?: "revalidateTag" | "updateTag"; profile?: RevalidateTagProfile; }): number; revalidateTagAsync(tag: string, options?: { source?: "revalidateTag" | "updateTag"; profile?: RevalidateTagProfile; }): Promise; revalidatePath(routePath: string): number; revalidatePathAsync(routePath: string): Promise; getOrSet(key: string, producer: () => Promise | T, options?: FarmCacheOptions): Promise; private fillCacheEntry; private waitForAdapterEntry; private countEntriesForTag; private countEntriesForTags; private invalidateTag; private toPublicEntry; private hydrateLocalEntry; private createAdapterKey; private createAdapterTag; private getAdapterTagVersions; private isAdapterEntryStale; } declare function getFarmDataCache(): FarmDataCache; declare function configureFarmCache(config: FarmCacheUserConfig | undefined): void; /** * Wrap an async function so its results are cached and shared across requests, * processes, and restarts. * * The cache key is built from the wrapped function's identity (its name and a * hash of its source), the active locale, `keyParts`, and the call arguments. * Deriving identity from the source — rather than the closure instance — is * deliberate: it keeps the key stable across processes and restarts so a * distributed cache adapter can share entries between server instances. * * The consequence is that two closures with **identical source text but * different captured variables** produce the same identity. Pass those captured * values in `keyParts` so they take part in the key; otherwise the closures * share a cache entry and return each other's data: * * ```ts * // Collides: both closures have identical source, and `table` is captured, * // not an argument, so it never reaches the key. * const makeLoader = (table: string) => * unstable_cache(async (id: number) => db.get(table, id)); * * // Correct: the captured value disambiguates the two closures. * const makeLoader = (table: string) => * unstable_cache(async (id: number) => db.get(table, id), [table]); * ``` * * Values passed as call arguments already participate in the key and do not * need to be repeated in `keyParts`. * * @param fn The async function to memoize. * @param keyParts Extra values that identify this call site. Include every * variable the function closes over that is not one of its arguments. * @param options Tags, paths, and revalidation settings for the cached entry. */ declare function unstable_cache(fn: (...args: Args) => Result | Promise, keyParts?: readonly unknown[], options?: FarmCacheOptions): (...args: Args) => Promise; /** * Invalidate every cache entry carrying `tag`. * * Observability note: the `count` on the emitted `cache.revalidateTag` event is * derived from Farm's process-local entry tracking. With a shared `cache.adapter` * configured, entries live in the adapter rather than in local memory, so the * count can read as `0` even though the invalidation is still propagated to the * adapter and applied. Treat it as a best-effort signal, not a distributed count. */ declare function revalidateTag(_tag: string, _profile?: RevalidateTagProfile): void | Promise; declare function updateTag(tag: string): void | Promise; /** * Invalidate cached data for a route path (and its PPR shell, if any). * * Observability note: the `count` on the emitted `cache.revalidatePath` event and * the `ppr.shell.invalidated` event are derived from process-local entry tracking. * With a shared `cache.adapter`, PPR shells live in the adapter rather than in * local memory, so the count can read as `0` and `ppr.shell.invalidated` may not * be emitted even though the invalidation is still propagated to the adapter and * applied. */ declare function revalidatePath(routePath: string): void | Promise; declare function invalidate(key: RouteDataCacheKey): void | Promise; declare function invalidateRouteData(key: RouteDataCacheKey): void | Promise; /** * Apply a normalized set of invalidation targets and return browser cache keys * that should be carried with an action/endpoint response. */ declare function applyFarmCacheInvalidationTargets(targets: readonly FarmCacheInvalidationTarget[]): Promise; declare function createPathCacheTag(routePath: string): string; declare function createRouteDataCacheTag(key: RouteDataCacheKey): string; declare function createRouteDataCacheKey(key: RouteDataCacheKey): string; declare function normalizeRevalidatePath(routePath: string): string; declare function createFarmCacheKey(parts: readonly unknown[]): string; export { type CacheKeyFactory, type DefinedCacheKey, type FarmCacheAdapter, type FarmCacheEntry, type FarmCacheInvalidationTarget, type FarmCacheOptions, type FarmCacheSetOptions, type FarmCacheStorage, type FarmCacheUserConfig, type FarmClientCacheUserConfig, FarmDataCache, type GetFarmCacheEntryOptions, type InferCacheKeyData, type RevalidateTagProfile, type RouteDataCacheKey, type StorageFarmCacheAdapterOptions, applyFarmCacheInvalidationTargets, applyFarmCacheInvalidations, configureFarmCache, createFarmCacheKey, createPathCacheTag, createRouteDataCacheKey, createRouteDataCacheTag, defineCacheKey, getFarmDataCache, invalidate, invalidateRouteData, normalizeRevalidatePath, revalidatePath, revalidateTag, storageCacheAdapter, unstable_cache, updateTag };