/** * Client Hints header parsing for edge-side device capability detection. * * Converts HTTP Client Hints headers into the same `ExtendedDeviceCapabilities` * structure that `@czap/detect` uses, enabling reuse of the pure tier mapping * functions at the edge without browser APIs. * * @module */ import type { ExtendedDeviceCapabilities } from '@czap/detect'; import type { ResponsiveMediaCapabilities } from '@czap/core'; /** * Plain-object header bag accepted by {@link ClientHints.parseClientHints}. * * All names are lowercased because Client Hints headers are always lowercase * in spec. Values that are missing simply fall back to conservative * defaults during parsing. */ export interface ClientHintsHeaders { /** `Sec-CH-UA-Platform` (e.g. `"macOS"`, `"Windows"`). */ readonly 'sec-ch-ua-platform'?: string; /** `Sec-CH-Device-Memory` in GiB (one of the standard buckets). */ readonly 'sec-ch-device-memory'?: string; /** `Sec-CH-DPR` — devicePixelRatio as a decimal string. */ readonly 'sec-ch-dpr'?: string; /** `Sec-CH-Viewport-Width` in CSS pixels. */ readonly 'sec-ch-viewport-width'?: string; /** `Sec-CH-Viewport-Height` in CSS pixels. */ readonly 'sec-ch-viewport-height'?: string; /** `Sec-CH-Prefers-Reduced-Motion` (`reduce` / `no-preference`). */ readonly 'sec-ch-prefers-reduced-motion'?: string; /** `Sec-CH-Prefers-Color-Scheme` (`light` / `dark`). */ readonly 'sec-ch-prefers-color-scheme'?: string; /** `Sec-CH-UA-Mobile` as a structured boolean (`?1` / `?0`). */ readonly 'sec-ch-ua-mobile'?: string; /** `Sec-CH-UA` — full user-agent brand list. */ readonly 'sec-ch-ua'?: string; /** `Save-Data` (`on`). */ readonly 'save-data'?: string; /** `Downlink` estimate in Mb/s. */ readonly downlink?: string; /** `ECT` effective connection type. */ readonly ect?: string; /** `RTT` round-trip-time estimate in ms. */ readonly rtt?: string; /** `User-Agent` fallback for GPU-tier heuristics. */ readonly 'user-agent'?: string; } /** * Parse Client Hints headers into an {@link ExtendedDeviceCapabilities} structure. * * For properties that cannot be determined from headers (GPU tier, WebGPU * support, CPU cores), conservative defaults are used. * * @example * ```ts * import { ClientHints } from '@czap/edge'; * * const caps = ClientHints.parseClientHints({ * 'sec-ch-device-memory': '8', * 'sec-ch-dpr': '2', * 'sec-ch-viewport-width': '1440', * 'sec-ch-prefers-color-scheme': 'dark', * 'sec-ch-ua-mobile': '?0', * }); * console.log(caps.memory); // 8 * console.log(caps.devicePixelRatio); // 2 * console.log(caps.prefersColorScheme); // 'dark' * ``` * * @param headers - Client Hints headers (plain object or Web API Headers) * @returns An {@link ExtendedDeviceCapabilities} structure */ declare function parseClientHints(headers: ClientHintsHeaders | Headers): ExtendedDeviceCapabilities; /** * Generate the `Accept-CH` header value for requesting all useful Client Hints * on subsequent requests. * * @example * ```ts * import { ClientHints } from '@czap/edge'; * * const response = new Response('OK', { * headers: { 'Accept-CH': ClientHints.acceptCHHeader() }, * }); * ``` * * @returns A comma-separated list of Client Hint header names */ declare function acceptCHHeader(): string; /** * Generate the `Critical-CH` header value for hints needed on the very first * request (triggers a browser retry if missing). * * @example * ```ts * import { ClientHints } from '@czap/edge'; * * const response = new Response('OK', { * headers: { * 'Accept-CH': ClientHints.acceptCHHeader(), * 'Critical-CH': ClientHints.criticalCHHeader(), * }, * }); * ``` * * @returns A comma-separated list of critical Client Hint header names */ declare function criticalCHHeader(): string; /** * Produce the `Vary` response header value listing every Client Hint (and * network hint) that shapes tier-specific HTML. CDN caches must vary on these * inputs or they can serve the wrong tier's representation (#122). */ declare function varyCHHeader(): string; /** * Derive Save-Data / DPR capabilities for responsive-media projection (#125). * Hosts that already parsed caps can also call this with the result of * {@link parseClientHints}. */ declare function responsiveMediaCapabilities(headersOrCaps: Headers | ClientHintsHeaders | ExtendedDeviceCapabilities): ResponsiveMediaCapabilities; /** * `Vary` inputs that shape responsive-media projection (DPR + Save-Data). * CDN caches must vary on these or they can serve the wrong srcset (#125). */ declare function responsiveMediaVaryHeader(): string; /** * Client Hints namespace. * * Parses HTTP Client Hints headers into the same * {@link ExtendedDeviceCapabilities} structure used by `@czap/detect`, * enabling server-side / edge-side tier mapping without browser APIs. * Also generates the `Accept-CH` and `Critical-CH` response headers needed * to request hints from the browser. * * @example * ```ts * import { ClientHints } from '@czap/edge'; * * // In an edge handler: * const caps = ClientHints.parseClientHints(request.headers); * const response = new Response(body, { * headers: { * 'Accept-CH': ClientHints.acceptCHHeader(), * 'Critical-CH': ClientHints.criticalCHHeader(), * }, * }); * ``` */ export declare const ClientHints: { /** Parse Client Hints headers into {@link ExtendedDeviceCapabilities}. */ readonly parseClientHints: typeof parseClientHints; /** Produce the `Accept-CH` response header value listing all useful hints. */ readonly acceptCHHeader: typeof acceptCHHeader; /** Produce the `Critical-CH` response header value listing boot-required hints. */ readonly criticalCHHeader: typeof criticalCHHeader; /** Produce the `Vary` response header value for tier-varying HTML (#122). */ readonly varyCHHeader: typeof varyCHHeader; /** Derive Save-Data/DPR capabilities for responsive-media projection (#125). */ readonly responsiveMediaCapabilities: typeof responsiveMediaCapabilities; /** Produce the `Vary` value for responsive-media representations (#125). */ readonly responsiveMediaVaryHeader: typeof responsiveMediaVaryHeader; }; export declare namespace ClientHints { /** Alias for {@link ClientHintsHeaders} — plain-object header bag shape. */ type Headers = ClientHintsHeaders; } export {}; //# sourceMappingURL=client-hints.d.ts.map