eleva
Version:
A minimalist and lightweight, pure vanilla JavaScript frontend runtime framework.
500 lines • 19.9 kB
TypeScript
export type RouterPlugin = {
/**
* - The plugin name.
*/
name: string;
/**
* - The plugin version.
*/
version?: string | undefined;
/**
* - The install function that receives the router instance.
*/
install: Function;
/**
* - Optional cleanup function called when the router is destroyed.
*/
destroy?: Function | undefined;
};
export namespace RouterPlugin {
let name: string;
let version: string;
let description: string;
/**
* Installs the RouterPlugin into an Eleva instance.
*
* @param {Eleva} eleva - The Eleva instance
* @param {RouterOptions} options - Router configuration options
* @param {string} options.mount - A CSS selector for the main element where the app is mounted
* @param {RouteDefinition[]} options.routes - An array of route definitions
* @param {'hash' | 'query' | 'history'} [options.mode='hash'] - The routing mode
* @param {string} [options.queryParam='page'] - The query parameter to use in 'query' mode
* @param {string} [options.viewSelector='view'] - The selector for the view element within a layout
* @param {boolean} [options.autoStart=true] - Whether to start the router automatically
* @param {NavigationGuard} [options.onBeforeEach] - A global guard executed before every navigation
* @param {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [options.globalLayout] - A global layout for all routes
*
* @example
* // main.js
* import Eleva from './eleva.js';
* import { RouterPlugin } from './plugins/RouterPlugin.js';
*
* const app = new Eleva('myApp');
*
* const HomePage = { template: () => `<h1>Home</h1>` };
* const AboutPage = { template: () => `<h1>About Us</h1>` };
*
* app.use(RouterPlugin, {
* mount: '#app',
* routes: [
* { path: '/', component: HomePage },
* { path: '/about', component: AboutPage }
* ]
* });
*/
function install(eleva: Eleva, options?: RouterOptions): Router;
/**
* Uninstalls the plugin from the Eleva instance
*
* @param {Eleva} eleva - The Eleva instance
*/
function uninstall(eleva: Eleva): Promise<void>;
}
export type Eleva = any;
export type Signal = any;
export type ComponentDefinition = any;
export type RouteLocation = {
/**
* - The path of the route (e.g., '/users/123').
*/
path: string;
/**
* - An object representing the query parameters.
*/
query: {
[x: string]: string;
};
/**
* - The complete URL including hash, path, and query string.
*/
fullUrl: string;
/**
* - An object containing dynamic route parameters.
*/
params: {
[x: string]: string;
};
/**
* - The meta object associated with the matched route.
*/
meta: {
[x: string]: any;
};
/**
* - The optional name of the matched route.
*/
name?: string | undefined;
/**
* - The raw route definition object that was matched.
*/
matched: RouteDefinition;
};
/**
* A function that acts as a guard for navigation. It runs *before* the navigation is confirmed.
* It can return:
* - `true` or `undefined`: to allow navigation.
* - `false`: to abort the navigation.
* - a `string` (path) or a `location object`: to redirect to a new route.
*/
export type NavigationGuard = (to: RouteLocation, from: RouteLocation | null) => boolean | string | {
path: string;
} | void | Promise<boolean | string | {
path: string;
} | void>;
/**
* A function that acts as a lifecycle hook, typically for side effects. It does not affect navigation flow.
*/
export type NavigationHook = (...args: any[]) => void | Promise<void>;
export type RouteDefinition = {
/**
* - The URL path pattern (e.g., '/', '/about', '/users/:id', '*').
*/
path: string;
/**
* - The component to render. Can be a registered name, a definition object, or an async import function.
*/
component: string | ComponentDefinition | (() => Promise<{
default: ComponentDefinition;
}>);
/**
* - An optional layout component to wrap the route's component.
*/
layout?: string | ComponentDefinition | (() => Promise<{
default: ComponentDefinition;
}>);
/**
* - An optional name for the route.
*/
name?: string | undefined;
/**
* - Optional metadata for the route (e.g., for titles, auth flags).
*/
meta?: {
[x: string]: any;
} | undefined;
/**
* - A route-specific guard executed before entering the route.
*/
beforeEnter?: NavigationGuard | undefined;
/**
* - A hook executed *after* the route has been entered and the new component is mounted.
*/
afterEnter?: NavigationHook | undefined;
/**
* - A guard executed *before* leaving the current route.
*/
beforeLeave?: NavigationGuard | undefined;
/**
* - A hook executed *after* leaving the current route and its component has been unmounted.
*/
afterLeave?: NavigationHook | undefined;
};
export type RouterOptions = {
/**
* - A CSS selector for the main element where the app is mounted.
*/
mount: string;
/**
* - An array of route definitions.
*/
routes: RouteDefinition[];
/**
* - The routing mode.
*/
mode?: "hash" | "query" | "history" | undefined;
/**
* - The query parameter to use in 'query' mode.
*/
queryParam?: string | undefined;
/**
* - The selector for the view element within a layout.
*/
viewSelector?: string | undefined;
/**
* - Whether to start the router automatically.
*/
autoStart?: boolean | undefined;
/**
* - A global guard executed before every navigation.
*/
onBeforeEach?: NavigationGuard | undefined;
/**
* - A global layout for all routes. Can be overridden by a route's specific layout.
*/
globalLayout?: string | ComponentDefinition | (() => Promise<{
default: ComponentDefinition;
}>);
};
/**
* @typedef {Object} RouteLocation
* @property {string} path - The path of the route (e.g., '/users/123').
* @property {Object<string, string>} query - An object representing the query parameters.
* @property {string} fullUrl - The complete URL including hash, path, and query string.
* @property {Object<string, string>} params - An object containing dynamic route parameters.
* @property {Object<string, any>} meta - The meta object associated with the matched route.
* @property {string} [name] - The optional name of the matched route.
* @property {RouteDefinition} matched - The raw route definition object that was matched.
*/
/**
* @typedef {(to: RouteLocation, from: RouteLocation | null) => boolean | string | {path: string} | void | Promise<boolean | string | {path: string} | void>} NavigationGuard
* A function that acts as a guard for navigation. It runs *before* the navigation is confirmed.
* It can return:
* - `true` or `undefined`: to allow navigation.
* - `false`: to abort the navigation.
* - a `string` (path) or a `location object`: to redirect to a new route.
*/
/**
* @typedef {(...args: any[]) => void | Promise<void>} NavigationHook
* A function that acts as a lifecycle hook, typically for side effects. It does not affect navigation flow.
*/
/**
* @typedef {Object} RouterPlugin
* @property {string} name - The plugin name.
* @property {string} [version] - The plugin version.
* @property {Function} install - The install function that receives the router instance.
* @property {Function} [destroy] - Optional cleanup function called when the router is destroyed.
*/
/**
* @typedef {Object} RouteDefinition
* @property {string} path - The URL path pattern (e.g., '/', '/about', '/users/:id', '*').
* @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} component - The component to render. Can be a registered name, a definition object, or an async import function.
* @property {string | ComponentDefinition | (() => Promise<{default: ComponentDefinition}>)} [layout] - An optional layout component to wrap the route's component.
* @property {string} [name] - An optional name for the route.
* @property {Object<string, any>} [meta] - Optional metadata for the route (e.g., for titles, auth flags).
* @property {NavigationGuard} [beforeEnter] - A route-specific guard executed before entering the route.
* @property {NavigationHook} [afterEnter] - A hook executed *after* the route has been entered and the new component is mounted.
* @property {NavigationGuard} [beforeLeave] - A guard executed *before* leaving the current route.
* @property {NavigationHook} [afterLeave] - A hook executed *after* leaving the current route and its component has been unmounted.
*/
/**
* @class Router
* @classdesc A powerful, reactive, and flexible Router Plugin for Eleva.js.
* This class manages all routing logic, including state, navigation, and rendering.
* @private
*/
declare class Router {
/**
* Creates an instance of the Router.
* @param {Eleva} eleva - The Eleva framework instance.
* @param {RouterOptions} options - The configuration options for the router.
*/
constructor(eleva: Eleva, options?: RouterOptions);
/** @type {Eleva} The Eleva framework instance. */
eleva: Eleva;
/** @type {RouterOptions} The merged router options. */
options: RouterOptions;
/** @private @type {RouteDefinition[]} The processed list of route definitions. */
private routes;
/** @private @type {import('eleva').Emitter} The shared Eleva event emitter for global hooks. */
private emitter;
/** @private @type {boolean} A flag indicating if the router has been started. */
private isStarted;
/** @private @type {boolean} A flag to prevent navigation loops from history events. */
private _isNavigating;
/** @private @type {Array<() => void>} A collection of cleanup functions for event listeners. */
private eventListeners;
/** @type {Signal<RouteLocation | null>} A reactive signal holding the current route's information. */
currentRoute: Signal<RouteLocation | null>;
/** @type {Signal<RouteLocation | null>} A reactive signal holding the previous route's information. */
previousRoute: Signal<RouteLocation | null>;
/** @type {Signal<Object<string, string>>} A reactive signal holding the current route's parameters. */
currentParams: Signal<{
[x: string]: string;
}>;
/** @type {Signal<Object<string, string>>} A reactive signal holding the current route's query parameters. */
currentQuery: Signal<{
[x: string]: string;
}>;
/** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted layout instance. */
currentLayout: Signal<any | null>;
/** @type {Signal<import('eleva').MountResult | null>} A reactive signal for the currently mounted view (page) instance. */
currentView: Signal<any | null>;
/** @private @type {Map<string, RouterPlugin>} Map of registered plugins by name. */
private plugins;
/** @type {Object} The error handler instance. Can be overridden by plugins. */
errorHandler: Object;
/**
* Validates the provided router options.
* @private
* @throws {Error} If the routing mode is invalid.
*/
private _validateOptions;
/**
* Pre-processes route definitions to parse their path segments for efficient matching.
* @private
* @param {RouteDefinition[]} routes - The raw route definitions.
* @returns {RouteDefinition[]} The processed routes.
*/
private _processRoutes;
/**
* Parses a route path string into an array of static and parameter segments.
* @private
* @param {string} path - The path pattern to parse.
* @returns {Array<{type: 'static' | 'param', value?: string, name?: string}>} An array of segment objects.
* @throws {Error} If the route path is not a valid string.
*/
private _parsePathIntoSegments;
/**
* Finds the view element within a container using multiple selector strategies.
* @private
* @param {HTMLElement} container - The parent element to search within.
* @returns {HTMLElement} The found view element or the container itself as a fallback.
*/
private _findViewElement;
/**
* Starts the router, initializes event listeners, and performs the initial navigation.
* @returns {Promise<void>}
*/
start(): Promise<void>;
/**
* Stops the router and cleans up all event listeners and mounted components.
* @returns {Promise<void>}
*/
destroy(): Promise<void>;
/**
* Programmatically navigates to a new route.
* @param {string | {path: string, query?: object, params?: object, replace?: boolean, state?: object}} location - The target location as a string or object.
* @param {object} [params] - Optional route parameters (for string-based location).
* @returns {Promise<void>}
*/
navigate(location: string | {
path: string;
query?: object;
params?: object;
replace?: boolean;
state?: object;
}, params?: object): Promise<void>;
/**
* Builds a URL for query mode.
* @private
* @param {string} path - The path to set as the query parameter.
* @returns {string} The full URL with the updated query string.
*/
private _buildQueryUrl;
/**
* Checks if the target route is identical to the current route.
* @private
* @param {string} path - The target path with query string.
* @param {object} params - The target params.
* @param {object} query - The target query.
* @returns {boolean} - True if the routes are the same.
*/
private _isSameRoute;
/**
* Injects dynamic parameters into a path string.
* @private
*/
private _buildPath;
/**
* The handler for browser-initiated route changes (e.g., back/forward buttons).
* @private
*/
private _handleRouteChange;
/**
* Manages the core navigation lifecycle. Runs guards before committing changes.
* @private
* @param {string} fullPath - The full path (e.g., '/users/123?foo=bar') to navigate to.
* @returns {Promise<boolean>} - `true` if navigation succeeded, `false` if aborted.
*/
private _proceedWithNavigation;
/**
* Executes all applicable navigation guards for a transition in order.
* @private
* @returns {Promise<boolean>} - `false` if navigation should be aborted.
*/
private _runGuards;
/**
* Resolves a string component definition to a component object.
* @private
* @param {string} def - The component name to resolve.
* @returns {ComponentDefinition} The resolved component.
* @throws {Error} If the component is not registered.
*/
private _resolveStringComponent;
/**
* Resolves a function component definition to a component object.
* @private
* @param {Function} def - The function to resolve.
* @returns {Promise<ComponentDefinition>} The resolved component.
* @throws {Error} If the function fails to load the component.
*/
private _resolveFunctionComponent;
/**
* Validates a component definition object.
* @private
* @param {any} def - The component definition to validate.
* @returns {ComponentDefinition} The validated component.
* @throws {Error} If the component definition is invalid.
*/
private _validateComponentDefinition;
/**
* Resolves a component definition to a component object.
* @private
* @param {any} def - The component definition to resolve.
* @returns {Promise<ComponentDefinition | null>} The resolved component or null.
*/
private _resolveComponent;
/**
* Asynchronously resolves the layout and page components for a route.
* @private
* @param {RouteDefinition} route - The route to resolve components for.
* @returns {Promise<{layoutComponent: ComponentDefinition | null, pageComponent: ComponentDefinition}>}
*/
private _resolveComponents;
/**
* Renders the components for the current route into the DOM.
* @private
* @param {ComponentDefinition | null} layoutComponent - The pre-loaded layout component.
* @param {ComponentDefinition} pageComponent - The pre-loaded page component.
*/
private _render;
/**
* Creates a getter function for router context properties.
* @private
* @param {string} property - The property name to access.
* @param {any} defaultValue - The default value if property is undefined.
* @returns {Function} A getter function.
*/
private _createRouteGetter;
/**
* Wraps a component definition to inject router-specific context into its setup function.
* @private
* @param {ComponentDefinition} component - The component to wrap.
* @returns {ComponentDefinition} The wrapped component definition.
*/
private _wrapComponent;
/**
* Recursively wraps all child components to ensure they have access to router context.
* @private
* @param {ComponentDefinition} component - The component to wrap.
* @returns {ComponentDefinition} The wrapped component definition.
*/
private _wrapComponentWithChildren;
/**
* Gets the current location information from the browser's window object.
* @private
* @returns {Omit<RouteLocation, 'params' | 'meta' | 'name' | 'matched'>}
*/
private _getCurrentLocation;
/**
* Parses a query string into a key-value object.
* @private
*/
private _parseQuery;
/**
* Matches a given path against the registered routes.
* @private
* @param {string} path - The path to match.
* @returns {{route: RouteDefinition, params: Object<string, string>} | null} The matched route and its params, or null.
*/
private _matchRoute;
/** Registers a global pre-navigation guard. */
onBeforeEach(guard: any): void;
/** Registers a global hook that runs after a new route component has been mounted *if* the route has an `afterEnter` hook. */
onAfterEnter(hook: any): void;
/** Registers a global hook that runs after a route component has been unmounted *if* the route has an `afterLeave` hook. */
onAfterLeave(hook: any): void;
/** Registers a global hook that runs after a navigation has been confirmed and all hooks have completed. */
onAfterEach(hook: any): void;
/** Registers a global error handler for navigation. */
onError(handler: any): void;
/**
* Registers a plugin with the router.
* @param {RouterPlugin} plugin - The plugin to register.
*/
use(plugin: RouterPlugin, options?: {}): void;
/**
* Gets all registered plugins.
* @returns {RouterPlugin[]} Array of registered plugins.
*/
getPlugins(): RouterPlugin[];
/**
* Gets a plugin by name.
* @param {string} name - The plugin name.
* @returns {RouterPlugin | undefined} The plugin or undefined.
*/
getPlugin(name: string): RouterPlugin | undefined;
/**
* Removes a plugin from the router.
* @param {string} name - The plugin name.
* @returns {boolean} True if the plugin was removed.
*/
removePlugin(name: string): boolean;
/**
* Sets a custom error handler. Used by error handling plugins.
* @param {Object} errorHandler - The error handler object with handle, warn, and log methods.
*/
setErrorHandler(errorHandler: Object): void;
}
export {};
//# sourceMappingURL=Router.d.ts.map