/** * Production hydration with configurable mismatch recovery. * * `verifyHydration()` (see `./mismatch`) reports *structural* divergence from * the server's `data-bq-h` signature and only ever warns. This module adds the * production-grade story tracked in GitHub issue #130: * * - `detectHydrationMismatches()` compares the **content** the server emitted * (text, visibility, bound attributes, `bq-model` values) against what the * client `context` evaluates to — the real "server data ≠ client data" case. * - `hydrate()` wraps `hydrateMount()` with a boundary-scoped recovery strategy * (`warn` | `repair` | `error`) plus an `onError` hook, so a mismatch in * production has a defined outcome instead of a silently broken UI. * * Detection is boundary-scoped (per directive-bearing element), uses the * CSP-safe expression evaluator (no `eval`), and skips expressions whose root * identifier is not present in `context` (e.g. `bq-for` loop variables) to * avoid false positives. * * @module bquery/ssr */ import type { BindingContext, View } from '../view/types'; import { type HydrateMountOptions } from './hydrate'; /** What kind of directive produced a hydration mismatch. */ export type HydrationMismatchKind = 'signature' | 'text' | 'show' | 'attribute' | 'model'; /** Recovery strategy applied when `hydrate()` detects a mismatch. */ export type MismatchStrategy = 'warn' | 'repair' | 'error'; /** A single content-level hydration mismatch. */ export interface HydrationBoundaryMismatch { /** The boundary element whose server output diverged. */ element: Element; /** Which directive class produced the mismatch. */ kind: HydrationMismatchKind; /** The offending directive, e.g. `bq-text` or `bq-bind:href`. */ directive: string; /** The value currently present in the server-rendered DOM. */ domValue: string; /** The value the client `context` evaluates to. */ clientValue: string; } /** Options for `detectHydrationMismatches()`. */ export interface DetectHydrationOptions { /** Directive prefix to match. Default: `'bq'`. */ prefix?: string; } /** * Walks the directive-bearing elements under `root` and reports every place * where the server-rendered DOM disagrees with what the client `context` * evaluates to. Safe to call in any environment; returns `[]` when `root` has * no `querySelectorAll`. * * Covers `bq-text`, `bq-show`, `bq-bind:*`, `bq-model`, and the structural * `data-bq-h` signature. `bq-class`/`bq-style` are intentionally excluded * because their additive/merge semantics make exact comparison ambiguous. * * @example * ```ts * import { detectHydrationMismatches } from '@bquery/bquery/ssr'; * * const mismatches = detectHydrationMismatches(document.getElementById('app')!, context); * if (mismatches.length) reportToDevtools(mismatches); * ``` */ export declare const detectHydrationMismatches: (root: Element | Document, context: BindingContext, options?: DetectHydrationOptions) => HydrationBoundaryMismatch[]; /** Options for `hydrate()`. */ export interface HydrateOptions extends HydrateMountOptions { /** * What to do when a hydration mismatch is detected. * - `'warn'` (default) logs each mismatch (dev-gated when left at the * default; always logged when set explicitly). * - `'repair'` rewrites the affected boundary from client state before * attaching reactivity. * - `'error'` routes each mismatch to `onError`; without an `onError` it * throws before mounting. */ onMismatch?: MismatchStrategy; /** Boundary-scoped error sink, used by the `'error'` strategy. */ onError?: (error: Error, boundary: Element) => void; /** Directive prefix. Default: `'bq'`. */ prefix?: string; } /** Result of `hydrate()`. */ export interface HydrateResult { /** The mounted, now-reactive view. */ view: View; /** Every mismatch detected before reactivity was attached. */ mismatches: HydrationBoundaryMismatch[]; } /** * Hydrates server-rendered DOM with a defined mismatch-recovery strategy. * * Detection runs against the untouched server output *before* reactivity is * attached, so it sees the real server↔client divergence; the chosen strategy * then warns, repairs, or surfaces each mismatch to an error boundary. After * that, `hydrateMount()` attaches the reactive bindings as usual. * * @example * ```ts * import { hydrate } from '@bquery/bquery/ssr'; * * const { mismatches } = hydrate('#app', context, { * onMismatch: 'repair', * onError: (err, boundary) => reportToDevtools(err, boundary), * }); * ``` */ export declare const hydrate: (selector: string | Element, context: BindingContext, options?: HydrateOptions) => HydrateResult; //# sourceMappingURL=hydration.d.ts.map