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.

184 lines 14.2 kB
/** * Framework Adapters for Router * Universal router integration with React, Svelte, Vue, etc. */ import { router, treeRouter } from './router'; import { createBrowserNav, createNodeNav } from './navigation'; /** * React Router Adapter */ export const useReactRouter = (routes) => { const React = require('react'); const routerSignal = router(routes, createBrowserNav()); // Force re-renders when route changes const [, forceUpdate] = React.useReducer((x) => x + 1, 0); React.useEffect(() => { const unsubscribe = routerSignal.subscribe(() => forceUpdate()); return unsubscribe; }, []); return { route: routerSignal.route.value(), params: routerSignal.params.value(), navigate: (to) => { routerSignal.navigate(to); }, back: () => routerSignal.back(), forward: () => routerSignal.forward(), replace: (to) => routerSignal.replace(to) }; }; /** * React Tree Router Adapter */ export const useReactTreeRouter = (tree) => { const React = require('react'); const routerSignal = treeRouter(tree, createBrowserNav()); const [, forceUpdate] = React.useReducer((x) => x + 1, 0); React.useEffect(() => { const unsubscribe = routerSignal.subscribe(() => forceUpdate()); return unsubscribe; }, []); return { route: routerSignal.route.value(), params: routerSignal.params.value(), navigate: (to) => routerSignal.navigate(to), back: () => routerSignal.back(), forward: () => routerSignal.forward(), replace: (to) => routerSignal.replace(to) }; }; /** * Svelte Router Adapter */ export const useSvelteRouter = (routes) => { const routerSignal = router(routes, createBrowserNav()); // In Svelte 5, we can use $effect for reactivity if (typeof globalThis !== 'undefined' && globalThis.$effect) { globalThis.$effect(() => { // This will automatically track the router signal routerSignal.value(); }); } return { route: routerSignal.route, params: routerSignal.params, navigate: (to) => routerSignal.navigate(to), back: () => routerSignal.back(), forward: () => routerSignal.forward(), replace: (to) => routerSignal.replace(to) }; }; /** * Vue Router Adapter */ export const useVueRouter = (routes) => { const vue = require('vue'); const routerSignal = router(routes, createBrowserNav()); const route = vue.ref(routerSignal.route.value()); const params = vue.ref(routerSignal.params.value()); // Watch for changes routerSignal.subscribe(() => { route.value = routerSignal.route.value(); params.value = routerSignal.params.value(); }); return { route, params, navigate: (to) => routerSignal.navigate(to), back: () => routerSignal.back(), forward: () => routerSignal.forward(), replace: (to) => routerSignal.replace(to) }; }; /** * SolidJS Router Adapter */ export const useSolidRouter = (routes) => { const solid = require('solid-js'); const routerSignal = router(routes, createBrowserNav()); const [route, setRoute] = solid.createSignal(routerSignal.route.value()); const [params, setParams] = solid.createSignal(routerSignal.params.value()); // Subscribe to changes routerSignal.subscribe(() => { setRoute(routerSignal.route.value()); setParams(routerSignal.params.value()); }); return { route, params, navigate: (to) => routerSignal.navigate(to), back: () => routerSignal.back(), forward: () => routerSignal.forward(), replace: (to) => routerSignal.replace(to) }; }; /** * Universal Router Hook * Automatically detects framework and returns appropriate adapter */ export const useRouter = (routes) => { // Framework detection if (typeof window !== 'undefined') { // Check for React if (globalThis.React || window.React) { return useReactRouter(routes); } // Check for Vue if (globalThis.Vue || window.Vue) { return useVueRouter(routes); } // Check for SolidJS if (globalThis.solid || window.solid) { return useSolidRouter(routes); } // Default to Svelte return useSvelteRouter(routes); } // SSR fallback return { route: { tag: 'None' }, params: null, navigate: (_to) => { }, back: () => { }, forward: () => { }, replace: (_to) => { } }; }; /** * Server-Side Rendering Adapter */ export const createSSRRouter = (routes, initialPath) => { const env = createNodeNav(initialPath); const routerSignal = router(routes, env); return { getRoute: () => routerSignal.route.value(), getParams: () => routerSignal.params.value(), setPath: (path) => env.setPath(path), render: () => { const route = routerSignal.route.value(); const params = routerSignal.params.value(); return { route, params, path: env.getCurrentPath() }; } }; }; /** * Testing Adapter */ export const createTestRouter = (routes, initialPath = '/') => { const { createMemoryNav } = require('./navigation'); const env = createMemoryNav(initialPath); const routerSignal = router(routes, env); return { router: routerSignal, navigate: (to) => routerSignal.navigate(to), getPath: () => env.getCurrentPath(), setPath: (path) => env.setPath(path), back: () => routerSignal.back(), forward: () => routerSignal.forward() }; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRhcHRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcm91dGVyL2FkYXB0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUdILE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFL0Q7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBSSxNQUFrQixFQUFFLEVBQUU7SUFDdEQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9CLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO0lBRXhELHNDQUFzQztJQUN0QyxNQUFNLENBQUMsRUFBRSxXQUFXLENBQUMsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRWxFLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ25CLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNoRSxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFUCxPQUFPO1FBQ0wsS0FBSyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFO1FBQ2pDLE1BQU0sRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNuQyxRQUFRLEVBQUUsQ0FBQyxFQUFVLEVBQUUsRUFBRTtZQUN2QixZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFDRCxJQUFJLEVB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