UNPKG

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.

170 lines 12.7 kB
/** * Router Coalgebra Implementation * Isomorphic router with Signal integration */ import { Some, None } from './types'; import { signal } from '../core/signal'; import { matchRoute } from './route'; import { createNavigationEffects } from './navigation'; /** * Creates a router coalgebra that maintains isomorphism * between path strings and route states */ export const createRouter = (routes, env) => { const routerInstance = { route: (path) => { return matchRoute(routes, path); }, generate: (state) => { // Find the first route that can generate a path for this state for (const route of routes) { try { return route.generate(state); } catch { continue; } } throw new Error('No route found for state'); }, current: signal(matchRoute(routes, env.getCurrentPath())), params: signal((() => { const match = matchRoute(routes, env.getCurrentPath()); if (match.tag === 'Some') { const parsed = match.value.parse(env.getCurrentPath()); return parsed; } return null; })()) }; // Update signals when path changes env.onPathChange((newPath) => { const newMatch = matchRoute(routes, newPath); routerInstance.current._set(newMatch); if (newMatch.tag === 'Some') { const parsed = newMatch.value.parse(newPath); routerInstance.params._set(parsed); } else { routerInstance.params._set(null); } }); return routerInstance; }; /** * Creates a reactive router signal */ export const createRouterSignal = (routes, env) => { const router = createRouter(routes, env); const navEffects = createNavigationEffects(env); const routerSignal = { value: () => router.params.value(), map: (f) => { return router.params.map(f); }, subscribe: (fn) => { return router.params.subscribe(fn); }, route: router.current, params: router.params, navigate: (to) => { return navEffects.push(to); }, back: () => { return navEffects.back(); }, forward: () => { return navEffects.forward(); }, replace: (to) => { return navEffects.replace(to); } }; return routerSignal; }; /** * Route Tree Matching - for nested routing */ export const matchRouteTree = (tree, path) => { // Try to match the current route if (tree.route.matches(path)) { const params = tree.route.parse(path); if (params) { return Some({ route: tree.route, params, path }); } } // Try children if they exist if (tree.children) { for (const child of tree.children) { const childMatch = matchRouteTree(child, path); if (childMatch.tag === 'Some') { return childMatch; } } } return None; }; /** * Route Tree Router - for complex nested routing */ export const createTreeRouter = (tree, env) => { const currentMatch = signal(matchRouteTree(tree, env.getCurrentPath())); const navEffects = createNavigationEffects(env); // Update match when path changes env.onPathChange((newPath) => { const newMatch = matchRouteTree(tree, newPath); currentMatch._set(newMatch); }); const routerSignal = { value: () => { const match = currentMatch.value(); return match.tag === 'Some' ? match.value.params : null; }, map: (f) => { return currentMatch.map(match => match.tag === 'Some' ? f(match.value.params) : f(null)); }, subscribe: (fn) => { return currentMatch.subscribe(match => { fn(match.tag === 'Some' ? match.value.params : null); }); }, route: currentMatch.map(match => match.tag === 'Some' ? Some(match.value.route) : None), params: currentMatch.map(match => match.tag === 'Some' ? match.value.params : null), navigate: (to) => { return navEffects.push(to); }, back: () => { return navEffects.back(); }, forward: () => { return navEffects.forward(); }, replace: (to) => { return navEffects.replace(to); } }; return routerSignal; }; /** * Router factory with environment detection */ export const router = (routes, env) => { const environment = env || (typeof window !== 'undefined' ? require('./navigation').createBrowserNav() : require('./navigation').createNodeNav()); return createRouterSignal(routes, environment); }; /** * Tree router factory with environment detection */ export const treeRouter = (tree, env) => { const environment = env || (typeof window !== 'undefined' ? require('./navigation').createBrowserNav() : require('./navigation').createNodeNav()); return createTreeRouter(tree, environment); }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3JvdXRlci9yb3V0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUE4RCxJQUFJLEVBQUUsSUFBSSxFQUFpQixNQUFNLFNBQVMsQ0FBQztBQUNoSCxPQUFPLEVBQVUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNyQyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFdkQ7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLENBQzFCLE1BQXNCLEVBQ3RCLEdBQWtCLEVBQ0gsRUFBRTtJQUNqQixNQUFNLGNBQWMsR0FBa0I7UUFDcEMsS0FBSyxFQUFFLENBQUMsSUFBWSxFQUF3QixFQUFFO1lBQzVDLE9BQU8sVUFBVSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBRUQsUUFBUSxFQUFFLENBQUMsS0FBWSxFQUFVLEVBQUU7WUFDakMsK0RBQStEO1lBQy9ELEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQzNCLElBQUksQ0FBQztvQkFDSCxPQUFPLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQy9CLENBQUM7Z0JBQUMsTUFBTSxDQUFDO29CQUNQLFNBQVM7Z0JBQ1gsQ0FBQztZQUNILENBQUM7WUFDRCxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUV6RCxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFO1lBQ25CLE1BQU0sS0FBSyxHQUFH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