import type { HousekeepingRegistry } from "../registry"; import { matchHousekeepingRoute } from "./match-route"; import type { HousekeepingRouteHandler, HousekeepingRouteMatch, } from "./route-handler"; export interface HousekeepingRouteRuntime { registry: HousekeepingRegistry; handlers: ReadonlyMap; match(pathname: string): HousekeepingRouteMatch | null; } export function createHousekeepingRouteRuntime( registry: HousekeepingRegistry, handlers: readonly HousekeepingRouteHandler[], ): HousekeepingRouteRuntime { const declaredRouteIds = new Set( registry.domains.flatMap((domain) => domain.routes.map((route) => route.id), ), ); const handlerMap = new Map(); for (const handler of handlers) { if (handlerMap.has(handler.routeId)) { throw new Error(`duplicate route handler: ${handler.routeId}`); } if (!declaredRouteIds.has(handler.routeId)) { throw new Error(`handler without route: ${handler.routeId}`); } handlerMap.set(handler.routeId, handler); } for (const routeId of declaredRouteIds) { if (!handlerMap.has(routeId)) { throw new Error(`missing route handler: ${routeId}`); } } return Object.freeze({ registry, handlers: handlerMap, match: (pathname: string) => matchHousekeepingRoute(registry, pathname), }); }