import { Component } from '../runtime/define-component'; import { VNode } from '../runtime/h'; /** * Lazy loader. Returns either the Component directly or a module object whose * `default` export is the Component (the shape returned by `import()`). */ export type LazyComponent = (() => Promise) | (() => Promise<{ default: Component; }>); export interface RouteWithComponent { /** URL pattern — same format as RouteDefinition.path (e.g. '/users/:id') */ path: string; /** * The page to render for this route. Either an imported Component (eager — * shipped in the main bundle) or a lazy loader (Vite emits a separate chunk * via dynamic import()). * * { path: '/heavy', component: () => import('./pages/heavy.ark') } * * The first time the route is matched the loader runs; subsequent visits * reuse the resolved Component from cache. */ component: Component | LazyComponent; /** * VNode shown while the lazy component loads. Default: an empty span with * data-ark-loading. */ loading?: () => VNode; /** * VNode shown when the lazy loader rejects. Default: empty span with * data-ark-route-error. The error is also logged to console. */ error?: (err: unknown) => VNode; } export interface RouterViewOptions { /** Routes to match against the current path. */ routes: RouteWithComponent[]; /** * Component rendered when no route matches (404). * Typically loaded from `_error.ark`. */ errorComponent?: Component | LazyComponent; } /** * Creates a RouterView component that reactively renders the page * matched by the current URL path. Supports lazy routes: * * const routes = [ * { path: '/', component: HomePage }, // eager * { path: '/heavy', component: () => import('./heavy.ark') }, // lazy * ] * * With error page (404): * const RouterView = createRouterView({ * routes, * errorComponent: () => import('./pages/_error.ark'), * }) * * Backwards compatible — can also be called with just the routes array: * const RouterView = createRouterView(routes) * * Lazy routes ship in a separate chunk and load on first visit. Subsequent * visits hit the cache. * * Usage A — mount directly as app root: * mount(createRouterView(routes), '#app') * * Usage B — as a variable in an .ark layout template: * // in