/** * Router ↔ SSR bridge. * * On the server you typically need to: * 1. Match the incoming URL against your router's route table. * 2. Run any data loaders attached to the matched route. * 3. Inject the resolved route + loader data into the SSR binding context. * * `resolveSSRRoute()` and `runRouteLoaders()` perform steps 1 and 2 without * coupling the SSR module to the actual `createRouter()` runtime — only the * pure `matchRoute()` helper from `@bquery/bquery/router` is used. Loaders * live on `RouteDefinition.meta.loader` (additive, no existing field changes). * * @module bquery/ssr */ import type { Route, RouteDefinition } from '../router/types'; import type { SSRContext } from './context'; /** * Loader signature for SSR routes. Attach as `meta.loader` on a * `RouteDefinition` and `runRouteLoaders()` will invoke it with the matched * route + the active SSR context. */ export type SSRRouteLoader = (args: { route: Route; ctx: SSRContext; }) => T | Promise; /** Result of `resolveSSRRoute()`. */ export interface ResolvedSSRRoute { /** Route-like snapshot for the requested URL, with `matched` set when found. */ route: Route; /** Whether a route definition was actually matched. */ matched: boolean; /** Whether the matched route has a `redirectTo` target. */ isRedirect: boolean; /** Redirect target, if any. */ redirectTo?: string; } /** * Matches a URL against a route table without instantiating a full router. * * Designed to be called on the server before the SSR render so userland can * branch on `matched`/`isRedirect` (e.g. issue a 302 instead of rendering). * * @example * ```ts * import { resolveSSRRoute } from '@bquery/bquery/ssr'; * * const { route, matched, isRedirect, redirectTo } = resolveSSRRoute({ * url: new URL(request.url), * routes, * }); * * if (isRedirect) return Response.redirect(redirectTo!, 302); * if (!matched) return new Response('Not Found', { status: 404 }); * ``` */ export declare const resolveSSRRoute: (options: { url: string | URL; routes: RouteDefinition[]; /** Strip a base path before matching. Default: `''`. */ base?: string; }) => ResolvedSSRRoute; /** * Runs the loader attached to the matched route (`meta.loader`), if any. * Returns the resolved data, or `undefined` if no loader is configured. */ export declare const runRouteLoaders: (route: Route, ctx: SSRContext) => Promise; /** * Convenience wrapper that resolves a route, runs its loader, and returns a * binding-context fragment ready to be merged into the data passed to * `renderToStringAsync()` / `renderToResponse()`. * * @example * ```ts * import { * createSSRContext, * createSSRRouterContext, * renderToResponse, * } from '@bquery/bquery/ssr'; * * const ctx = createSSRContext(); * const router = await createSSRRouterContext({ url: request.url, routes, ctx }); * if (router.isRedirect) return Response.redirect(router.redirectTo!, 302); * * return renderToResponse(template, { ...router.bindings }, { context: ctx }); * ``` */ export declare const createSSRRouterContext: (options: { url: string | URL; routes: RouteDefinition[]; base?: string; ctx: SSRContext; }) => Promise<{ route: Route; matched: boolean; isRedirect: boolean; redirectTo?: string; data: unknown; bindings: Record; }>; //# sourceMappingURL=router-bridge.d.ts.map