resig.js
Version:
Universal reactive signal library with complete platform features: signals, animations, CRDTs, scheduling, DOM integration. Works identically across React, SolidJS, Svelte, Vue, and Qwik.
124 lines (123 loc) • 3.82 kB
TypeScript
/**
* Core Router Types - Category Theory Foundation
* Following categorical laws for route composition
*/
import { Signal } from '../core/signal';
import { Effect } from '../core/effect';
/**
* Route Functor - preserves structure through mapping
* Laws:
* - route.map(id) ≡ route (identity)
* - route.map(f ∘ g) ≡ route.map(f).map(g) (composition)
*/
export interface Route<A> {
readonly path: string;
readonly params: A;
readonly map: <B>(f: (a: A) => B) => Route<B>;
readonly matches: (path: string) => boolean;
readonly parse: (path: string) => A | null;
readonly generate: (params: A) => string;
}
/**
* Navigation Monad - effect composition for route changes
* Laws:
* - Navigation.pure(a).bind(f) ≡ f(a) (left identity)
* - m.bind(Navigation.pure) ≡ m (right identity)
* - m.bind(f).bind(g) ≡ m.bind(a => f(a).bind(g)) (associativity)
*/
export interface Navigation<A> extends Route<A> {
readonly bind: <B>(f: (a: A) => Navigation<B>) => Navigation<B>;
readonly navigate: () => Effect<A>;
}
/**
* Router Coalgebra - isomorphic path/state transformation
* Isomorphism Law: route(generate(state)) ≡ Some(Route<State>)
*/
export interface Router<State> {
readonly route: (path: string) => Option<Route<State>>;
readonly generate: (state: State) => string;
readonly current: Signal<Option<Route<State>>>;
readonly params: Signal<State | null>;
}
/**
* Option type for safe route matching
*/
export type Option<A> = {
readonly tag: 'Some';
readonly value: A;
} | {
readonly tag: 'None';
};
export declare const Some: <A>(value: A) => Option<A>;
export declare const None: Option<never>;
export declare const isSome: <A>(option: Option<A>) => option is {
tag: 'Some';
value: A;
};
export declare const isNone: <A>(option: Option<A>) => option is {
tag: 'None';
};
/**
* Navigation Environment - isomorphic abstraction
*/
export interface NavigationEnv {
readonly getCurrentPath: () => string;
readonly setPath: (path: string, replace?: boolean) => void;
readonly onPathChange: (fn: (path: string) => void) => () => void;
}
/**
* Route Guard for access control
*/
export interface RouteGuard<A> {
readonly canActivate: (params: A) => Effect<boolean>;
readonly canDeactivate: (params: A) => Effect<boolean>;
}
/**
* Route Tree for nested routing
*/
export interface RouteTree<A> {
readonly route: Route<A>;
readonly children?: RouteTree<any>[];
readonly component?: (props: A) => any;
readonly guards?: RouteGuard<A>[];
}
/**
* Router Signal - reactive route management
*/
export interface RouterSignal<A> extends Signal<A | null> {
readonly route: Signal<Option<Route<A>>>;
readonly params: Signal<A | null>;
readonly navigate: (to: string) => Effect<void>;
readonly back: () => Effect<void>;
readonly forward: () => Effect<void>;
readonly replace: (to: string) => Effect<void>;
}
/**
* Type-level path parsing
*/
export type ParsePath<T extends string> = T extends `${infer _Head}/:${infer Param}/${infer Tail}` ? {
[K in Param]: string;
} & ParsePath<Tail> : T extends `${infer _Head}/:${infer Param}` ? {
[K in Param]: string;
} : T extends `${infer _Head}?${infer Query}` ? ParseQuery<Query> : {};
export type ParseQuery<T extends string> = T extends `${infer Key}=${infer _Value}&${infer Rest}` ? {
[K in Key]?: string;
} & ParseQuery<Rest> : T extends `${infer Key}=${infer _Value}` ? {
[K in Key]?: string;
} : {};
/**
* Prefetch Strategy
*/
export interface PrefetchStrategy {
readonly onHover: boolean;
readonly onIdle: boolean;
readonly preload: string[];
}
/**
* Route Match Result
*/
export interface RouteMatch<A> {
readonly route: Route<A>;
readonly params: A;
readonly path: string;
}