@wizecorp/stratusjs
Version:
Stratus React Framework
96 lines • 3.9 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Suspense, lazy, useEffect, useState } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { RouterProvider } from './RouterContext';
import { discoverRoutes } from './routeUtils';
import { getConfig, setConfig } from '../config';
const DefaultFallback = () => _jsx("div", { children: "Loading..." });
const DefaultErrorBoundary = ({ error, retry }) => (_jsxs("div", { children: [_jsx("h2", { children: "An error occurred" }), _jsx("p", { children: error.message }), _jsx("button", { onClick: retry, children: "Retry" })] }));
// Layout cache
const layoutsCache = new Map();
export const AppRouter = ({ config, fallback = _jsx(DefaultFallback, {}), errorBoundary: ErrorBoundary = DefaultErrorBoundary, routes: predefinedRoutes }) => {
const [routes, setRoutes] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Configure Stratus on startup
useEffect(() => {
if (config) {
setConfig(config);
}
}, [config]);
// Route discovery
useEffect(() => {
const loadRoutes = async () => {
try {
setLoading(true);
if (predefinedRoutes) {
setRoutes(predefinedRoutes);
}
else {
const discoveredRoutes = await discoverRoutes();
setRoutes(discoveredRoutes);
}
setError(null);
}
catch (err) {
console.error('Error loading routes:', err);
setError(err instanceof Error ? err : new Error('Unknown error'));
}
finally {
setLoading(false);
}
};
loadRoutes();
}, [predefinedRoutes]);
const retry = () => {
setError(null);
setRoutes([]);
setLoading(true);
// Re-trigger the effect
};
if (loading) {
return _jsx(Suspense, { fallback: fallback, children: fallback });
}
if (error) {
return _jsx(ErrorBoundary, { error: error, retry: retry });
}
return (_jsx(BrowserRouter, { basename: getConfig().basePath, children: _jsx(RouterProvider, { children: _jsx(Routes, { children: routes.map((route) => (_jsx(Route, { path: route.path, element: _jsx(RouteRenderer, { route: route, fallback: fallback }) }, route.path))) }) }) }));
};
const RouteRenderer = ({ route, fallback }) => {
const LazyComponent = lazy(route.component);
const [Layout, setLayout] = useState(null);
// Load layout if necessary
useEffect(() => {
const loadLayout = async () => {
if (!route.layout) {
setLayout(null);
return;
}
// Check cache
if (layoutsCache.has(route.layout)) {
setLayout(layoutsCache.get(route.layout));
return;
}
try {
const config = getConfig();
const layoutPath = `${config.layoutsDir}/${route.layout}`;
const layoutModule = await import(/* @vite-ignore */ layoutPath);
const LayoutComponent = layoutModule.default;
// Cache layout
layoutsCache.set(route.layout, LayoutComponent);
setLayout(() => LayoutComponent);
}
catch (err) {
console.warn(`Layout not found: ${route.layout}`, err);
setLayout(null);
}
};
loadLayout();
}, [route.layout]);
const content = (_jsx(Suspense, { fallback: fallback, children: _jsx(LazyComponent, {}) }));
if (Layout) {
return _jsx(Layout, { children: content });
}
return content;
};
//# sourceMappingURL=AppRouter.js.map