alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
196 lines • 7.16 kB
TypeScript
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