Repository navigation
0.2.0
What changed
Plugin
- Windows path fix —
fileToRoute()now normalizes backslashes to forward slashes, preventingPARSE_ERRORfrom OXC parser when route paths contain Windows separators. - Layout resolution fix —
findLayouts()now normalizes allpath.join()output withnormalizePath(), fixing layout detection and import paths on Windows.
Router
- Layout chain rendering — plugin now generates
{ route, component, layouts, leaf }for routes with layouts. Client router builds layout chains inside-out (leaf → innermost layout → outermost layout) with prefix-diff detection to reuse shared layouts across sibling pages. RouteLayouttype — new type for{ path, component }layout entries in the generated route modules.routerState._oldValnon-reactive reads —microStore()now exposes_oldValgetters backed byrawVal, which never create reactive subscriptions (van.state().rawValstays in sync with.valonvanjs-core, with a.valfallback onmini-van-plate). Everything except navigation signals is read through it.- Single Router instance with
hydrate(main, App)—Router()setup reads (pathname,searchParams) are non-reactive, so the template pattern of passingAppas a function no longer re-creates the whole Router (and its derive, layout state and outlet) on every navigation. Fixes layout DOM being rebuilt and lifecycle executions accumulating by one per navigation. - Search-aware routing — client derives (hydration and SPA) now subscribe to both
pathnameandsearchParams, so same-path query changes (search input, pagination) trigger navigation. VanJS batches the synchronous writes fromsetRouterState()into a single run and ignores same-value writes, so each navigation still executes its lifecycle exactly once. - Stale navigation guard — the
navTokenis re-checked afterexecuteLifecycle(), before any DOM mutation, on both client paths. A slow load from a superseded navigation (e.g. rapid search typing) resolves but never renders over fresh results. - Live-target hydration — after the initial render, client navigations mutate the adopted SSR root instead of the detached render wrapper. Shared layouts swap only the outlet's children, preserving layout DOM and component state;
outletis cleared when leaving layout routes. - Server one-shot render — the server branch inlines resolve → lifecycle → render with no shared
loadingflag. Overlapping SSR requests share therouterStatesingleton, so the client-side loading guard could wrongly bail out withundefined("Render error! Source not recognized"). lazy()component resolution — also resolvesmodule.component(layout-chain modules), not justdefault/Page.
Testing
- 100% coverage — 880/880 statements, 500/500 branches, 162/162 functions, 829/829 lines. New suites: template-pattern hydration (single Router instance, layout DOM preservation, array leaves), search-only navigations with overlapping slow/fast loads on hydration and SPA paths, concurrent SSR renders. Hydration tests now assert on the live DOM like real templates do.
Dependencies
- Updated
vanjs-coreto^1.6.1,@types/nodeto^26.5.1,@vitest/browserto^5.0.1,@vitest/coverage-istanbulto^5.0.1,@vitest/uito^5.0.1,happy-domto^20.14.5,typescriptto7.0.2,viteto^8.3.0,vitestto^5.0.1.
Full Changelog: 0.1.25...0.2.0