@buzola/router 0.0.17 → 0.0.19

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.
Files changed (59) hide show
  1. package/dist/define/create-page.js +1 -1
  2. package/dist/engine/loader-cache.d.ts +1 -1
  3. package/dist/engine/loader-cache.js +1 -1
  4. package/dist/engine/loader-state.d.ts +5 -5
  5. package/dist/engine/loader-state.d.ts.map +1 -1
  6. package/dist/engine/loader-state.js +8 -8
  7. package/dist/engine/loader-state.js.map +1 -1
  8. package/dist/engine/matcher.js +4 -4
  9. package/dist/engine/matcher.js.map +1 -1
  10. package/dist/engine/navigation-adapter.js +6 -6
  11. package/dist/engine/navigation-adapter.js.map +1 -1
  12. package/dist/engine/route-tree.js +2 -2
  13. package/dist/engine/route-tree.js.map +1 -1
  14. package/dist/engine/router.d.ts +31 -5
  15. package/dist/engine/router.d.ts.map +1 -1
  16. package/dist/engine/router.js +47 -10
  17. package/dist/engine/router.js.map +1 -1
  18. package/dist/engine/types.d.ts +28 -8
  19. package/dist/engine/types.d.ts.map +1 -1
  20. package/dist/engine/utils.d.ts +8 -3
  21. package/dist/engine/utils.d.ts.map +1 -1
  22. package/dist/engine/utils.js +16 -3
  23. package/dist/engine/utils.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/react/hooks.d.ts +2 -2
  28. package/dist/react/hooks.js +1 -1
  29. package/dist/react/link.d.ts +4 -4
  30. package/dist/react/link.js +1 -1
  31. package/dist/react/outlet.js +2 -2
  32. package/dist/react/outlet.js.map +1 -1
  33. package/dist/react/provider.d.ts +4 -1
  34. package/dist/react/provider.d.ts.map +1 -1
  35. package/dist/react/provider.js +6 -0
  36. package/dist/react/provider.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/__tests__/create-page.test.ts +1 -1
  39. package/src/__tests__/loader-cache.test.ts +1 -1
  40. package/src/__tests__/loader-state.test.ts +12 -12
  41. package/src/__tests__/navigation-adapter.test.ts +2 -2
  42. package/src/__tests__/react.test.tsx +70 -4
  43. package/src/__tests__/router.test.ts +223 -4
  44. package/src/__tests__/setup-dom.ts +1 -1
  45. package/src/__tests__/type-safety.test.tsx +22 -22
  46. package/src/define/create-page.tsx +1 -1
  47. package/src/engine/loader-cache.ts +1 -1
  48. package/src/engine/loader-state.ts +9 -9
  49. package/src/engine/matcher.ts +4 -4
  50. package/src/engine/navigation-adapter.ts +6 -6
  51. package/src/engine/route-tree.ts +3 -3
  52. package/src/engine/router.ts +59 -11
  53. package/src/engine/types.ts +30 -8
  54. package/src/engine/utils.ts +16 -3
  55. package/src/index.ts +2 -0
  56. package/src/react/hooks.ts +2 -2
  57. package/src/react/link.tsx +5 -5
  58. package/src/react/outlet.tsx +2 -2
  59. package/src/react/provider.tsx +10 -2
@@ -22,7 +22,7 @@ export type RegisteredPage = keyof BuzolaPageMap & string;
22
22
  */
23
23
  export type PageParams<P extends keyof BuzolaPageMap> = BuzolaPageMap[P];
24
24
  /**
25
- * Effective params for a page — persistent params become optional.
25
+ * Effective params for a page: persistent params become optional.
26
26
  * When BuzolaPersistentParams is empty (default), collapses to BuzolaPageMap[P].
27
27
  */
28
28
  export type EffectivePageParams<P extends keyof BuzolaPageMap> = Omit<BuzolaPageMap[P], keyof BuzolaPersistentParams & string> & Partial<Pick<BuzolaPageMap[P], keyof BuzolaPersistentParams & string & keyof BuzolaPageMap[P]>>;
@@ -43,7 +43,7 @@ export interface StandardSchema<T = unknown> {
43
43
  };
44
44
  };
45
45
  }
46
- /** Route component — either a regular component or a lazy-loaded one. */
46
+ /** Route component: either a regular component or a lazy-loaded one. */
47
47
  export type RouteComponent = ComponentType<Record<string, never>> | LazyExoticComponent<ComponentType<Record<string, never>>>;
48
48
  /** Configuration for a single route. */
49
49
  export interface RouteConfig {
@@ -55,7 +55,7 @@ export interface RouteConfig {
55
55
  component?: RouteComponent;
56
56
  /** Schema for validating search params (Standard Schema compatible). */
57
57
  searchSchema?: StandardSchema;
58
- /** Preload function — triggers lazy component import ahead of navigation. */
58
+ /** Preload function: triggers lazy component import ahead of navigation. */
59
59
  preload?: () => void;
60
60
  /** Child routes. */
61
61
  children?: RouteConfig[];
@@ -63,7 +63,7 @@ export interface RouteConfig {
63
63
  isLayout?: boolean;
64
64
  /** Whether this is an index route (renders at parent's exact path). */
65
65
  isIndex?: boolean;
66
- /** Whether this is a pathless group (e.g., (auth) — no URL segment). */
66
+ /** Whether this is a pathless group (e.g., (auth), with no URL segment). */
67
67
  isPathlessGroup?: boolean;
68
68
  }
69
69
  /** A matched route with extracted params. */
@@ -87,7 +87,7 @@ export interface RouteNode {
87
87
  component?: RouteComponent;
88
88
  /** Search params schema. */
89
89
  searchSchema?: StandardSchema;
90
- /** Preload function — triggers lazy component import ahead of navigation. */
90
+ /** Preload function: triggers lazy component import ahead of navigation. */
91
91
  preload?: () => void;
92
92
  /** Whether this is a layout node (renders children via Outlet). */
93
93
  isLayout: boolean;
@@ -96,7 +96,7 @@ export interface RouteNode {
96
96
  }
97
97
  /** A node in the segment trie used for URL matching. */
98
98
  export interface TrieNode {
99
- /** Static children — exact segment match via Map lookup (O(1)). */
99
+ /** Static children: exact segment match via Map lookup (O(1)). */
100
100
  staticChildren: Map<string, TrieNode>;
101
101
  /**
102
102
  * Dynamic child: matches any single segment. It carries no param name, because routes sharing this
@@ -149,8 +149,8 @@ export interface NavigateOptions {
149
149
  resetScroll?: boolean;
150
150
  /**
151
151
  * Whether the browser moves focus after navigation.
152
- * Defaults to `manual` when only the search string changes — so search boxes, filters and
153
- * pagination controls keep the caret — and to `after-transition` when the path or the hash
152
+ * Defaults to `manual` when only the search string changes (so search boxes, filters and
153
+ * pagination controls keep the caret), and to `after-transition` when the path or the hash
154
154
  * changes, so fragment links move focus to the section they target.
155
155
  */
156
156
  focusReset?: 'after-transition' | 'manual';
@@ -161,6 +161,26 @@ export interface NavigateOptions {
161
161
  * Must return a Promise that resolves to `true` to allow navigation, `false` to block.
162
162
  */
163
163
  export type BlockerFn = () => Promise<boolean>;
164
+ /** A navigation the router is about to intercept, as offered to `shouldIntercept`. */
165
+ export interface InterceptInfo {
166
+ /** Where the navigation goes. */
167
+ destination: URL;
168
+ /**
169
+ * The location the router currently shows. While a navigation is pending, this can differ from
170
+ * `navigation.currentEntry`, which has already moved to that navigation's destination.
171
+ */
172
+ from: URL;
173
+ /** How the navigation moves through history. Reloads always go to the browser and are never offered. */
174
+ navigationType: 'push' | 'replace' | 'traverse';
175
+ /** Whether the user initiated the navigation (e.g., clicking a link). */
176
+ userInitiated: boolean;
177
+ }
178
+ /**
179
+ * Decides whether the router handles a navigation in the current document.
180
+ * Return `false` to have the browser load the destination as a new document instead.
181
+ * Called synchronously from the `navigate` event, so it cannot await anything.
182
+ */
183
+ export type ShouldInterceptFn = (info: InterceptInfo) => boolean;
164
184
  /** Navigate event from the Navigation API (simplified). */
165
185
  export interface BuzolaNavigateEvent {
166
186
  /** The destination URL. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"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"}
@@ -13,12 +13,17 @@ export declare function parseParamSegment(segment: string): {
13
13
  */
14
14
  export declare function extractParamNames(pattern: string): string[];
15
15
  /**
16
- * Whether two URLs address the same page — i.e. only search/hash differ.
16
+ * Whether two URLs address the same page, i.e. only search/hash differ.
17
17
  * Same-path navigations (filters, sorting, pagination, search) keep the page
18
18
  * on screen and keep its loader data as stale; path changes do not.
19
19
  *
20
- * Note this ignores the hash. Callers that care about fragment changes — focus
21
- * handling, for one — have to compare `hash` themselves.
20
+ * Note this ignores the hash. Callers that care about fragment changes (focus
21
+ * handling, for one) have to compare `hash` themselves.
22
22
  */
23
23
  export declare function isSamePath(a: string | URL, b: string | URL): boolean;
24
+ /**
25
+ * Whether going from `from` to `to` is a fragment navigation: the URLs differ at most in the hash and `to`
26
+ * has one. Browsers always perform those within the current document, whether intercepted or not.
27
+ */
28
+ export declare function isFragmentNavigation(from: URL, to: URL): boolean;
24
29
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/engine/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAIxF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAIpE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/engine/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAIxF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ3D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,CAIpE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAOhE"}
@@ -22,16 +22,29 @@ export function extractParamNames(pattern) {
22
22
  return names;
23
23
  }
24
24
  /**
25
- * Whether two URLs address the same page — i.e. only search/hash differ.
25
+ * Whether two URLs address the same page, i.e. only search/hash differ.
26
26
  * Same-path navigations (filters, sorting, pagination, search) keep the page
27
27
  * on screen and keep its loader data as stale; path changes do not.
28
28
  *
29
- * Note this ignores the hash. Callers that care about fragment changes — focus
30
- * handling, for one — have to compare `hash` themselves.
29
+ * Note this ignores the hash. Callers that care about fragment changes (focus
30
+ * handling, for one) have to compare `hash` themselves.
31
31
  */
32
32
  export function isSamePath(a, b) {
33
33
  const urlA = typeof a === 'string' ? new URL(a) : a;
34
34
  const urlB = typeof b === 'string' ? new URL(b) : b;
35
35
  return urlA.origin === urlB.origin && urlA.pathname === urlB.pathname;
36
36
  }
37
+ /**
38
+ * Whether going from `from` to `to` is a fragment navigation: the URLs differ at most in the hash and `to`
39
+ * has one. Browsers always perform those within the current document, whether intercepted or not.
40
+ */
41
+ export function isFragmentNavigation(from, to) {
42
+ if (to.hash === '')
43
+ return false;
44
+ const fromWithoutHash = new URL(from);
45
+ fromWithoutHash.hash = '';
46
+ const toWithoutHash = new URL(to);
47
+ toWithoutHash.hash = '';
48
+ return fromWithoutHash.href === toWithoutHash.href;
49
+ }
37
50
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/engine/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACjE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAChD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,CAAe,EAAE,CAAe;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAA;AACtE,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/engine/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IACxC,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IACjE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;AAC5B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAChD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAA;AACb,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,CAAe,EAAE,CAAe;IAC1D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAA;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAS,EAAE,EAAO;IACtD,IAAI,EAAE,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,KAAK,CAAA;IAChC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAA;IACrC,eAAe,CAAC,IAAI,GAAG,EAAE,CAAA;IACzB,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAA;IACjC,aAAa,CAAC,IAAI,GAAG,EAAE,CAAA;IACvB,OAAO,eAAe,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAAA;AACnD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export type { CreateRouteNodeOptions } from './engine/route-tree.js';
6
6
  export { matchRoutes } from './engine/matcher.js';
7
7
  export { createBrowserNavigationAdapter, createMemoryNavigationAdapter } from './engine/navigation-adapter.js';
8
8
  export type { MemoryNavigationAdapter, MemoryNavigationAdapterOptions } from './engine/navigation-adapter.js';
9
- export type { BlockerFn, BuzolaNavigateEvent, BuzolaPageMap, BuzolaPersistentParams, EffectivePageParams, NavigateOptions, NavigationAdapter, PageParams, RegisteredPage, RouteComponent, RouteConfig, RouteMatch, RouteNode, RouterState, RouteTree, StandardSchema, } from './engine/types.js';
9
+ export type { BlockerFn, BuzolaNavigateEvent, BuzolaPageMap, BuzolaPersistentParams, EffectivePageParams, InterceptInfo, NavigateOptions, NavigationAdapter, PageParams, RegisteredPage, RouteComponent, RouteConfig, RouteMatch, RouteNode, RouterState, RouteTree, ShouldInterceptFn, StandardSchema, } from './engine/types.js';
10
10
  export { s } from './engine/schema.js';
11
11
  export { BuzolaRedirect, createPage, redirect } from './define/create-page.js';
12
12
  export type { CatchContext, PageDefinition, PageProps, RedirectFn } from './define/create-page.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACnE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEzE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAC9G,YAAY,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AAG7G,YAAY,EACX,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,cAAc,GACd,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAGtC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC9E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGlG,OAAO,EACN,cAAc,EACd,aAAa,EACb,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AACnE,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEzE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxE,YAAY,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAC9G,YAAY,EAAE,uBAAuB,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAA;AAG7G,YAAY,EACX,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,cAAc,EACd,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,cAAc,GACd,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAGtC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAC9E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAGlG,OAAO,EACN,cAAc,EACd,aAAa,EACb,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAuB9G,gFAAgF;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAEtC,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAG9E,+EAA+E;AAC/E,OAAO,EACN,cAAc,EACd,aAAa,EACb,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAEtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAGxE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,OAAO,EAAE,8BAA8B,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAA;AAyB9G,gFAAgF;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAEtC,+EAA+E;AAC/E,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAG9E,+EAA+E;AAC/E,OAAO,EACN,cAAc,EACd,aAAa,EACb,IAAI,EACJ,MAAM,EACN,YAAY,EACZ,aAAa,EACb,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,SAAS,EACT,QAAQ,EACR,SAAS,EACT,cAAc,EACd,eAAe,GACf,MAAM,kBAAkB,CAAA"}
@@ -7,7 +7,7 @@ export declare function useRouter(): Router;
7
7
  /**
8
8
  * Type-safe navigation function.
9
9
  * Uses page IDs instead of URL patterns.
10
- * Persistent params are optional — resolved from current URL or fallback.
10
+ * Persistent params are optional: resolved from current URL or fallback.
11
11
  */
12
12
  type NavigateFn = <P extends RegisteredPage>(to: P, ...args: [keyof EffectivePageParams<P>] extends [never] ? [options?: NavigateOptions] : {} extends EffectivePageParams<P> ? [options?: NavigateOptions & {
13
13
  params?: EffectivePageParams<P>;
@@ -16,7 +16,7 @@ type NavigateFn = <P extends RegisteredPage>(to: P, ...args: [keyof EffectivePag
16
16
  }]) => void;
17
17
  /**
18
18
  * Hook to get a type-safe navigate function.
19
- * Navigates using page IDs — the router looks up the route pattern from the page registry.
19
+ * Navigates using page IDs: the router looks up the route pattern from the page registry.
20
20
  */
21
21
  export declare function useNavigate(): NavigateFn;
22
22
  /**
@@ -23,7 +23,7 @@ function useRouteContext() {
23
23
  }
24
24
  /**
25
25
  * Hook to get a type-safe navigate function.
26
- * Navigates using page IDs — the router looks up the route pattern from the page registry.
26
+ * Navigates using page IDs: the router looks up the route pattern from the page registry.
27
27
  */
28
28
  export function useNavigate() {
29
29
  const router = useRouter();
@@ -25,9 +25,9 @@ type LinkPropsBase = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>
25
25
  asChild?: boolean;
26
26
  /**
27
27
  * Prefetch strategy for lazy-loaded route code.
28
- * - `'intent'` — preload on mouseEnter/focus (default)
29
- * - `'render'` — preload as soon as the Link renders
30
- * - `'none'` — disable prefetching
28
+ * - `'intent'`: preload on mouseEnter/focus (default)
29
+ * - `'render'`: preload as soon as the Link renders
30
+ * - `'none'`: disable prefetching
31
31
  */
32
32
  prefetch?: 'intent' | 'render' | 'none';
33
33
  };
@@ -43,7 +43,7 @@ export type LinkProps<P extends RegisteredPage = RegisteredPage> = [keyof Effect
43
43
  };
44
44
  /**
45
45
  * Type-safe link component.
46
- * Uses page IDs for navigation — the router looks up the route pattern from the page registry.
46
+ * Uses page IDs for navigation: the router looks up the route pattern from the page registry.
47
47
  * For simple navigations, renders a native <a> and lets the Navigation API handle it.
48
48
  * Uses programmatic navigation when state, replace, resetScroll, or viewTransition is needed.
49
49
  *
@@ -3,7 +3,7 @@ import React, { useCallback, useEffect, useRef } from 'react';
3
3
  import { useRouter, useRouterState } from './hooks.js';
4
4
  /**
5
5
  * Type-safe link component.
6
- * Uses page IDs for navigation — the router looks up the route pattern from the page registry.
6
+ * Uses page IDs for navigation: the router looks up the route pattern from the page registry.
7
7
  * For simple navigations, renders a native <a> and lets the Navigation API handle it.
8
8
  * Uses programmatic navigation when state, replace, resetScroll, or viewTransition is needed.
9
9
  *
@@ -8,7 +8,7 @@ function DefaultNotFound() {
8
8
  style: { fontFamily: 'system-ui, sans-serif', padding: '2rem', maxWidth: '600px', margin: '0 auto' },
9
9
  }, isDev
10
10
  ? [
11
- React.createElement('h1', { key: 'h' }, '404 — Page Not Found'),
11
+ React.createElement('h1', { key: 'h' }, '404: Page Not Found'),
12
12
  React.createElement('p', { key: 'p1' }, `No route matches "${typeof window !== 'undefined' ? window.location.pathname : ''}".`),
13
13
  React.createElement('p', {
14
14
  key: 'p2',
@@ -56,7 +56,7 @@ export function Outlet({ fallback, errorFallback, notFound }) {
56
56
  };
57
57
  }, [state, depth, effectiveDepth, matches, match, routeContext.params]);
58
58
  if (!match) {
59
- // At root depth with no matches — show 404
59
+ // At root depth with no matches: show 404
60
60
  if (depth === 0 && matches.length === 0) {
61
61
  if (notFound === null)
62
62
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"outlet.js","sourceRoot":"","sources":["../../src/react/outlet.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"outlet.js","sourceRoot":"","sources":["../../src/react/outlet.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Router } from '../engine/router.js';
3
- import type { RouteMatch, RouteTree } from '../engine/types.js';
3
+ import type { RouteMatch, RouteTree, ShouldInterceptFn } from '../engine/types.js';
4
4
  /** Props passed to the middleware component. */
5
5
  export interface MiddlewareProps {
6
6
  /** Merged params from all matched routes. */
@@ -21,11 +21,14 @@ export type BuzolaProviderProps = {
21
21
  routes?: never;
22
22
  persistentParams?: never;
23
23
  pageRegistry?: never;
24
+ shouldIntercept?: never;
24
25
  } | {
25
26
  router?: never;
26
27
  routes: RouteTree;
27
28
  persistentParams?: () => Record<string, string>;
28
29
  pageRegistry?: Record<string, string>;
30
+ /** Decides per navigation whether the router handles it; see `RouterOptions.shouldIntercept`. */
31
+ shouldIntercept?: ShouldInterceptFn;
29
32
  });
30
33
  /**
31
34
  * Root provider for Buzola router.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAA;AAElG,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAI/D,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC/B,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,2CAA2C;IAC3C,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,uCAAuC;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,gEAAgE;AAChE,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;AAEtE,MAAM,MAAM,mBAAmB,GAC5B;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,8FAA8F;IAC9F,UAAU,CAAC,EAAE,mBAAmB,CAAA;CAChC,GACC,CACC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAA;CAAE,GAClF;IACD,MAAM,CAAC,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC,CACD,CAAA;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CA+C9H"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAA;AAElG,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAIlF,gDAAgD;AAChD,MAAM,WAAW,eAAe;IAC/B,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,2CAA2C;IAC3C,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,uCAAuC;IACvC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB;AAED,gEAAgE;AAChE,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;AAEtE,MAAM,MAAM,mBAAmB,GAC5B;IACD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC1B,8FAA8F;IAC9F,UAAU,CAAC,EAAE,mBAAmB,CAAA;CAChC,GACC,CACC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,KAAK,CAAC;IAAC,eAAe,CAAC,EAAE,KAAK,CAAA;CAAE,GAC3G;IACD,MAAM,CAAC,EAAE,KAAK,CAAA;IACd,MAAM,EAAE,SAAS,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,iGAAiG;IACjG,eAAe,CAAC,EAAE,iBAAiB,CAAA;CACnC,CACD,CAAA;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,GAAG,KAAK,CAAC,YAAY,CAqD9H"}
@@ -9,6 +9,11 @@ import { Outlet } from './outlet.js';
9
9
  * Subscribes to router state and provides context to the React tree.
10
10
  */
11
11
  export function BuzolaProvider({ routes, children, middleware: Middleware, ...props }) {
12
+ // The router is created once, so it reads the latest prop through a ref rather than the first render's closure.
13
+ const shouldInterceptRef = useRef(props.shouldIntercept);
14
+ useLayoutEffect(() => {
15
+ shouldInterceptRef.current = props.shouldIntercept;
16
+ });
12
17
  const routerRef = useRef(props.router);
13
18
  if (!routerRef.current) {
14
19
  routerRef.current = new Router({
@@ -16,6 +21,7 @@ export function BuzolaProvider({ routes, children, middleware: Middleware, ...pr
16
21
  adapter: createBrowserNavigationAdapter(),
17
22
  persistentParams: props.persistentParams,
18
23
  pageRegistry: props.pageRegistry,
24
+ shouldIntercept: info => shouldInterceptRef.current?.(info) ?? true,
19
25
  });
20
26
  }
21
27
  const router = routerRef.current;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AAClG,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAA;AAChF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,OAAO,EAAE,YAAY,EAA0B,aAAa,EAAE,MAAM,cAAc,CAAA;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AA+BpC;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,KAAK,EAAuB;IACzG,MAAM,SAAS,GAAG,MAAM,CAAqB,KAAK,CAAC,MAAM,CAAC,CAAA;IAC1D,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QACxB,SAAS,CAAC,OAAO,GAAG,IAAI,MAAM,CAAC;YAC9B,MAAM,EAAE,MAAO;YACf,OAAO,EAAE,8BAA8B,EAAE;YACzC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;YACxC,YAAY,EAAE,KAAK,CAAC,YAAY;SAChC,CAAC,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;IAChC,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,EAAc,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IACjF,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAClE,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;IAEvE,gCAAgC;IAChC,eAAe,CAAC,GAAG,EAAE;QACpB,OAAO,MAAM,CAAC,KAAK,EAAE,CAAA;IACtB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,MAAM,iBAAiB,GAAG,OAAO,CAAoB,GAAG,EAAE,CAAC,CAAC;QAC3D,KAAK;QACL,KAAK,EAAE,CAAC;QACR,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,MAAM,EAAE,EAAE;KACV,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEZ,+CAA+C;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;QAC9B,IAAI,MAAM,GAA2B,EAAE,CAAA;QACvC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAA;QACxC,CAAC;QACD,OAAO,MAAM,CAAA;IACd,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IAEnB,MAAM,OAAO,GAAG,QAAQ,IAAI,KAAC,MAAM,KAAG,CAAA;IAEtC,OAAO,CACN,KAAC,aAAa,IAAC,KAAK,EAAE,MAAM,YAC3B,KAAC,YAAY,IAAC,KAAK,EAAE,iBAAiB,YACpC,UAAU;gBACV,CAAC,CAAC,KAAC,UAAU,IAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,YAAG,OAAO,GAAc;gBAC/E,CAAC,CAAC,OAAO,GACI,GACA,CAChB,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/react/provider.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buzola/router",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -610,7 +610,7 @@ describe('redirect()', () => {
610
610
  })
611
611
  .render(() => null)
612
612
 
613
- expect(typeof receivedRedirect).toBe('undefined') // not called yet — component not rendered
613
+ expect(typeof receivedRedirect).toBe('undefined') // not called yet: component not rendered
614
614
  // Verify the type is correct by checking the function signature
615
615
  expect(page.__buzolaPage).toBe(true)
616
616
  })
@@ -91,7 +91,7 @@ describe('LoaderCache', () => {
91
91
  cache.set('a', 1)
92
92
  cache.set('b', 2)
93
93
 
94
- // Update 'a' — should move to most recent
94
+ // Update 'a': should move to most recent
95
95
  cache.set('a', 10)
96
96
 
97
97
  // Now 'b' is the oldest
@@ -74,7 +74,7 @@ describe('PageLoaderState', () => {
74
74
  })
75
75
 
76
76
  describe('invalidation (cache key change)', () => {
77
- it('with stale data — returns stale data with isLoading and starts background fetch', () => {
77
+ it('with stale data: returns stale data with isLoading and starts background fetch', () => {
78
78
  const state = createState()
79
79
  resolveCtx(state, { cacheKey: 'k:0' })
80
80
  state.commitResult('stale-data')
@@ -93,12 +93,12 @@ describe('PageLoaderState', () => {
93
93
  expect(bgLoad).toBeDefined()
94
94
  })
95
95
 
96
- it('without stale data — returns suspend instruction', () => {
96
+ it('without stale data: returns suspend instruction', () => {
97
97
  const state = createState()
98
98
  const promise = Promise.resolve('data')
99
99
  const instruction = resolveCtx(state, { cacheKey: 'k:0', load: () => promise })
100
100
 
101
- // No commitResult called — no stale data
101
+ // No commitResult called: no stale data
102
102
  const second = resolveCtx(state, { cacheKey: 'k:1', load: () => Promise.resolve('new') })
103
103
  expect(second.action).toBe('suspend')
104
104
  })
@@ -149,7 +149,7 @@ describe('PageLoaderState', () => {
149
149
  onBackgroundSettled: settled1,
150
150
  })
151
151
 
152
- // Immediately invalidate again — supersedes the first background fetch
152
+ // Immediately invalidate again: supersedes the first background fetch
153
153
  state.commitBackgroundResult('stale') // commit so hasResolved stays true
154
154
  const settled2 = mock(() => {})
155
155
  resolveCtx(state, {
@@ -200,7 +200,7 @@ describe('PageLoaderState', () => {
200
200
  resolveCtx(state, { url: 'http://localhost/a', cacheKey: 'a:0', loaderCache: cache })
201
201
  state.commitResult('data-a')
202
202
 
203
- // Navigate to B — should save A's data to cache
203
+ // Navigate to B: should save A's data to cache
204
204
  resolveCtx(state, { url: 'http://localhost/b', cacheKey: 'b:0', loaderCache: cache })
205
205
 
206
206
  expect(cache.size).toBe(1)
@@ -218,7 +218,7 @@ describe('PageLoaderState', () => {
218
218
  resolveCtx(state, { url: 'http://localhost/b', cacheKey: 'b:0', loaderCache: cache })
219
219
  state.commitResult('data-b')
220
220
 
221
- // Navigate back to A — should restore from cache
221
+ // Navigate back to A: should restore from cache
222
222
  const instruction = resolveCtx(state, {
223
223
  url: 'http://localhost/a',
224
224
  cacheKey: 'a:0',
@@ -229,11 +229,11 @@ describe('PageLoaderState', () => {
229
229
  expect(instruction.action).toBe('render')
230
230
  if (instruction.action === 'render') {
231
231
  expect(instruction.data).toBe('data-a')
232
- expect(instruction.isLoading).toBe(true) // SWR — stale data + background reload
232
+ expect(instruction.isLoading).toBe(true) // SWR: stale data + background reload
233
233
  }
234
234
  })
235
235
 
236
- it('keeps data as stale when only the query changes — no suspend', () => {
236
+ it('keeps data as stale when only the query changes: no suspend', () => {
237
237
  const cache = new LoaderCache(10)
238
238
  const state = createState()
239
239
 
@@ -301,7 +301,7 @@ describe('PageLoaderState', () => {
301
301
  // Load A without committing (no stale data to cache)
302
302
  resolveCtx(state, { url: 'http://localhost/a', cacheKey: 'a:0', loaderCache: cache })
303
303
 
304
- // Navigate to B — no cache for B
304
+ // Navigate to B: no cache for B
305
305
  const instruction = resolveCtx(state, {
306
306
  url: 'http://localhost/b',
307
307
  cacheKey: 'b:0',
@@ -317,7 +317,7 @@ describe('PageLoaderState', () => {
317
317
  const cache = new LoaderCache(10)
318
318
  const state1 = createState()
319
319
 
320
- // First mount — load and dispose
320
+ // First mount: load and dispose
321
321
  resolveCtx(state1, { url: 'http://localhost/a', cacheKey: 'a:0', loaderCache: cache })
322
322
  state1.commitResult('cached-data')
323
323
  state1.dispose(cache) // saves to cache
@@ -386,13 +386,13 @@ describe('PageLoaderState', () => {
386
386
  })
387
387
 
388
388
  describe('no loader cache', () => {
389
- it('works without loaderCache — no stale caching', () => {
389
+ it('works without loaderCache: no stale caching', () => {
390
390
  const state = createState()
391
391
 
392
392
  resolveCtx(state, { url: 'http://localhost/a', cacheKey: 'a:0' })
393
393
  state.commitResult('data-a')
394
394
 
395
- // URL change without cache — no restore
395
+ // URL change without cache: no restore
396
396
  const instruction = resolveCtx(state, { url: 'http://localhost/b', cacheKey: 'b:0' })
397
397
  expect(instruction.action).toBe('suspend')
398
398
  })
@@ -39,7 +39,7 @@ describe('createBrowserNavigationAdapter', () => {
39
39
  /* The case actually seen in the wild: the getter returns the empty string on a
40
40
  document that is not fully active, which is what Safari handed us. `new
41
41
  URL('')` throws just as `new URL(null)` does, and it throws out of the
42
- `Router` constructor during render — a blank page, not a degraded route. An
42
+ `Router` constructor during render: a blank page, not a degraded route. An
43
43
  empty string is falsy but not nullish, so this is the case `??` would miss. */
44
44
  it('falls back to the document URL when the entry reports an empty URL', () => {
45
45
  const adapter = withNavigation({ url: '' })
@@ -50,7 +50,7 @@ describe('createBrowserNavigationAdapter', () => {
50
50
  /* `url` is also typed nullable: the getter returns null for entries whose
51
51
  document is not the current one and was fetched under a `no-referrer` or
52
52
  `origin` referrer policy. That branch needs `sameDocument` to be false, which
53
- `currentEntry` never is, so it should not be reachable through this call —
53
+ `currentEntry` never is, so it should not be reachable through this call,
54
54
  but the type permits it and the fallback costs nothing. */
55
55
  it('falls back to the document URL when the entry reports no URL', () => {
56
56
  const adapter = withNavigation({ url: null })
@@ -563,7 +563,7 @@ describe('Page loaders', () => {
563
563
  })
564
564
  await flushNav()
565
565
 
566
- // No Suspense fallback — the stale render stays up until the reload lands
566
+ // No Suspense fallback: the stale render stays up until the reload lands
567
567
  expect(container.textContent).toBe('loads:1')
568
568
 
569
569
  await act(async () => {
@@ -672,7 +672,7 @@ describe('Outlet', () => {
672
672
  {
673
673
  path: '/admin',
674
674
  isLayout: true,
675
- // No component — should be skipped
675
+ // No component: should be skipped
676
676
  children: [
677
677
  { path: '/dashboard', component: () => <div>Dashboard</div> },
678
678
  ],
@@ -952,7 +952,7 @@ describe('useBlocker', () => {
952
952
 
953
953
  expect(getByTestId('state').textContent).toBe('idle')
954
954
 
955
- // Try to navigate — should be blocked
955
+ // Try to navigate: should be blocked
956
956
  router.navigate('/about')
957
957
  await flushNav()
958
958
 
@@ -1123,7 +1123,7 @@ describe('ErrorBoundary', () => {
1123
1123
 
1124
1124
  expect(container.textContent).toContain('Route error: boom')
1125
1125
 
1126
- // Change resetKey and stop throwing — should reset
1126
+ // Change resetKey and stop throwing: should reset
1127
1127
  rerender(
1128
1128
  <ErrorBoundary resetKey="b">
1129
1129
  <MaybeThrow shouldThrow={false} />
@@ -1134,3 +1134,69 @@ describe('ErrorBoundary', () => {
1134
1134
  spy.mockRestore()
1135
1135
  })
1136
1136
  })
1137
+
1138
+ // ─── BuzolaProvider shouldIntercept ──────────────────────────────────────────
1139
+
1140
+ describe('BuzolaProvider shouldIntercept', () => {
1141
+ /* The provider builds its router on the browser adapter, so stand in for the slice of the
1142
+ Navigation API it uses and raise navigate events by hand. */
1143
+ interface FakeNavigateEvent {
1144
+ destination: { url: string }
1145
+ canIntercept: boolean
1146
+ navigationType: 'push'
1147
+ userInitiated: boolean
1148
+ intercept: () => void
1149
+ }
1150
+
1151
+ function withNavigation() {
1152
+ const listeners = new Set<(event: FakeNavigateEvent) => void>()
1153
+ Object.defineProperty(window, 'navigation', {
1154
+ value: {
1155
+ currentEntry: { url: 'http://localhost/', getState: () => undefined },
1156
+ addEventListener: (type: string, listener: (event: FakeNavigateEvent) => void) => listeners.add(listener),
1157
+ removeEventListener: (type: string, listener: (event: FakeNavigateEvent) => void) => listeners.delete(listener),
1158
+ },
1159
+ writable: true,
1160
+ configurable: true,
1161
+ })
1162
+ return function push(url: string) {
1163
+ const intercept = mock(() => {})
1164
+ for (const listener of listeners) {
1165
+ listener({ destination: { url }, canIntercept: true, navigationType: 'push', userInitiated: true, intercept })
1166
+ }
1167
+ return intercept
1168
+ }
1169
+ }
1170
+
1171
+ afterEach(() => {
1172
+ Reflect.deleteProperty(window, 'navigation')
1173
+ })
1174
+
1175
+ const routes = buildRouteTree([
1176
+ { path: '/', component: Home, isIndex: true },
1177
+ { path: '/about', component: About },
1178
+ ])
1179
+
1180
+ it('lets the browser take a navigation the prop declines', () => {
1181
+ const push = withNavigation()
1182
+ render(<BuzolaProvider routes={routes} shouldIntercept={() => false} />)
1183
+
1184
+ expect(push('http://localhost/about')).not.toHaveBeenCalled()
1185
+ })
1186
+
1187
+ it('consults the prop from the latest render', () => {
1188
+ const push = withNavigation()
1189
+ const { rerender } = render(<BuzolaProvider routes={routes} shouldIntercept={() => true} />)
1190
+
1191
+ rerender(<BuzolaProvider routes={routes} shouldIntercept={() => false} />)
1192
+
1193
+ expect(push('http://localhost/about')).not.toHaveBeenCalled()
1194
+ })
1195
+
1196
+ it('intercepts as before without the prop', () => {
1197
+ const push = withNavigation()
1198
+ render(<BuzolaProvider routes={routes} />)
1199
+
1200
+ expect(push('http://localhost/about')).toHaveBeenCalledTimes(1)
1201
+ })
1202
+ })