import { SiteOf } from "./entryTypeExtractors.mjs"; import { ClientManifest, ManifestChunk } from "./resolveAssets.mjs"; import { SsrRequestContextStore } from "./requestContext.mjs"; import { PipeableStream } from "react-dom/server"; import { ClientInstrumentation, HydrationState, RouteObject, RouterContextProvider, ServerInstrumentation } from "react-router"; import { Server } from "node:http"; import { Server as Server$1 } from "node:https"; import { Express, Request as Request$1, RequestHandler } from "express"; //#region src/services/vite/ssr/types.d.ts interface DocumentAssets { css: string[]; modulePreloads: string[]; } interface RenderAssets extends DocumentAssets { bootstrapModules: string[]; } /** Connect-compatible middleware from the SSR server entry. */ type SkuMiddleware = RequestHandler[]; /** * Optional server-entry post-listen hook — same window as webpack SSR `onStart`. * Called once after middleware + HTML are mounted and `listen` succeeds. */ type SkuOnListen = (args: { app: Express; httpServer: Server | Server$1; port: number; }) => void | Promise; /** JSON-serialisable shell seed for SSR `clientContext`. */ type JsonValue = string | number | boolean | null | Array | { [key: string]: JsonValue | undefined; }; /** * Route object for `routesEntry`: React Router `RouteObject` plus optional * `sites` membership. Omit `sites` ⇒ route is on every config site; present ⇒ * only those names. Sku type helper only — not a wrapped RR re-export. * `children` are also `SkuRouteObject` so nested routes may set `sites` * (no parent→child inheritance — each route declares membership explicitly). */ type SkuRouteObject = Omit & { sites?: Site[]; children?: Array>; }; /** * Args for optional `routesEntry` `mapRoutePath`. * Called while pre-building each site tree (after `sites` membership filter). */ type MapRoutePathArgs = { /** * This route’s own authored `path`, or `''` when the route is `index: true`. */ path: string; /** Resolved site name for the tree being built. */ site: string; /** * Authored `path` values from path-bearing ancestors only (pathless layouts * and index ancestors omitted), not including the current route. * Source (pre-mapping) segments. */ parentSegments: string[]; }; /** * Optional `routesEntry` hook — map one logical path to concrete paths per site. * Return `string[]` replacement paths (empty ⇒ omit). * Omitted export ⇒ identity (`[path]` / `['']` for index). * For an index source, `''` keeps `index: true`; a non-empty string becomes a * `path` clone without `index`. */ type MapRoutePath = (args: MapRoutePathArgs) => string[]; /** * Sync server-entry getter — app-owned site name selecting the pre-built tree. * Required when config `sites` has more than one entry; optional on single-site * (sku uses the sole config site name when omitted). */ type SkuGetSite = (args: { /** Express request after consumer middleware (not Fetch `Request`). */ req: Request$1; }) => string; /** * Sync server-entry getter — configured language name (or `en-PSEUDO`) for * Document vocab chunk registration. Omit or return `undefined` ⇒ no chunk. */ type SkuGetLanguage = (args: { req: Request$1; }) => string | undefined; /** * Dual-entry getter — values that MAY differ on server vs client (e.g. * `makeClient`, `apiClient`). Not serialised; reaches React via `useReactContext`. */ type SkuServerGetReactContext = (args: { req: Request$1; site: string; clientContext: C | undefined; }) => R | Promise; type SkuClientGetReactContext = (args: { site: string; clientContext: C | undefined; }) => R | Promise; /** * Optional server-entry `getRouterContext` — seeds React Router `requestContext` * for document `query()` / loaders. Receives already-resolved sibling values. */ type SkuServerGetRouterContext = (args: { /** Fetch `Request` — same shape as `query()` / loaders. */ request: Request; /** Express request after consumer middleware. */ req: Request$1; site: string; clientContext: C | undefined; reactContext: R | undefined; }) => RouterContextProvider | Promise; /** Hydrate side effects only — request values reach React via `SkuProvider`. */ type SkuOnHydrate = (args: { clientContext: JsonValue | undefined; }) => void; /** * Optional client-entry `getRouterContext` — sku wraps into React Router’s * native `createBrowserRouter({ getContext })` (zero-arg) and injects hydrate * sibling values (`site`, `clientContext`, `reactContext`). */ type SkuClientGetRouterContext = (args: { site: string; clientContext: C | undefined; reactContext: R | undefined; }) => RouterContextProvider | Promise; /** * Structural shape of a SSR `serverEntry` default export (prefer * `defineServerEntry` for sibling inference). */ type SkuServerEntry = { getSite?: SkuGetSite; getLanguage?: SkuGetLanguage; getClientContext?: (args: { req: Request$1; }) => C | Promise; getReactContext?: SkuServerGetReactContext; middleware?: SkuMiddleware; onListen?: SkuOnListen; getRouterContext?: SkuServerGetRouterContext; instrumentations?: Array>; }; /** * Structural shape of a SSR `clientEntry` default export (prefer * `defineClientEntry` for sibling inference). */ type SkuClientEntry = { onHydrate?: SkuOnHydrate; getReactContext?: SkuClientGetReactContext; getRouterContext?: SkuClientGetRouterContext; instrumentations?: ClientInstrumentation[]; }; interface RenderManifest { manifest: ClientManifest; publicPath: string; entry: ManifestChunk; } interface RenderOptions { signal?: AbortSignal; nonce?: string; /** Shared request context for this render (CSP nonce). */ requestContextStore?: SsrRequestContextStore; development?: boolean; onShellError?: (error: unknown) => void; onError?: (error: unknown) => void; /** Document render deadline in ms. Default 10_000. */ renderTimeoutMs?: number; } type DocumentDestination = Parameters[0]; type CommitDocumentOptions = { signal?: AbortSignal; beforePipe?: (destination: DocumentDestination) => void; }; type CommitDocument = (destination: DocumentDestination, options?: CommitDocumentOptions) => void; interface RenderSuccess { statusCode: number; headers: Headers; inlineScripts: string[]; commit: CommitDocument; } type RenderResult = RenderSuccess | { response: Response; }; declare global { interface Window { __SKU_DOCUMENT_ASSETS__?: DocumentAssets; __SKU_CLIENT_CONTEXT__?: JsonValue; /** Hydrated site — selects the same pre-built client site tree as SSR. */ __SKU_SITE__?: string; __staticRouterHydrationData?: HydrationState; } } declare module 'express-serve-static-core' { interface Request { /** * SSR: mint/reuse the single request-scoped CSP nonce. * Only include `'nonce-…'` in CSP after this (or `getCspNonce()`) is called. */ getCspNonce?: () => string; } } //#endregion export { CommitDocument, CommitDocumentOptions, DocumentAssets, DocumentDestination, JsonValue, MapRoutePath, MapRoutePathArgs, RenderAssets, RenderManifest, RenderOptions, RenderResult, RenderSuccess, type SiteOf, SkuClientEntry, SkuClientGetReactContext, SkuClientGetRouterContext, SkuGetLanguage, SkuGetSite, SkuMiddleware, SkuOnHydrate, SkuOnListen, SkuRouteObject, SkuServerEntry, SkuServerGetReactContext, SkuServerGetRouterContext };