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.
190 lines • 13.5 kB
JavaScript
/**
* Navigation Monad Implementation
* Monadic composition for route changes
*/
import { pureEffect } from '../core/effect';
/**
* Creates a Navigation monad that follows monadic laws
*/
const createNavigation = (route, env) => {
const navigationInstance = {
...route,
bind: (f) => {
// Monadic bind - composition of navigations
const currentParams = route.parse(env.getCurrentPath());
if (!currentParams) {
// If current route doesn't match, return a failed navigation
return createNavigation({
path: '',
params: {},
map: (_g) => createNavigation(route, env),
matches: () => false,
parse: () => null,
generate: () => ''
}, env);
}
return f(currentParams);
},
navigate: () => {
return pureEffect((() => {
const currentPath = env.getCurrentPath();
const params = route.parse(currentPath);
if (params) {
return params;
}
else {
// Navigate to this route
const newPath = route.generate({}); // Need params for generation
env.setPath(newPath);
return route.parse(newPath);
}
})());
}
};
return navigationInstance;
};
/**
* Pure function for Navigation monad - left identity law
*/
export const pureNavigation = (value, env) => {
// Create a synthetic route that always matches and returns the value
const syntheticRoute = {
path: env.getCurrentPath(),
params: value,
map: (f) => ({
path: env.getCurrentPath(),
params: f(value),
map: (g) => pureNavigation(g(f(value)), env),
matches: () => true,
parse: () => f(value),
generate: () => env.getCurrentPath()
}),
matches: () => true,
parse: () => value,
generate: () => env.getCurrentPath()
};
return createNavigation(syntheticRoute, env);
};
/**
* Navigation Environment Implementations
*/
/**
* Browser Navigation Environment
*/
export const createBrowserNav = () => ({
getCurrentPath: () => {
if (typeof window === 'undefined')
return '/';
return window.location.pathname + window.location.search + window.location.hash;
},
setPath: (path, replace = false) => {
if (typeof window === 'undefined')
return;
if (replace) {
window.history.replaceState({}, '', path);
}
else {
window.history.pushState({}, '', path);
}
// Dispatch a custom event for listeners
window.dispatchEvent(new PopStateEvent('popstate'));
},
onPathChange: (fn) => {
if (typeof window === 'undefined')
return () => { };
const handler = () => {
fn(window.location.pathname + window.location.search + window.location.hash);
};
window.addEventListener('popstate', handler);
return () => window.removeEventListener('popstate', handler);
}
});
/**
* Node.js Navigation Environment (for SSR)
*/
export const createNodeNav = (initialPath = '/') => {
let currentPath = initialPath;
const listeners = [];
return {
getCurrentPath: () => currentPath,
setPath: (path) => {
currentPath = path;
listeners.forEach(fn => fn(path));
},
onPathChange: (fn) => {
listeners.push(fn);
return () => {
const index = listeners.indexOf(fn);
if (index > -1)
listeners.splice(index, 1);
};
}
};
};
/**
* Memory Navigation Environment (for testing)
*/
export const createMemoryNav = (initialPath = '/') => {
let currentPath = initialPath;
const history = [initialPath];
let currentIndex = 0;
const listeners = [];
const notifyListeners = () => {
listeners.forEach(fn => fn(currentPath));
};
return {
getCurrentPath: () => currentPath,
setPath: (path, replace = false) => {
if (replace) {
history[currentIndex] = path;
}
else {
// Remove any forward history
history.splice(currentIndex + 1);
history.push(path);
currentIndex = history.length - 1;
}
currentPath = path;
notifyListeners();
},
onPathChange: (fn) => {
listeners.push(fn);
return () => {
const index = listeners.indexOf(fn);
if (index > -1)
listeners.splice(index, 1);
};
}
};
};
/**
* Navigation Effects - additional navigation operations
*/
export const createNavigationEffects = (env) => ({
back: () => pureEffect((() => {
if (typeof window !== 'undefined') {
window.history.back();
}
})()),
forward: () => pureEffect((() => {
if (typeof window !== 'undefined') {
window.history.forward();
}
})()),
go: (delta) => pureEffect((() => {
if (typeof window !== 'undefined') {
window.history.go(delta);
}
})()),
replace: (path) => pureEffect((() => {
env.setPath(path, true);
})()),
push: (path) => pureEffect((() => {
env.setPath(path, false);
})())
});
/**
* Export navigation constructor
*/
export const navigation = (route, env) => createNavigation(route, env);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF2aWdhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yb3V0ZXIvbmF2aWdhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFHSCxPQUFPLEVBQVUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEQ7O0dBRUc7QUFDSCxNQUFNLGdCQUFnQixHQUFHLENBQ3ZCLEtBQWUsRUFDZixHQUFrQixFQUNILEVBQUU7SUFDakIsTUFBTSxrQkFBa0IsR0FBa0I7UUFDeEMsR0FBRyxLQUFLO1FBRVIsSUFBSSxFQUFFLENBQUksQ0FBMEIsRUFBaUIsRUFBRTtZQUNyRCw0Q0FBNEM7WUFDNUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ25CLDZEQUE2RDtnQkFDN0QsT0FBTyxnQkFBZ0IsQ0FDckI7b0JBQ0UsSUFBSSxFQUFFLEVBQUU7b0JBQ1IsTUFBTSxFQUFFLEVBQU87b0JBQ2YsR0FBRyxFQUFFLENBQUksRUFBZSxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFZLEVBQUUsR0FBRyxDQUFRO29CQUN2RSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSztvQkFDcEIsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUk7b0JBQ2pCLFFBQVEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFO2lCQUNuQixFQUNELEdBQUcsQ0FDSixDQUFDO1lBQ0osQ0FBQztZQUVELE9BQU8sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFFRCxRQUFRLEVBQUUsR0FBYyxFQUFFO1lBQ3hCLE9BQU8sVUFBVSxDQUFDLENBQUMsR0FBRyxFQUFFO2dCQUN0QixNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3pDLE1B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