import type { CoercedAdapterRequestContext } from './AdapterRequestContext'; import type { TTLStrategy } from './reader/resolve'; import type { Selector } from './Select'; import type { PendingSnapshot, Snapshot, SnapshotRefresh } from './interfaces/Snapshot'; import type { Luvio } from './Root'; /** * returns fresh and (optionally) stale data from the cache, but always makes a * network request */ export interface CachePolicyCacheAndNetwork { type: 'cache-and-network'; staleDurationSeconds?: number; } /** * returns fresh data from the cache; makes a network request if the cache did * not contain fresh data */ export interface CachePolicyCacheThenNetwork { type: 'cache-then-network'; } /** * ignores cached data and always makes a network request */ export interface CachePolicyNoCache { type: 'no-cache'; } /** * returns fresh cached data only; per RFC 7234, a 504 error (Gateway Timeout) is * returned if cached data is unavailable */ export interface CachePolicyOnlyIfCached { type: 'only-if-cached'; } /** * returns fresh or stale data from the cache; makes a network request if the * cached data was stale or missing */ export interface CachePolicyStaleWhileRevalidate { type: 'stale-while-revalidate'; staleDurationSeconds: number; } /** * returns cached data if the specified base cache policy would have returned * it at any point since the specified timestamp; makes a network request if * no suitable data was found in the cache */ export interface CachePolicyValidAt { type: 'valid-at'; basePolicy?: CachePolicy; timestamp: number; } export type CachePolicy = CachePolicyCacheAndNetwork | CachePolicyCacheThenNetwork | CachePolicyNoCache | CachePolicyOnlyIfCached | CachePolicyStaleWhileRevalidate | CachePolicyValidAt; export type CachePolicyType = CachePolicy['type']; export type StoreLookup = (sel: Selector, refresh?: SnapshotRefresh) => Snapshot; /** * A function that builds a Snapshot from data in the Luvio cache. * * Implementations of this function should return synchronously, without generating * any external requests for data. * * @typeParam C - type of the context argument passed to snapshot builder functions; * corresponds to the C type on Luvio.applyCachePolicy * @typeParam D - type of data in the returned snapshot * @typeParam V - type of the variables in the returned snapshot * @param buildSnapshotContext - snapshot builder context value that was passed to * the Luvio.applyCachePolicy; this value allows callers of applyCachePolicy to * pass contextual information to their snapshot builder functions without having * to resort to closures or .bind() calls * @param storeLookup - function that implementations must use to retrieve data from * the Luvio store; use of this function ensures that data from the store is accessed * in a manner consistent with the cache policy * @returns Snapshot of the requested data; implementations should return a Snapshot if they * are able to construct one - returning undefined will preclude looking up the data * in a durable store and is intended only for use in scenarios where there is * insufficient data to construct a Selector for the Snapshot. Implementations * may return a Promise to a Snapshot in very custom cases where an async step * is required to build the snapshot. */ export type BuildCachedSnapshot = (buildSnapshotContext: C, storeLookup: StoreLookup, luvio: Luvio) => Snapshot | Promise> | undefined | Promise; /** * A function that makes a network request to obtain data needed to build a Snapshot. Most * implementations will do something like: * * return dispatchResourceRequest(request, override) * .then((response) => { * return onFetchResponseSuccess(luvio, config, resourceParams, response); * }, (response: $64$luvio_engine_FetchResponse) => { * return onFetchResponseError(luvio, config, resourceParams, response); * }); * * Implementations of BuildNetworkSnapshot should not access data directly from the * cache. Doing so can break the semantics of cache policies that guarantee all data * will be fetched from the network. * * Adapters that need to combine cached data with network data should access the cached * data in their buildCachedSnapshot functions (using the storeLookup function * parameter) and store references to that cached data in the buildSnapshotContext. * Their buildNetworkSnapshot functions can check their buildSnapshotContexts and * use these references if they are present. This guarantees that all cache and * network access is done in accordance with the cache policy. * * @typeParam C - type of the context argument passed to snapshot builder functions; * corresponds to the C type on Luvio.applyCachePolicy * @typeParam D - type of data in the returned snapshot * @typeParam V - type of the variables in the returned snapshot * @param buildSnapshotContext - snapshot builder context value that was passed to * the Luvio.applyCachePolicy; this value allows callers of applyCachePolicy to * pass contextual information to their snapshot builder functions without having * to resort to closures or .bind() calls * @returns Promise for a Snapshot of the requested data */ export type BuildNetworkSnapshot = (buildSnapshotContext: C, coercedAdapterRequestContext: CoercedAdapterRequestContext) => Promise>; /** * Parameters passed to a CachePolicyImplementation. Defined as its own type since it's used in * several places & keeping them all in sync is a chore. */ export type CachePolicyImplementationArgs = { buildCachedSnapshot: BuildCachedSnapshot; buildNetworkSnapshot: BuildNetworkSnapshot; buildSnapshotContext: C; resolvePendingSnapshot: (snapshot: PendingSnapshot) => Promise>; storeLookup: (sel: Selector, refresh: SnapshotRefresh | undefined, ttlStrategy: TTLStrategy) => Snapshot; coercedAdapterRequestContext: CoercedAdapterRequestContext; luvio: Luvio; }; /** * Implementation of a CachePolicy. Exported only for use within engine code; adapters * are restricted to passing in CachePolicy objects. */ export type CachePolicyImplementation = (args: CachePolicyImplementationArgs) => Snapshot | Promise>;