UNPKG

alepha

Version:

Easy-to-use modern TypeScript framework for building many kind of applications.

196 lines 7.16 kB
import { Alepha, Middleware } from "alepha"; import { CachePrimitiveOptions } from "alepha/cache"; import { CryptoProvider } from "alepha/crypto"; import { DateTimeProvider, DurationLike } from "alepha/datetime"; import { ServerRequest, ServerRoute } from "alepha/server"; //#region ../../src/server/etag/primitives/$etag.d.ts /** * Middleware that enables ETag-based response caching per-route. * * Sets per-request etag options in the ALS context. * The global `ServerEtagProvider` hooks read these * to generate ETags, handle 304s, and optionally store responses. * * When `store` is enabled, the middleware also checks the cache before * calling the handler, short-circuiting on cache hits. * * **Route middleware** — works inside `$action`, `$page`, or any pipeline. * * ```typescript * class UserController { * // ETag only (no response caching) * getUser = $action({ * use: [$etag()], * handler: async ({ params }) => { ... }, * }); * * // ETag + response caching (store) * getProfile = $action({ * use: [$etag(true)], * handler: async ({ params }) => { ... }, * }); * * // Fine-grained control * getStats = $action({ * use: [$etag({ store: { ttl: [5, "minutes"] }, control: { public: true, maxAge: 300 } })], * handler: async ({ params }) => { ... }, * }); * } * ``` */ declare const $etag: (options?: EtagMiddlewareOptions) => Middleware; declare function resolveEtagOptions(options?: EtagMiddlewareOptions): EtagMiddlewareOptionsResolved; type EtagMiddlewareOptions = /** * If true, enables both store and etag. */ true | /** * Object configuration for fine-grained control. */ { /** * If true, enables storing cached responses. (in-memory, Redis, @see alepha/cache for other providers) * If a DurationLike is provided, it will be used as the TTL for the cache. * If CachePrimitiveOptions is provided, it will be used to configure the cache storage. * * @default false */ store?: true | DurationLike | CachePrimitiveOptions; /** * If true, enables ETag support for the cached responses. * * @default true (always true when using $etag) */ etag?: true; /** * - If true, sets Cache-Control to "public, max-age=300" (5 minutes). * - If string, sets Cache-Control to the provided value directly. * - If object, configures Cache-Control directives. */ control?: true | string | { /** * Indicates that the response may be cached by any cache. */ public?: boolean; /** * Indicates that the response is intended for a single user and must not be stored by a shared cache. */ private?: boolean; /** * Forces caches to submit the request to the origin server for validation before releasing a cached copy. */ noCache?: boolean; /** * Instructs caches not to store the response. */ noStore?: boolean; /** * Maximum amount of time a resource is considered fresh. * Can be specified as a number (seconds) or as a DurationLike object. */ maxAge?: number | DurationLike; /** * Overrides max-age for shared caches (e.g., CDNs). * Can be specified as a number (seconds) or as a DurationLike object. */ sMaxAge?: number | DurationLike; /** * Indicates that once a resource becomes stale, caches must not use it without successful validation. */ mustRevalidate?: boolean; /** * Similar to must-revalidate, but only for shared caches. */ proxyRevalidate?: boolean; /** * Indicates that the response can be stored but must be revalidated before each use. */ immutable?: boolean; /** * Time window (in seconds or DurationLike) during which a stale response may be served * while a fresh one is fetched in the background. * Supported by Cloudflare, modern browsers, and most CDNs. */ staleWhileRevalidate?: number | DurationLike; }; }; interface EtagMiddlewareOptionsResolved { store?: true | DurationLike | CachePrimitiveOptions; etag?: true; control?: true | string | { public?: boolean; private?: boolean; noCache?: boolean; noStore?: boolean; maxAge?: number | DurationLike; sMaxAge?: number | DurationLike; mustRevalidate?: boolean; proxyRevalidate?: boolean; immutable?: boolean; staleWhileRevalidate?: number | DurationLike; }; } //#endregion //#region ../../src/server/etag/providers/ServerEtagProvider.d.ts declare class ServerEtagProvider { protected readonly log: import("alepha/logger").Logger; protected readonly alepha: Alepha; protected readonly crypto: CryptoProvider; protected readonly time: DateTimeProvider; protected readonly cache: import("alepha/cache").CacheMiddlewareFn<RouteCacheEntry>; generateETag(content: string | Buffer): string; invalidate(route: ServerRoute): Promise<void>; /** * Check cache for a stored response. Returns the cached body if found, undefined otherwise. * Called by the $etag() middleware before the handler runs. */ checkCache(request: ServerRequest, options: EtagMiddlewareOptionsResolved): Promise<any>; /** * After an action response, store it in cache if store is enabled. */ protected readonly onActionResponse: import("alepha").HookPrimitive<"action:onResponse">; /** * Before sending the response, check ETag for etag-only routes. * This handles the case where etag is enabled but store is not. */ protected readonly onSend: import("alepha").HookPrimitive<"server:onSend">; /** * After the response is generated, store it and set ETag headers. */ protected readonly onResponse: import("alepha").HookPrimitive<"server:onResponse">; buildCacheControlHeader(options?: EtagMiddlewareOptionsResolved): string | undefined; shouldStore(options?: EtagMiddlewareOptionsResolved): boolean; shouldUseEtag(options?: EtagMiddlewareOptionsResolved): boolean; protected durationToSeconds(duration: number | DurationLike): number; protected createCacheKey(route: ServerRoute, config?: ServerRequest): string; /** * Collect a ReadableStream into a string and store it in the cache. * This runs in the background while the original stream is sent to the client. */ protected collectStreamForCache(stream: ReadableStream<Uint8Array>, key: string, status: number | undefined, contentType: string | undefined, generateEtag: boolean): Promise<string | undefined>; } interface RouteCacheEntry { contentType?: string; body: any; status?: number; lastModified: string; hash: string; } //#endregion //#region ../../src/server/etag/index.d.ts /** * ETag-based response caching. * * **Features:** * - ETag generation and validation * - Conditional request handling (304 Not Modified) * - Optional response caching (store) * - Cache-Control header support * * @module alepha.server.etag */ declare const AlephaServerEtag: import("alepha").Service<import("alepha").Module>; //#endregion export { $etag, AlephaServerEtag, EtagMiddlewareOptions, EtagMiddlewareOptionsResolved, ServerEtagProvider, resolveEtagOptions }; //# sourceMappingURL=index.d.ts.map