import { $EventMethod, $Node, $EventManager } from "elexis"; import { $Util } from "elexis/lib/$Util"; export class Route { path: string | PathResolverFn; builder: (req: RouteRequest) => RouteContent; constructor(path: Path, builder: ((req: RouteRequest) => RouteContent) | RouteContent) { this.path = path; this.builder = builder instanceof Function ? builder : (req: RouteRequest) => builder; } } type PathParams = Path extends `${infer Segment}/${infer Rest}` ? Segment extends `${string}:${infer Param}` ? Record & PathParams : PathParams : Path extends `${string}:${infer Param}` ? Record : {} export type PathResolverFn = (path: string) => undefined | string; type PathParamResolver

= P extends PathResolverFn ? undefined : PathParams

// type PathResolverRecord

= { // [key in keyof ReturnType

]: ReturnType

[key] // } export interface RouteRecord extends $EventMethod {}; export class RouteRecord { id: string; readonly content?: $Node; events = new $EventManager().register('open', 'load') constructor(id: string) { this.id = id; } } $Util.mixin(RouteRecord, $EventMethod) export interface RouteRecordEventMap { 'open': [{path: string, record: RouteRecord}]; 'load': [{path: string, record: RouteRecord}]; } export interface RouteRequest { params: PathParamResolver, record: RouteRecord, loaded: () => void; } export type RouteContent = $Node | string | void;