@buzola/router 0.0.18 → 0.0.20
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/define/create-page.js +1 -1
- package/dist/engine/loader-cache.d.ts +1 -1
- package/dist/engine/loader-cache.js +1 -1
- package/dist/engine/loader-state.d.ts +5 -5
- package/dist/engine/loader-state.d.ts.map +1 -1
- package/dist/engine/loader-state.js +8 -8
- package/dist/engine/loader-state.js.map +1 -1
- package/dist/engine/matcher.js +4 -4
- package/dist/engine/matcher.js.map +1 -1
- package/dist/engine/navigation-adapter.d.ts +3 -1
- package/dist/engine/navigation-adapter.d.ts.map +1 -1
- package/dist/engine/navigation-adapter.js +27 -2
- package/dist/engine/navigation-adapter.js.map +1 -1
- package/dist/engine/route-tree.js +2 -2
- package/dist/engine/route-tree.js.map +1 -1
- package/dist/engine/router.d.ts +7 -6
- package/dist/engine/router.d.ts.map +1 -1
- package/dist/engine/router.js +60 -26
- package/dist/engine/router.js.map +1 -1
- package/dist/engine/types.d.ts +15 -9
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/engine/utils.d.ts +3 -3
- package/dist/engine/utils.js +3 -3
- package/dist/react/hooks.d.ts +2 -2
- package/dist/react/hooks.js +1 -1
- package/dist/react/link.d.ts +4 -4
- package/dist/react/link.js +1 -1
- package/dist/react/outlet.js +2 -2
- package/dist/react/outlet.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/create-page.test.ts +1 -1
- package/src/__tests__/loader-cache.test.ts +1 -1
- package/src/__tests__/loader-state.test.ts +12 -12
- package/src/__tests__/navigation-adapter.test.ts +76 -3
- package/src/__tests__/react.test.tsx +4 -4
- package/src/__tests__/router.test.ts +293 -4
- package/src/__tests__/setup-dom.ts +1 -1
- package/src/__tests__/type-safety.test.tsx +22 -22
- package/src/define/create-page.tsx +1 -1
- package/src/engine/loader-cache.ts +1 -1
- package/src/engine/loader-state.ts +9 -9
- package/src/engine/matcher.ts +4 -4
- package/src/engine/navigation-adapter.ts +27 -2
- package/src/engine/route-tree.ts +3 -3
- package/src/engine/router.ts +68 -27
- package/src/engine/types.ts +15 -9
- package/src/engine/utils.ts +3 -3
- package/src/env.d.ts +8 -0
- package/src/react/hooks.ts +2 -2
- package/src/react/link.tsx +5 -5
- package/src/react/outlet.tsx +2 -2
|
@@ -75,7 +75,7 @@ function combineLoaders(loaders) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Follow a loader redirect, unless it points at the URL the page is already on
|
|
78
|
+
* Follow a loader redirect, unless it points at the URL the page is already on:
|
|
79
79
|
* that navigation re-runs the loader, which returns the same redirect, forever.
|
|
80
80
|
*/
|
|
81
81
|
function followRedirect(router, target) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Global LRU cache for page loader data.
|
|
3
3
|
* Shared across all page components to limit total memory usage.
|
|
4
|
-
* Uses Map insertion order for LRU eviction
|
|
4
|
+
* Uses Map insertion order for LRU eviction: oldest entries are evicted first.
|
|
5
5
|
*/
|
|
6
6
|
export declare class LoaderCache {
|
|
7
7
|
private cache;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Global LRU cache for page loader data.
|
|
3
3
|
* Shared across all page components to limit total memory usage.
|
|
4
|
-
* Uses Map insertion order for LRU eviction
|
|
4
|
+
* Uses Map insertion order for LRU eviction: oldest entries are evicted first.
|
|
5
5
|
*/
|
|
6
6
|
export class LoaderCache {
|
|
7
7
|
cache = new Map();
|
|
@@ -8,7 +8,7 @@ export type LoaderInstruction = {
|
|
|
8
8
|
promise: Promise<unknown>;
|
|
9
9
|
};
|
|
10
10
|
export interface LoaderResolveContext {
|
|
11
|
-
/** Current URL href
|
|
11
|
+
/** Current URL href: used for stale cache keying */
|
|
12
12
|
currentUrlHref: string;
|
|
13
13
|
/** Cache key that changes on URL change or invalidation */
|
|
14
14
|
cacheKey: string;
|
|
@@ -31,7 +31,7 @@ export interface LoaderResolveContext {
|
|
|
31
31
|
/**
|
|
32
32
|
* Manages loader data lifecycle outside of React's render cycle.
|
|
33
33
|
*
|
|
34
|
-
* This state survives React Suspense retries
|
|
34
|
+
* This state survives React Suspense retries. When use() suspends, React
|
|
35
35
|
* discards uncommitted hook state (useRef, useState, useMemo). Closure/instance
|
|
36
36
|
* state is preserved, preventing infinite suspend loops from promise recreation.
|
|
37
37
|
*
|
|
@@ -43,7 +43,7 @@ export declare class PageLoaderState {
|
|
|
43
43
|
private activeCacheKey;
|
|
44
44
|
private activePromise;
|
|
45
45
|
private activeResolvedData;
|
|
46
|
-
/** URL the currently held data was loaded for
|
|
46
|
+
/** URL the currently held data was loaded for: data is cached under this href, not the active one. */
|
|
47
47
|
private resolvedUrlHref;
|
|
48
48
|
private hasResolved;
|
|
49
49
|
private pendingBackgroundKey;
|
|
@@ -56,9 +56,9 @@ export declare class PageLoaderState {
|
|
|
56
56
|
resolve(ctx: LoaderResolveContext): LoaderInstruction;
|
|
57
57
|
/** Commit data after use() resolves (suspend case) */
|
|
58
58
|
commitResult(data: unknown): void;
|
|
59
|
-
/** Commit background SWR success
|
|
59
|
+
/** Commit background SWR success: update data and clear pending flag */
|
|
60
60
|
commitBackgroundResult(data: unknown): void;
|
|
61
|
-
/** Mark background load as failed
|
|
61
|
+
/** Mark background load as failed: next render will suspend with rejected promise */
|
|
62
62
|
commitBackgroundError(): void;
|
|
63
63
|
/** Save state to stale cache and reset (called on unmount) */
|
|
64
64
|
dispose(loaderCache: LoaderCache | undefined): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-state.d.ts","sourceRoot":"","sources":["../../src/engine/loader-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAKpD,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,oBAAoB;IACpC,
|
|
1
|
+
{"version":3,"file":"loader-state.d.ts","sourceRoot":"","sources":["../../src/engine/loader-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAKpD,MAAM,MAAM,iBAAiB,GAC1B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAA;AAEnD,MAAM,WAAW,oBAAoB;IACpC,oDAAoD;IACpD,cAAc,EAAE,MAAM,CAAA;IACtB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5B,0DAA0D;IAC1D,WAAW,EAAE,WAAW,GAAG,SAAS,CAAA;IACpC;;;;OAIG;IACH,mBAAmB,EAAE,CAAC,OAAO,EAAE;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG;QAAE,EAAE,EAAE,KAAK,CAAA;KAAE,KAAK,IAAI,CAAA;CACrF;AAMD;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,kBAAkB,CAAS;IACnC,sGAAsG;IACtG,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,oBAAoB,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAQ;;IAM3B;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,oBAAoB,GAAG,iBAAiB;IA8CrD,sDAAsD;IACtD,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAMjC,wEAAwE;IACxE,sBAAsB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAM3C,qFAAqF;IACrF,qBAAqB,IAAI,IAAI;IAK7B,8DAA8D;IAC9D,OAAO,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI;IAenD,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,gBAAgB;CAGxB"}
|
|
@@ -4,7 +4,7 @@ let nextId = 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* Manages loader data lifecycle outside of React's render cycle.
|
|
6
6
|
*
|
|
7
|
-
* This state survives React Suspense retries
|
|
7
|
+
* This state survives React Suspense retries. When use() suspends, React
|
|
8
8
|
* discards uncommitted hook state (useRef, useState, useMemo). Closure/instance
|
|
9
9
|
* state is preserved, preventing infinite suspend loops from promise recreation.
|
|
10
10
|
*
|
|
@@ -16,7 +16,7 @@ export class PageLoaderState {
|
|
|
16
16
|
activeCacheKey = null;
|
|
17
17
|
activePromise = null;
|
|
18
18
|
activeResolvedData;
|
|
19
|
-
/** URL the currently held data was loaded for
|
|
19
|
+
/** URL the currently held data was loaded for: data is cached under this href, not the active one. */
|
|
20
20
|
resolvedUrlHref = null;
|
|
21
21
|
hasResolved = false;
|
|
22
22
|
pendingBackgroundKey = null;
|
|
@@ -31,7 +31,7 @@ export class PageLoaderState {
|
|
|
31
31
|
resolve(ctx) {
|
|
32
32
|
const { currentUrlHref, cacheKey, load, loaderCache, onBackgroundSettled } = ctx;
|
|
33
33
|
this.handleUrlChange(currentUrlHref, loaderCache);
|
|
34
|
-
// ─── Same cache key
|
|
34
|
+
// ─── Same cache key: return current state ─────
|
|
35
35
|
if (this.activeCacheKey === cacheKey) {
|
|
36
36
|
if (this.pendingBackgroundKey === cacheKey) {
|
|
37
37
|
return { action: 'render', data: this.activeResolvedData, isLoading: true };
|
|
@@ -70,13 +70,13 @@ export class PageLoaderState {
|
|
|
70
70
|
this.resolvedUrlHref = this.activeUrlHref;
|
|
71
71
|
this.hasResolved = true;
|
|
72
72
|
}
|
|
73
|
-
/** Commit background SWR success
|
|
73
|
+
/** Commit background SWR success: update data and clear pending flag */
|
|
74
74
|
commitBackgroundResult(data) {
|
|
75
75
|
this.activeResolvedData = data;
|
|
76
76
|
this.resolvedUrlHref = this.activeUrlHref;
|
|
77
77
|
this.pendingBackgroundKey = null;
|
|
78
78
|
}
|
|
79
|
-
/** Mark background load as failed
|
|
79
|
+
/** Mark background load as failed: next render will suspend with rejected promise */
|
|
80
80
|
commitBackgroundError() {
|
|
81
81
|
this.hasResolved = false;
|
|
82
82
|
this.pendingBackgroundKey = null;
|
|
@@ -97,7 +97,7 @@ export class PageLoaderState {
|
|
|
97
97
|
// ─── Private ────────────────────────────────────────────────────────────
|
|
98
98
|
handleUrlChange(currentUrlHref, loaderCache) {
|
|
99
99
|
if (this.activeUrlHref !== null && this.activeUrlHref !== currentUrlHref) {
|
|
100
|
-
// URL changed
|
|
100
|
+
// URL changed: save the held data to stale cache under the href it was loaded for
|
|
101
101
|
if (loaderCache && this.hasResolved && this.activeResolvedData !== undefined && this.resolvedUrlHref) {
|
|
102
102
|
this.saveToStaleCache(loaderCache, this.resolvedUrlHref, this.activeResolvedData);
|
|
103
103
|
}
|
|
@@ -109,7 +109,7 @@ export class PageLoaderState {
|
|
|
109
109
|
this.hasResolved = true;
|
|
110
110
|
}
|
|
111
111
|
else if (!isSamePath(this.activeUrlHref, currentUrlHref)) {
|
|
112
|
-
// Different path
|
|
112
|
+
// Different path: the held data describes another page, so drop it and suspend
|
|
113
113
|
this.hasResolved = false;
|
|
114
114
|
this.activeResolvedData = undefined;
|
|
115
115
|
this.resolvedUrlHref = null;
|
|
@@ -119,7 +119,7 @@ export class PageLoaderState {
|
|
|
119
119
|
this.pendingBackgroundKey = null;
|
|
120
120
|
}
|
|
121
121
|
else if (this.activeUrlHref === null && loaderCache) {
|
|
122
|
-
// Remount
|
|
122
|
+
// Remount: try to restore from stale cache
|
|
123
123
|
const cached = this.restoreFromStaleCache(loaderCache, currentUrlHref);
|
|
124
124
|
if (cached.hit) {
|
|
125
125
|
this.activeResolvedData = cached.value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader-state.js","sourceRoot":"","sources":["../../src/engine/loader-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAyBvC,+EAA+E;AAE/E,IAAI,MAAM,GAAG,CAAC,CAAA;AAEd;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAe;IACnB,aAAa,GAAkB,IAAI,CAAA;IACnC,cAAc,GAAkB,IAAI,CAAA;IACpC,aAAa,GAA4B,IAAI,CAAA;IAC7C,kBAAkB,CAAS;IACnC,
|
|
1
|
+
{"version":3,"file":"loader-state.js","sourceRoot":"","sources":["../../src/engine/loader-state.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/matcher.js
CHANGED
|
@@ -11,7 +11,7 @@ export function matchRoutes(tree, url) {
|
|
|
11
11
|
return matchTrie(tree.root, segments, 0, [], pathname);
|
|
12
12
|
}
|
|
13
13
|
function matchTrie(node, segments, index, values, pathname) {
|
|
14
|
-
// All segments consumed
|
|
14
|
+
// All segments consumed: check if this trie node has a terminal route
|
|
15
15
|
if (index === segments.length) {
|
|
16
16
|
if (node.route) {
|
|
17
17
|
return buildMatchChain(node.route, values, pathname);
|
|
@@ -19,20 +19,20 @@ function matchTrie(node, segments, index, values, pathname) {
|
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
21
|
const segment = segments[index];
|
|
22
|
-
// 1. Try static child first
|
|
22
|
+
// 1. Try static child first: O(1) Map lookup, always most specific
|
|
23
23
|
const staticChild = node.staticChildren.get(segment);
|
|
24
24
|
if (staticChild) {
|
|
25
25
|
const result = matchTrie(staticChild, segments, index + 1, values, pathname);
|
|
26
26
|
if (result)
|
|
27
27
|
return result;
|
|
28
28
|
}
|
|
29
|
-
// 2. Try dynamic child
|
|
29
|
+
// 2. Try dynamic child: matches any single segment
|
|
30
30
|
if (node.dynamicChild) {
|
|
31
31
|
const result = matchTrie(node.dynamicChild, segments, index + 1, [...values, decodeURIComponent(segment)], pathname);
|
|
32
32
|
if (result)
|
|
33
33
|
return result;
|
|
34
34
|
}
|
|
35
|
-
// 3. Try catch-all child
|
|
35
|
+
// 3. Try catch-all child: consumes all remaining segments
|
|
36
36
|
if (node.catchAllChild) {
|
|
37
37
|
const remaining = segments.slice(index).map(s => decodeURIComponent(s)).join('/');
|
|
38
38
|
return buildMatchChain(node.catchAllChild, [...values, remaining], pathname);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../src/engine/matcher.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAe,EAAE,GAAQ;IACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACpD,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAA;AACvD,CAAC;AAED,SAAS,SAAS,CACjB,IAAc,EACd,QAAkB,EAClB,KAAa,EACb,MAAgB,EAChB,QAAgB;IAEhB,
|
|
1
|
+
{"version":3,"file":"matcher.js","sourceRoot":"","sources":["../../src/engine/matcher.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,IAAe,EAAE,GAAQ;IACpD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACpD,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAA;AACvD,CAAC;AAED,SAAS,SAAS,CACjB,IAAc,EACd,QAAkB,EAClB,KAAa,EACb,MAAgB,EAChB,QAAgB;IAEhB,sEAAsE;IACtE,IAAI,KAAK,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;QACrD,CAAC;QACD,OAAO,IAAI,CAAA;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE/B,mEAAmE;IACnE,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACpD,IAAI,WAAW,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC5E,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;IAC1B,CAAC;IAED,mDAAmD;IACnD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;QACpH,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;IAC1B,CAAC;IAED,0DAA0D;IAC1D,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjF,OAAO,eAAe,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC7E,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,KAAgB,EAAE,MAAgB,EAAE,QAAgB;IAC5E,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;IACF,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;AAC7D,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NavigationAdapter } from './types.js';
|
|
1
|
+
import type { BuzolaNavigateEvent, NavigationAdapter } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Create a NavigationAdapter that delegates to the browser's Navigation API.
|
|
4
4
|
*/
|
|
@@ -15,6 +15,8 @@ export interface MemoryNavigationAdapter extends NavigationAdapter {
|
|
|
15
15
|
leftApp(): readonly string[];
|
|
16
16
|
/** How many reloads went through to the browser, i.e. were not intercepted. */
|
|
17
17
|
reloadCount(): number;
|
|
18
|
+
/** How many navigations of each type the router intercepted. */
|
|
19
|
+
interceptCount(type: BuzolaNavigateEvent['navigationType']): number;
|
|
18
20
|
}
|
|
19
21
|
export declare function createMemoryNavigationAdapter(options?: MemoryNavigationAdapterOptions): MemoryNavigationAdapter;
|
|
20
22
|
//# sourceMappingURL=navigation-adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-adapter.d.ts","sourceRoot":"","sources":["../../src/engine/navigation-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"navigation-adapter.d.ts","sourceRoot":"","sources":["../../src/engine/navigation-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAIzF;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,iBAAiB,CAmGlE;AAID,MAAM,WAAW,8BAA8B;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAOD;;GAEG;AACH,6FAA6F;AAC7F,MAAM,WAAW,uBAAwB,SAAQ,iBAAiB;IACjE,2CAA2C;IAC3C,OAAO,IAAI,SAAS,MAAM,EAAE,CAAA;IAC5B,+EAA+E;IAC/E,WAAW,IAAI,MAAM,CAAA;IACrB,gEAAgE;IAChE,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAA;CACnE;AAED,wBAAgB,6BAA6B,CAC5C,OAAO,GAAE,8BAAmC,GAC1C,uBAAuB,CA6HzB"}
|
|
@@ -18,6 +18,21 @@ export function createBrowserNavigationAdapter() {
|
|
|
18
18
|
navigationType: event.navigationType,
|
|
19
19
|
userInitiated: event.userInitiated,
|
|
20
20
|
viewTransition,
|
|
21
|
+
whenCommitted(callback) {
|
|
22
|
+
// The next entry change a navigation makes is this one's commit, unless it was cancelled and another
|
|
23
|
+
// navigation got there first. The destination key tells them apart (it is set on traversals).
|
|
24
|
+
// updateCurrentEntry() also fires the event, with no navigation type, and commits nothing: code that
|
|
25
|
+
// saves the scroll position into the entry being left does exactly that while the traversal is pending.
|
|
26
|
+
const key = event.destination.key;
|
|
27
|
+
const onChange = (change) => {
|
|
28
|
+
if (change.navigationType === null)
|
|
29
|
+
return;
|
|
30
|
+
nav.removeEventListener('currententrychange', onChange);
|
|
31
|
+
if (nav.currentEntry?.key === key)
|
|
32
|
+
callback();
|
|
33
|
+
};
|
|
34
|
+
nav.addEventListener('currententrychange', onChange);
|
|
35
|
+
},
|
|
21
36
|
intercept(options) {
|
|
22
37
|
event.intercept({
|
|
23
38
|
handler: options.handler,
|
|
@@ -89,15 +104,20 @@ export function createMemoryNavigationAdapter(options = {}) {
|
|
|
89
104
|
const listeners = new Set();
|
|
90
105
|
const left = [];
|
|
91
106
|
let reloads = 0;
|
|
107
|
+
const intercepts = new Map();
|
|
92
108
|
function emitNavigateEvent(url, navigationType, commitNavigation, viewTransition) {
|
|
93
109
|
let intercepted = false;
|
|
94
110
|
let interceptHandler;
|
|
111
|
+
let onCommitted;
|
|
95
112
|
const event = {
|
|
96
113
|
destination: { url },
|
|
97
114
|
canIntercept: true,
|
|
98
115
|
navigationType,
|
|
99
116
|
userInitiated: false,
|
|
100
117
|
viewTransition,
|
|
118
|
+
whenCommitted(callback) {
|
|
119
|
+
onCommitted = callback;
|
|
120
|
+
},
|
|
101
121
|
intercept(options) {
|
|
102
122
|
intercepted = true;
|
|
103
123
|
interceptHandler = options.handler;
|
|
@@ -107,19 +127,21 @@ export function createMemoryNavigationAdapter(options = {}) {
|
|
|
107
127
|
listener(event);
|
|
108
128
|
}
|
|
109
129
|
if (intercepted && interceptHandler) {
|
|
130
|
+
intercepts.set(navigationType, (intercepts.get(navigationType) ?? 0) + 1);
|
|
110
131
|
// Like the browser, commit the destination entry before the handler runs. A handler that
|
|
111
132
|
// fails or reloads therefore sees the destination as the current entry.
|
|
112
133
|
commitNavigation(true);
|
|
113
134
|
void interceptHandler().then(() => { }, (error) => {
|
|
114
|
-
// Guard aborts are expected
|
|
135
|
+
// Guard aborts are expected: rethrow unexpected errors
|
|
115
136
|
if (error instanceof Error && error.name === 'NavigationAbortedError')
|
|
116
137
|
return;
|
|
117
138
|
throw error;
|
|
118
139
|
});
|
|
119
140
|
}
|
|
120
141
|
else {
|
|
121
|
-
// No interception
|
|
142
|
+
// No interception: commit immediately
|
|
122
143
|
commitNavigation(false);
|
|
144
|
+
onCommitted?.();
|
|
123
145
|
}
|
|
124
146
|
}
|
|
125
147
|
return {
|
|
@@ -185,6 +207,9 @@ export function createMemoryNavigationAdapter(options = {}) {
|
|
|
185
207
|
reloadCount() {
|
|
186
208
|
return reloads;
|
|
187
209
|
},
|
|
210
|
+
interceptCount(type) {
|
|
211
|
+
return intercepts.get(type) ?? 0;
|
|
212
|
+
},
|
|
188
213
|
};
|
|
189
214
|
}
|
|
190
215
|
//# sourceMappingURL=navigation-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation-adapter.js","sourceRoot":"","sources":["../../src/engine/navigation-adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"navigation-adapter.js","sourceRoot":"","sources":["../../src/engine/navigation-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,7 +84,7 @@ function insertIntoTrie(root, pattern, chain) {
|
|
|
84
84
|
for (let i = 0; i < segments.length; i++) {
|
|
85
85
|
const segment = segments[i];
|
|
86
86
|
if (segment.startsWith(':') && (segment.endsWith('+') || segment.endsWith('*'))) {
|
|
87
|
-
// Catch-all segment
|
|
87
|
+
// Catch-all segment: consumes all remaining segments
|
|
88
88
|
paramNames.push(segment.slice(1, -1));
|
|
89
89
|
node.catchAllChild = { chain, paramNames };
|
|
90
90
|
return;
|
|
@@ -106,7 +106,7 @@ function insertIntoTrie(root, pattern, chain) {
|
|
|
106
106
|
node = child;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
// Terminal
|
|
109
|
+
// Terminal: route matches at this trie node
|
|
110
110
|
node.route = { chain, paramNames };
|
|
111
111
|
}
|
|
112
112
|
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-tree.js","sourceRoot":"","sources":["../../src/engine/route-tree.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"route-tree.js","sourceRoot":"","sources":["../../src/engine/route-tree.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/router.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface RouterOptions {
|
|
|
39
39
|
loaderCacheSize?: number;
|
|
40
40
|
/**
|
|
41
41
|
* Decides, per navigation, whether the router handles it in the current document.
|
|
42
|
-
* Return `false` to have the browser load the destination as a new document instead
|
|
42
|
+
* Return `false` to have the browser load the destination as a new document instead,
|
|
43
43
|
* e.g. to pick up a newly deployed build on the next in-app navigation.
|
|
44
44
|
*
|
|
45
45
|
* Offered every push, replace and traverse the router would otherwise intercept, except
|
|
@@ -94,6 +94,7 @@ export declare class Router {
|
|
|
94
94
|
* Call this once when the router is initialized.
|
|
95
95
|
*/
|
|
96
96
|
start(): () => void;
|
|
97
|
+
private commitLocation;
|
|
97
98
|
/**
|
|
98
99
|
* A reload asks for a fresh document (e.g. to recover from stale chunks after a deploy), so it goes to
|
|
99
100
|
* the browser. Re-rendering the current route from the JavaScript already loaded would defeat it.
|
|
@@ -112,13 +113,13 @@ export declare class Router {
|
|
|
112
113
|
*/
|
|
113
114
|
private handleDeclined;
|
|
114
115
|
/**
|
|
115
|
-
* Hold the navigation while the blockers run and, if they allow it, reload the current entry
|
|
116
|
+
* Hold the navigation while the blockers run and, if they allow it, reload the current entry,
|
|
116
117
|
* which is already the navigation's destination, because an intercepted navigation commits before
|
|
117
118
|
* its handler runs.
|
|
118
119
|
*/
|
|
119
120
|
private reloadAfterBlockers;
|
|
120
121
|
/**
|
|
121
|
-
* Hand one navigation to the browser instead of intercepting it, for a URL the SERVER owns
|
|
122
|
+
* Hand one navigation to the browser instead of intercepting it, for a URL the SERVER owns:
|
|
122
123
|
* an auth handoff, a file download, a server-rendered page that happens to share this origin.
|
|
123
124
|
*
|
|
124
125
|
* The Navigation API offers no way for a caller to mark a navigation un-interceptable:
|
|
@@ -128,12 +129,12 @@ export declare class Router {
|
|
|
128
129
|
*
|
|
129
130
|
* The release is recorded BEFORE the navigation is requested and is keyed to the resolved URL, so
|
|
130
131
|
* it cannot race the event or release some other navigation. Unlike `navigate`, the URL is passed
|
|
131
|
-
* to the browser as given
|
|
132
|
+
* to the browser as given: no base path is prepended, because the target is outside the app.
|
|
132
133
|
*/
|
|
133
134
|
leaveApp(url: string): void;
|
|
134
135
|
/**
|
|
135
136
|
* Navigate programmatically.
|
|
136
|
-
* The `to` path should not include the base path
|
|
137
|
+
* The `to` path should not include the base path. It is prepended automatically.
|
|
137
138
|
*/
|
|
138
139
|
navigate(to: string, options?: NavigateOptions): void;
|
|
139
140
|
/**
|
|
@@ -200,7 +201,7 @@ export declare class Router {
|
|
|
200
201
|
*/
|
|
201
202
|
addBlocker(fn: BlockerFn): () => void;
|
|
202
203
|
/**
|
|
203
|
-
* Dispose the router
|
|
204
|
+
* Dispose the router: clear all subscribers and reset state.
|
|
204
205
|
*/
|
|
205
206
|
dispose(): void;
|
|
206
207
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/engine/router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAuB,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAG/I;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;AAE3D,MAAM,WAAW,aAAa;IAC7B,iCAAiC;IACjC,MAAM,EAAE,SAAS,CAAA;IACjB,8CAA8C;IAC9C,OAAO,EAAE,iBAAiB,CAAA;IAC1B,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,iBAAiB,CAAA;CACnC;AAED;;;GAGG;AACH,qBAAa,MAAM;IAClB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAA8B;IAClE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAwB;IACrD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA+B;IAC/D,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,qBAAqB,CAAoD;IACjF,OAAO,CAAC,iBAAiB,CAA2C;IACpE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;gBAE1C,OAAO,EAAE,aAAa;IA2BlC;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;OAGG;IACH,IAAI,WAAW,IAAI,WAAW,GAAG,SAAS,CAEzC;IAED;;OAEG;IACH,QAAQ,IAAI,WAAW;IAIvB;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,gBAAgB,GAAG,MAAM,IAAI;IAOnD;;;OAGG;IACH,KAAK,IAAI,MAAM,IAAI;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/engine/router.ts"],"names":[],"mappings":"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"}
|
package/dist/engine/router.js
CHANGED
|
@@ -90,7 +90,7 @@ export class Router {
|
|
|
90
90
|
*/
|
|
91
91
|
start() {
|
|
92
92
|
const handler = (event) => {
|
|
93
|
-
// Consume the pending options before any early return
|
|
93
|
+
// Consume the pending options before any early return: they belong to the
|
|
94
94
|
// navigation that armed them and must not leak into the next one.
|
|
95
95
|
const scrollBehavior = this.pendingScrollBehavior;
|
|
96
96
|
const explicitFocusReset = this.pendingFocusReset;
|
|
@@ -132,14 +132,35 @@ export class Router {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
const currentNavId = ++this.navigationId;
|
|
135
|
-
const useViewTransition = event.viewTransition || this.viewTransitions
|
|
136
|
-
|
|
135
|
+
const useViewTransition = (event.viewTransition || this.viewTransitions) && typeof document !== 'undefined'
|
|
136
|
+
&& 'startViewTransition' in document;
|
|
137
|
+
// A traversal nobody needs to hold is left to the browser. Safari restores scroll for an intercepted
|
|
138
|
+
// traversal in a later task, and skips the restore if a wheel event reached the page in between. A trackpad
|
|
139
|
+
// back swipe always delivers some, and React always has a wheel listener, so the page comes back unscrolled
|
|
140
|
+
// and the swipe snapshot hangs for its 3 s timeout. Not intercepted, the traversal takes the browser's
|
|
141
|
+
// classic path, which switches the entry and restores scroll in one task. Rendering at the switch keeps the
|
|
142
|
+
// screen in step with the URL (an effect that replaces the entry must not hit the one being left) while
|
|
143
|
+
// the page is still in place before the restore.
|
|
144
|
+
if (event.navigationType === 'traverse' && this.blockers.size === 0 && !useViewTransition && event.whenCommitted) {
|
|
145
|
+
event.whenCommitted(() => {
|
|
146
|
+
if (this.navigationId !== currentNavId)
|
|
147
|
+
return;
|
|
148
|
+
this.commitLocation(url, matches, this.adapter.getState(), event.navigationType);
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Query-only navigations stay on the same page, so keep focus where the user left it
|
|
137
153
|
// (search boxes, filters, pagination). Path changes keep the browser's focus reset,
|
|
138
154
|
// and so do fragment changes, which must move focus to the targeted section.
|
|
139
155
|
const focusReset = explicitFocusReset
|
|
140
156
|
?? (isSamePath(this.state.location, url) && this.state.location.hash === url.hash ? 'manual' : 'after-transition');
|
|
157
|
+
// Safari 26.5 scrolls an intercepted push or replace to the top only in the web process. The page reports
|
|
158
|
+
// scrollY 0 while the screen stays where it was (a sticky header is gone) until the next scroll, which
|
|
159
|
+
// jumps from the old position (WebKit bug 309542, fixed in 308976@main). window.scrollTo reaches the
|
|
160
|
+
// screen, so the router scrolls to the top itself. A fragment and a traversal stay with the browser.
|
|
161
|
+
const scrollToTop = scrollBehavior === 'after-transition' && event.navigationType !== 'traverse' && url.hash === '';
|
|
141
162
|
event.intercept({
|
|
142
|
-
scroll: scrollBehavior,
|
|
163
|
+
scroll: scrollToTop ? 'manual' : scrollBehavior,
|
|
143
164
|
focusReset,
|
|
144
165
|
handler: async () => {
|
|
145
166
|
// Check blockers before setting pending state
|
|
@@ -157,27 +178,22 @@ export class Router {
|
|
|
157
178
|
isPending: true,
|
|
158
179
|
pendingLocation: url,
|
|
159
180
|
});
|
|
160
|
-
// A newer navigation has started
|
|
181
|
+
// A newer navigation has started, so abandon this one
|
|
161
182
|
if (this.navigationId !== currentNavId)
|
|
162
183
|
return;
|
|
163
|
-
// Perform the DOM update
|
|
184
|
+
// Perform the DOM update. A view transition runs it later, by when a newer navigation may have
|
|
185
|
+
// committed its own state, so check again.
|
|
164
186
|
const doUpdate = () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
173
|
-
// Going to the URL we are already on is still a navigation — a browser
|
|
174
|
-
// re-requests the document for it. Loader data is keyed by href, so it
|
|
175
|
-
// would silently keep serving stale data without an explicit invalidation.
|
|
176
|
-
if (previousHref === url.href) {
|
|
177
|
-
this.invalidateAll();
|
|
187
|
+
if (this.navigationId !== currentNavId)
|
|
188
|
+
return;
|
|
189
|
+
this.commitLocation(url, matches, this.adapter.getState(), event.navigationType);
|
|
190
|
+
// Instant even where the page sets scroll-behavior: smooth, so the jump does not animate. Safari's
|
|
191
|
+
// own reset is instant as well (Chromium's follows the CSS).
|
|
192
|
+
if (scrollToTop && typeof window !== 'undefined') {
|
|
193
|
+
window.scrollTo({ top: 0, left: 0, behavior: 'instant' });
|
|
178
194
|
}
|
|
179
195
|
};
|
|
180
|
-
if (useViewTransition
|
|
196
|
+
if (useViewTransition) {
|
|
181
197
|
;
|
|
182
198
|
document.startViewTransition(doUpdate);
|
|
183
199
|
}
|
|
@@ -194,6 +210,24 @@ export class Router {
|
|
|
194
210
|
this.stopFn = stop;
|
|
195
211
|
return stop;
|
|
196
212
|
}
|
|
213
|
+
commitLocation(url, matches, navigationState, navigationType) {
|
|
214
|
+
const previousHref = this.state.location.href;
|
|
215
|
+
this.setState({
|
|
216
|
+
location: url,
|
|
217
|
+
matches,
|
|
218
|
+
isPending: false,
|
|
219
|
+
pendingLocation: undefined,
|
|
220
|
+
navigationState,
|
|
221
|
+
});
|
|
222
|
+
// Going to the URL we are already on is still a navigation: a browser
|
|
223
|
+
// re-requests the document for it. Loader data is keyed by href, so it
|
|
224
|
+
// would silently keep serving stale data without an explicit invalidation.
|
|
225
|
+
// A traversal re-requests nothing, and reloading would shorten the page before
|
|
226
|
+
// the browser restores its scroll position.
|
|
227
|
+
if (previousHref === url.href && navigationType !== 'traverse') {
|
|
228
|
+
this.invalidateAll();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
197
231
|
/**
|
|
198
232
|
* A reload asks for a fresh document (e.g. to recover from stale chunks after a deploy), so it goes to
|
|
199
233
|
* the browser. Re-rendering the current route from the JavaScript already loaded would defeat it.
|
|
@@ -220,7 +254,7 @@ export class Router {
|
|
|
220
254
|
this.reloadAfterBlockers(event);
|
|
221
255
|
}
|
|
222
256
|
/**
|
|
223
|
-
* Hold the navigation while the blockers run and, if they allow it, reload the current entry
|
|
257
|
+
* Hold the navigation while the blockers run and, if they allow it, reload the current entry,
|
|
224
258
|
* which is already the navigation's destination, because an intercepted navigation commits before
|
|
225
259
|
* its handler runs.
|
|
226
260
|
*/
|
|
@@ -246,7 +280,7 @@ export class Router {
|
|
|
246
280
|
});
|
|
247
281
|
}
|
|
248
282
|
/**
|
|
249
|
-
* Hand one navigation to the browser instead of intercepting it, for a URL the SERVER owns
|
|
283
|
+
* Hand one navigation to the browser instead of intercepting it, for a URL the SERVER owns:
|
|
250
284
|
* an auth handoff, a file download, a server-rendered page that happens to share this origin.
|
|
251
285
|
*
|
|
252
286
|
* The Navigation API offers no way for a caller to mark a navigation un-interceptable:
|
|
@@ -256,7 +290,7 @@ export class Router {
|
|
|
256
290
|
*
|
|
257
291
|
* The release is recorded BEFORE the navigation is requested and is keyed to the resolved URL, so
|
|
258
292
|
* it cannot race the event or release some other navigation. Unlike `navigate`, the URL is passed
|
|
259
|
-
* to the browser as given
|
|
293
|
+
* to the browser as given: no base path is prepended, because the target is outside the app.
|
|
260
294
|
*/
|
|
261
295
|
leaveApp(url) {
|
|
262
296
|
this.releasedURL = new URL(url, this.adapter.getCurrentURL()).href;
|
|
@@ -264,7 +298,7 @@ export class Router {
|
|
|
264
298
|
}
|
|
265
299
|
/**
|
|
266
300
|
* Navigate programmatically.
|
|
267
|
-
* The `to` path should not include the base path
|
|
301
|
+
* The `to` path should not include the base path. It is prepended automatically.
|
|
268
302
|
*/
|
|
269
303
|
navigate(to, options) {
|
|
270
304
|
if (options?.resetScroll === false) {
|
|
@@ -340,7 +374,7 @@ export class Router {
|
|
|
340
374
|
}
|
|
341
375
|
else {
|
|
342
376
|
if (isCatchAll) {
|
|
343
|
-
// Catch-all values may contain slashes
|
|
377
|
+
// Catch-all values may contain slashes: insert raw
|
|
344
378
|
result.push(value);
|
|
345
379
|
}
|
|
346
380
|
else {
|
|
@@ -453,7 +487,7 @@ export class Router {
|
|
|
453
487
|
};
|
|
454
488
|
}
|
|
455
489
|
/**
|
|
456
|
-
* Dispose the router
|
|
490
|
+
* Dispose the router: clear all subscribers and reset state.
|
|
457
491
|
*/
|
|
458
492
|
dispose() {
|
|
459
493
|
this.stopFn?.();
|