@ilha/router 0.8.5 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -65,6 +65,10 @@ export type Loader<T> = (ctx: LoaderContext) => Promise<T> | T;
65
65
  /**
66
66
  * Identity function for declaring a loader. Exists purely as a type anchor and
67
67
  * a marker for the Vite plugin to detect by export name.
68
+ *
69
+ * Loaders must read `ctx.params`/`ctx.url` rather than `useRoute()` — the
70
+ * route store still holds the previous route while a navigation's loader is
71
+ * in flight, so `useRoute().params()` inside a loader reads stale params.
68
72
  */
69
73
  export declare function loader<T>(fn: Loader<T>): Loader<T>;
70
74
  /** Extract the return type of a loader. */
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as wrapLayout, C as routePath, D as src_default, E as serializeHead, M as setHistoryMode, O as useRoute, S as routeParams, T as router, _ as navigating, a as RouterView, b as redirect, c as composeLoaders, d as error, f as head, g as navigate, h as loader, i as RouterLink, j as getHistoryMode, k as wrapError, l as defineLayout, m as isActive, n as LoaderError, o as afterNavigate, p as invalidate, r as Redirect, s as beforeNavigate, t as LOADER_ENDPOINT, u as enableLinkInterception, v as prefetch, w as routeSearch, x as routeHash, y as prime } from "./src-C2_zEYnV.js";
1
+ import { A as wrapLayout, C as routePath, D as src_default, E as serializeHead, M as setHistoryMode, O as useRoute, S as routeParams, T as router, _ as navigating, a as RouterView, b as redirect, c as composeLoaders, d as error, f as head, g as navigate, h as loader, i as RouterLink, j as getHistoryMode, k as wrapError, l as defineLayout, m as isActive, n as LoaderError, o as afterNavigate, p as invalidate, r as Redirect, s as beforeNavigate, t as LOADER_ENDPOINT, u as enableLinkInterception, v as prefetch, w as routeSearch, x as routeHash, y as prime } from "./src-_T1q_MN5.js";
2
2
 
3
3
  export { LOADER_ENDPOINT, LoaderError, Redirect, RouterLink, RouterView, afterNavigate, beforeNavigate, composeLoaders, src_default as default, defineLayout, enableLinkInterception, error, getHistoryMode, head, invalidate, isActive, loader, navigate, navigating, prefetch, prime, redirect, routeHash, routeParams, routePath, routeSearch, router, serializeHead, setHistoryMode, useRoute, wrapError, wrapLayout };
@@ -136,6 +136,10 @@ const isBrowser = typeof window !== "undefined" && typeof document !== "undefine
136
136
  /**
137
137
  * Identity function for declaring a loader. Exists purely as a type anchor and
138
138
  * a marker for the Vite plugin to detect by export name.
139
+ *
140
+ * Loaders must read `ctx.params`/`ctx.url` rather than `useRoute()` — the
141
+ * route store still holds the previous route while a navigation's loader is
142
+ * in flight, so `useRoute().params()` inside a loader reads stale params.
139
143
  */
140
144
  function loader(fn) {
141
145
  return fn;
@@ -1534,11 +1538,13 @@ function router(options = {}) {
1534
1538
  if (getHistoryMode() === "hash") console.warn("[ilha-router] mount({ hydrate: true }) was called in hash mode. SSR + hydration assumes the server can render the active route, but in hash mode the server only ever sees the document URL. Use plain SPA mode (`mount(target)` without `hydrate: true`) for hash-mode apps.");
1535
1539
  const viewHost = host.querySelector("[data-router-view]") ?? host;
1536
1540
  let currentMountedIsland = activeIsland();
1541
+ let currentMountedPath = routePath() + routeSearch();
1537
1542
  const reverseRegistry = registry ? buildReverseRegistry(registry) : void 0;
1538
1543
  let navVersion = 0;
1539
1544
  const NavHandler = ilha.render(() => {
1540
1545
  const current = activeIsland();
1541
- if (current !== currentMountedIsland) {
1546
+ const pathWithSearch = routePath() + routeSearch();
1547
+ if (current !== currentMountedIsland || pathWithSearch !== currentMountedPath) {
1542
1548
  const thisNav = ++navVersion;
1543
1549
  navAbort?.abort();
1544
1550
  navAbort = new AbortController();
@@ -1549,8 +1555,7 @@ function router(options = {}) {
1549
1555
  unmountView?.();
1550
1556
  unmountView = null;
1551
1557
  try {
1552
- const loc = getAdapter().readLocation();
1553
- unmountView = await mountRouteWithHydration(current, viewHost, loc.pathname + loc.search, signal, registry, reverseRegistry);
1558
+ unmountView = await mountRouteWithHydration(current, viewHost, pathWithSearch, signal, registry, reverseRegistry);
1554
1559
  } catch (e) {
1555
1560
  if (e?.name === "AbortError") return;
1556
1561
  console.error("[ilha-router] navigation failed:", e);
@@ -1560,6 +1565,7 @@ function router(options = {}) {
1560
1565
  settle();
1561
1566
  }
1562
1567
  currentMountedIsland = current;
1568
+ currentMountedPath = pathWithSearch;
1563
1569
  });
1564
1570
  }
1565
1571
  return "";
@@ -1607,11 +1613,13 @@ function router(options = {}) {
1607
1613
  const settle = beginNavigation();
1608
1614
  try {
1609
1615
  const loc = getAdapter().readLocation();
1610
- const um = await mountRouteWithHydration(island, viewHost, loc.pathname + loc.search, ac.signal, registry, reverseRegistry);
1616
+ const pathWithSearch = loc.pathname + loc.search;
1617
+ const um = await mountRouteWithHydration(island, viewHost, pathWithSearch, ac.signal, registry, reverseRegistry);
1611
1618
  if (thisNav === navVersion) {
1612
1619
  unmountView?.();
1613
1620
  unmountView = um;
1614
1621
  currentMountedIsland = island;
1622
+ currentMountedPath = pathWithSearch;
1615
1623
  } else um();
1616
1624
  } catch (e) {
1617
1625
  if (e?.name !== "AbortError") console.error("[ilha-router] invalidate failed:", e);
@@ -1636,6 +1644,7 @@ function router(options = {}) {
1636
1644
  }
1637
1645
  let unmountIsland = null;
1638
1646
  let currentMountedIsland = null;
1647
+ let currentMountedPath = null;
1639
1648
  let navVersion = 0;
1640
1649
  unmountView = RouterView.mount(host);
1641
1650
  /**
@@ -1647,6 +1656,7 @@ function router(options = {}) {
1647
1656
  unmountIsland?.();
1648
1657
  unmountIsland = null;
1649
1658
  currentMountedIsland = island;
1659
+ currentMountedPath = routePath() + routeSearch();
1650
1660
  if (!island) {
1651
1661
  const nfHost = host?.querySelector("[data-router-not-found]");
1652
1662
  if (_notFound && nfHost) unmountIsland = _notFound.mount(nfHost);
@@ -1693,7 +1703,8 @@ function router(options = {}) {
1693
1703
  });
1694
1704
  const NavHandler = ilha.render(() => {
1695
1705
  const current = activeIsland();
1696
- if (current !== currentMountedIsland) {
1706
+ const pathWithSearch = routePath() + routeSearch();
1707
+ if (current !== currentMountedIsland || pathWithSearch !== currentMountedPath) {
1697
1708
  const thisNav = ++navVersion;
1698
1709
  navAbort?.abort();
1699
1710
  navAbort = new AbortController();
package/dist/ssr.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as LOADER_ENDPOINT } from "./src-C2_zEYnV.js";
1
+ import { t as LOADER_ENDPOINT } from "./src-_T1q_MN5.js";
2
2
  import { pageRouter, registry } from "ilha:pages/server";
3
3
  import "ilha:loaders";
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilha/router",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "A tiny SPA router for Ilha",
5
5
  "keywords": [
6
6
  "frontend",