48 lines
1.3 KiB
TypeScript
48 lines
1.3 KiB
TypeScript
import type { HousekeepingRegistry } from "../registry";
|
|
import { matchHousekeepingRoute } from "./match-route";
|
|
import type {
|
|
HousekeepingRouteHandler,
|
|
HousekeepingRouteMatch,
|
|
} from "./route-handler";
|
|
|
|
export interface HousekeepingRouteRuntime {
|
|
registry: HousekeepingRegistry;
|
|
handlers: ReadonlyMap<string, HousekeepingRouteHandler>;
|
|
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<string, HousekeepingRouteHandler>();
|
|
|
|
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),
|
|
});
|
|
}
|