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