@tanstack/router-core 1.167.4 → 1.168.0
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/cjs/index.cjs +3 -0
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/load-matches.cjs +14 -9
- package/dist/cjs/load-matches.cjs.map +1 -1
- package/dist/cjs/router.cjs +135 -151
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +16 -10
- package/dist/cjs/scroll-restoration.cjs +5 -4
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/ssr/createRequestHandler.cjs +2 -2
- package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.cjs +14 -17
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.cjs +1 -1
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/stores.cjs +148 -0
- package/dist/cjs/stores.cjs.map +1 -0
- package/dist/cjs/stores.d.cts +70 -0
- package/dist/cjs/utils.cjs +7 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/load-matches.js +14 -9
- package/dist/esm/load-matches.js.map +1 -1
- package/dist/esm/router.d.ts +16 -10
- package/dist/esm/router.js +135 -151
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/scroll-restoration.js +5 -4
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/ssr/createRequestHandler.js +2 -2
- package/dist/esm/ssr/createRequestHandler.js.map +1 -1
- package/dist/esm/ssr/ssr-client.js +14 -17
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.js +1 -1
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/stores.d.ts +70 -0
- package/dist/esm/stores.js +146 -0
- package/dist/esm/stores.js.map +1 -0
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +7 -1
- package/dist/esm/utils.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +11 -0
- package/src/load-matches.ts +23 -11
- package/src/router.ts +238 -252
- package/src/scroll-restoration.ts +6 -5
- package/src/ssr/createRequestHandler.ts +5 -4
- package/src/ssr/ssr-client.ts +17 -18
- package/src/ssr/ssr-server.ts +1 -1
- package/src/stores.ts +342 -0
- package/src/utils.ts +9 -0
- package/dist/cjs/utils/batch.cjs +0 -16
- package/dist/cjs/utils/batch.cjs.map +0 -1
- package/dist/cjs/utils/batch.d.cts +0 -1
- package/dist/esm/utils/batch.d.ts +0 -1
- package/dist/esm/utils/batch.js +0 -15
- package/dist/esm/utils/batch.js.map +0 -1
- package/src/utils/batch.ts +0 -18
package/dist/esm/router.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { batch as batch$1 } from "./utils/batch.js";
|
|
2
1
|
import { DEFAULT_PROTOCOL_ALLOWLIST, createControlledPromise, decodePath, deepEqual, encodePathLikeUrl, findLast, functionalUpdate, isDangerousProtocol, last, nullReplaceEqualDeep, replaceEqualDeep } from "./utils.js";
|
|
3
2
|
import { createLRUCache } from "./lru-cache.js";
|
|
4
3
|
import { findFlatMatch, findRouteMatch, findSingleMatch, processRouteMasks, processRouteTree } from "./new-process-route-tree.js";
|
|
@@ -10,7 +9,7 @@ import { rootRouteId } from "./root.js";
|
|
|
10
9
|
import { isRedirect, redirect } from "./redirect.js";
|
|
11
10
|
import { loadMatches, loadRouteChunk, routeNeedsPreload } from "./load-matches.js";
|
|
12
11
|
import { composeRewrites, executeRewriteInput, executeRewriteOutput, rewriteBasepath } from "./rewrite.js";
|
|
13
|
-
import {
|
|
12
|
+
import { createRouterStores } from "./stores.js";
|
|
14
13
|
import { createBrowserHistory, parseHref } from "@tanstack/history";
|
|
15
14
|
import { isServer } from "@tanstack/router-core/isServer";
|
|
16
15
|
//#region src/router.ts
|
|
@@ -37,11 +36,11 @@ var trailingSlashOptions = {
|
|
|
37
36
|
};
|
|
38
37
|
/**
|
|
39
38
|
* Compute whether path, href or hash changed between previous and current
|
|
40
|
-
* resolved locations
|
|
39
|
+
* resolved locations.
|
|
41
40
|
*/
|
|
42
|
-
function getLocationChangeInfo(
|
|
43
|
-
const fromLocation =
|
|
44
|
-
const toLocation =
|
|
41
|
+
function getLocationChangeInfo(location, resolvedLocation) {
|
|
42
|
+
const fromLocation = resolvedLocation;
|
|
43
|
+
const toLocation = location;
|
|
45
44
|
return {
|
|
46
45
|
fromLocation,
|
|
47
46
|
toLocation,
|
|
@@ -50,24 +49,20 @@ function getLocationChangeInfo(routerState) {
|
|
|
50
49
|
hashChanged: fromLocation?.hash !== toLocation.hash
|
|
51
50
|
};
|
|
52
51
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
return store;
|
|
65
|
-
}
|
|
52
|
+
/**
|
|
53
|
+
* Core, framework-agnostic router engine that powers TanStack Router.
|
|
54
|
+
*
|
|
55
|
+
* Provides navigation, matching, loading, preloading, caching and event APIs
|
|
56
|
+
* used by framework adapters (React/Solid). Prefer framework helpers like
|
|
57
|
+
* `createRouter` in app code.
|
|
58
|
+
*
|
|
59
|
+
* @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType
|
|
60
|
+
*/
|
|
66
61
|
var RouterCore = class {
|
|
67
62
|
/**
|
|
68
63
|
* @deprecated Use the `createRouter` function instead
|
|
69
64
|
*/
|
|
70
|
-
constructor(options) {
|
|
65
|
+
constructor(options, getStoreConfig) {
|
|
71
66
|
this.tempLocationKey = `${Math.round(Math.random() * 1e7)}`;
|
|
72
67
|
this.resetNextScroll = true;
|
|
73
68
|
this.shouldViewTransition = void 0;
|
|
@@ -116,10 +111,11 @@ var RouterCore = class {
|
|
|
116
111
|
}
|
|
117
112
|
this.setRoutes(processRouteTreeResult);
|
|
118
113
|
}
|
|
119
|
-
if (!this.
|
|
120
|
-
|
|
121
|
-
this.
|
|
122
|
-
|
|
114
|
+
if (!this.stores && this.latestLocation) {
|
|
115
|
+
const config = this.getStoreConfig(this);
|
|
116
|
+
this.batch = config.batch;
|
|
117
|
+
this.stores = createRouterStores(getInitialRouterState(this.latestLocation), config);
|
|
118
|
+
if (!(isServer ?? this.isServer)) setupScrollRestoration(this);
|
|
123
119
|
}
|
|
124
120
|
let needsLocationUpdate = false;
|
|
125
121
|
const nextBasepath = this.options.basepath ?? "/";
|
|
@@ -134,10 +130,7 @@ var RouterCore = class {
|
|
|
134
130
|
if (this.history) this.updateLatestLocation();
|
|
135
131
|
needsLocationUpdate = true;
|
|
136
132
|
}
|
|
137
|
-
if (needsLocationUpdate && this.
|
|
138
|
-
...s,
|
|
139
|
-
location: this.latestLocation
|
|
140
|
-
}));
|
|
133
|
+
if (needsLocationUpdate && this.stores) this.stores.location.setState(() => this.latestLocation);
|
|
141
134
|
if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a)");
|
|
142
135
|
};
|
|
143
136
|
this.updateLatestLocation = () => {
|
|
@@ -241,14 +234,14 @@ var RouterCore = class {
|
|
|
241
234
|
match._nonReactive.pendingTimeout = void 0;
|
|
242
235
|
};
|
|
243
236
|
this.cancelMatches = () => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.cancelMatch(
|
|
237
|
+
this.stores.pendingMatchesId.state.forEach((matchId) => {
|
|
238
|
+
this.cancelMatch(matchId);
|
|
239
|
+
});
|
|
240
|
+
this.stores.matchesId.state.forEach((matchId) => {
|
|
241
|
+
if (this.stores.pendingMatchStoresById.has(matchId)) return;
|
|
242
|
+
const match = this.stores.activeMatchStoresById.get(matchId)?.state;
|
|
243
|
+
if (!match) return;
|
|
244
|
+
if (match.status === "pending" || match.isFetching === "loader") this.cancelMatch(matchId);
|
|
252
245
|
});
|
|
253
246
|
};
|
|
254
247
|
this.buildLocation = (opts) => {
|
|
@@ -514,83 +507,85 @@ var RouterCore = class {
|
|
|
514
507
|
}
|
|
515
508
|
}
|
|
516
509
|
const pendingMatches = this.matchRoutes(this.latestLocation);
|
|
517
|
-
this.
|
|
518
|
-
|
|
519
|
-
status
|
|
520
|
-
statusCode
|
|
521
|
-
isLoading
|
|
522
|
-
location
|
|
523
|
-
pendingMatches
|
|
524
|
-
|
|
525
|
-
})
|
|
510
|
+
const nextCachedMatches = this.stores.cachedMatchesSnapshot.state.filter((d) => !pendingMatches.some((e) => e.id === d.id));
|
|
511
|
+
this.batch(() => {
|
|
512
|
+
this.stores.status.setState(() => "pending");
|
|
513
|
+
this.stores.statusCode.setState(() => 200);
|
|
514
|
+
this.stores.isLoading.setState(() => true);
|
|
515
|
+
this.stores.location.setState(() => this.latestLocation);
|
|
516
|
+
this.stores.setPendingMatches(pendingMatches);
|
|
517
|
+
this.stores.setCachedMatches(nextCachedMatches);
|
|
518
|
+
});
|
|
526
519
|
};
|
|
527
520
|
this.load = async (opts) => {
|
|
528
521
|
let redirect;
|
|
529
522
|
let notFound;
|
|
530
523
|
let loadPromise;
|
|
531
|
-
const previousLocation = this.
|
|
524
|
+
const previousLocation = this.stores.resolvedLocation.state ?? this.stores.location.state;
|
|
532
525
|
loadPromise = new Promise((resolve) => {
|
|
533
526
|
this.startTransition(async () => {
|
|
534
527
|
try {
|
|
535
528
|
this.beforeLoad();
|
|
536
529
|
const next = this.latestLocation;
|
|
537
|
-
const prevLocation = this.
|
|
538
|
-
|
|
530
|
+
const prevLocation = this.stores.resolvedLocation.state;
|
|
531
|
+
const locationChangeInfo = getLocationChangeInfo(next, prevLocation);
|
|
532
|
+
if (!this.stores.redirect.state) this.emit({
|
|
539
533
|
type: "onBeforeNavigate",
|
|
540
|
-
...
|
|
541
|
-
resolvedLocation: prevLocation,
|
|
542
|
-
location: next
|
|
543
|
-
})
|
|
534
|
+
...locationChangeInfo
|
|
544
535
|
});
|
|
545
536
|
this.emit({
|
|
546
537
|
type: "onBeforeLoad",
|
|
547
|
-
...
|
|
548
|
-
resolvedLocation: prevLocation,
|
|
549
|
-
location: next
|
|
550
|
-
})
|
|
538
|
+
...locationChangeInfo
|
|
551
539
|
});
|
|
552
540
|
await loadMatches({
|
|
553
541
|
router: this,
|
|
554
542
|
sync: opts?.sync,
|
|
555
543
|
forceStaleReload: previousLocation.href === next.href,
|
|
556
|
-
matches: this.state
|
|
544
|
+
matches: this.stores.pendingMatchesSnapshot.state,
|
|
557
545
|
location: next,
|
|
558
546
|
updateMatch: this.updateMatch,
|
|
559
547
|
onReady: async () => {
|
|
560
548
|
this.startTransition(() => {
|
|
561
549
|
this.startViewTransition(async () => {
|
|
562
|
-
let exitingMatches =
|
|
563
|
-
let hookExitingMatches =
|
|
564
|
-
let hookEnteringMatches =
|
|
565
|
-
let hookStayingMatches =
|
|
566
|
-
batch
|
|
567
|
-
this.
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
550
|
+
let exitingMatches = null;
|
|
551
|
+
let hookExitingMatches = null;
|
|
552
|
+
let hookEnteringMatches = null;
|
|
553
|
+
let hookStayingMatches = null;
|
|
554
|
+
this.batch(() => {
|
|
555
|
+
const pendingMatches = this.stores.pendingMatchesSnapshot.state;
|
|
556
|
+
const mountPending = pendingMatches.length;
|
|
557
|
+
const currentMatches = this.stores.activeMatchesSnapshot.state;
|
|
558
|
+
exitingMatches = mountPending ? currentMatches.filter((match) => !this.stores.pendingMatchStoresById.has(match.id)) : null;
|
|
559
|
+
const pendingRouteIds = /* @__PURE__ */ new Set();
|
|
560
|
+
for (const s of this.stores.pendingMatchStoresById.values()) if (s.routeId) pendingRouteIds.add(s.routeId);
|
|
561
|
+
const activeRouteIds = /* @__PURE__ */ new Set();
|
|
562
|
+
for (const s of this.stores.activeMatchStoresById.values()) if (s.routeId) activeRouteIds.add(s.routeId);
|
|
563
|
+
hookExitingMatches = mountPending ? currentMatches.filter((match) => !pendingRouteIds.has(match.routeId)) : null;
|
|
564
|
+
hookEnteringMatches = mountPending ? pendingMatches.filter((match) => !activeRouteIds.has(match.routeId)) : null;
|
|
565
|
+
hookStayingMatches = mountPending ? pendingMatches.filter((match) => activeRouteIds.has(match.routeId)) : currentMatches;
|
|
566
|
+
this.stores.isLoading.setState(() => false);
|
|
567
|
+
this.stores.loadedAt.setState(() => Date.now());
|
|
568
|
+
/**
|
|
569
|
+
* When committing new matches, cache any exiting matches that are still usable.
|
|
570
|
+
* Routes that resolved with `status: 'error'` or `status: 'notFound'` are
|
|
571
|
+
* deliberately excluded from `cachedMatches` so that subsequent invalidations
|
|
572
|
+
* or reloads re-run their loaders instead of reusing the failed/not-found data.
|
|
573
|
+
*/
|
|
574
|
+
if (mountPending) {
|
|
575
|
+
this.stores.setActiveMatches(pendingMatches);
|
|
576
|
+
this.stores.setPendingMatches([]);
|
|
577
|
+
this.stores.setCachedMatches([...this.stores.cachedMatchesSnapshot.state, ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]);
|
|
578
|
+
this.clearExpiredCache();
|
|
579
|
+
}
|
|
584
580
|
});
|
|
585
|
-
[
|
|
581
|
+
for (const [matches, hook] of [
|
|
586
582
|
[hookExitingMatches, "onLeave"],
|
|
587
583
|
[hookEnteringMatches, "onEnter"],
|
|
588
584
|
[hookStayingMatches, "onStay"]
|
|
589
|
-
]
|
|
590
|
-
matches
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
});
|
|
585
|
+
]) {
|
|
586
|
+
if (!matches) continue;
|
|
587
|
+
for (const match of matches) this.looseRoutesById[match.routeId].options[hook]?.(match);
|
|
588
|
+
}
|
|
594
589
|
});
|
|
595
590
|
});
|
|
596
591
|
}
|
|
@@ -604,11 +599,11 @@ var RouterCore = class {
|
|
|
604
599
|
ignoreBlocker: true
|
|
605
600
|
});
|
|
606
601
|
} else if (isNotFound(err)) notFound = err;
|
|
607
|
-
this.
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
redirect
|
|
611
|
-
})
|
|
602
|
+
const nextStatusCode = redirect ? redirect.status : notFound ? 404 : this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error") ? 500 : 200;
|
|
603
|
+
this.batch(() => {
|
|
604
|
+
this.stores.statusCode.setState(() => nextStatusCode);
|
|
605
|
+
this.stores.redirect.setState(() => redirect);
|
|
606
|
+
});
|
|
612
607
|
}
|
|
613
608
|
if (this.latestLoadPromise === loadPromise) {
|
|
614
609
|
this.commitLocationPromise?.resolve();
|
|
@@ -623,11 +618,8 @@ var RouterCore = class {
|
|
|
623
618
|
while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) await this.latestLoadPromise;
|
|
624
619
|
let newStatusCode = void 0;
|
|
625
620
|
if (this.hasNotFoundMatch()) newStatusCode = 404;
|
|
626
|
-
else if (this.
|
|
627
|
-
if (newStatusCode !== void 0) this.
|
|
628
|
-
...s,
|
|
629
|
-
statusCode: newStatusCode
|
|
630
|
-
}));
|
|
621
|
+
else if (this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error")) newStatusCode = 500;
|
|
622
|
+
if (newStatusCode !== void 0) this.stores.statusCode.setState(() => newStatusCode);
|
|
631
623
|
};
|
|
632
624
|
this.startViewTransition = (fn) => {
|
|
633
625
|
const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
|
|
@@ -636,11 +628,8 @@ var RouterCore = class {
|
|
|
636
628
|
let startViewTransitionParams;
|
|
637
629
|
if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
|
|
638
630
|
const next = this.latestLocation;
|
|
639
|
-
const prevLocation = this.
|
|
640
|
-
const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo(
|
|
641
|
-
resolvedLocation: prevLocation,
|
|
642
|
-
location: next
|
|
643
|
-
})) : shouldViewTransition.types;
|
|
631
|
+
const prevLocation = this.stores.resolvedLocation.state;
|
|
632
|
+
const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo(next, prevLocation)) : shouldViewTransition.types;
|
|
644
633
|
if (resolvedViewTransitionTypes === false) {
|
|
645
634
|
fn();
|
|
646
635
|
return;
|
|
@@ -655,20 +644,27 @@ var RouterCore = class {
|
|
|
655
644
|
};
|
|
656
645
|
this.updateMatch = (id, updater) => {
|
|
657
646
|
this.startTransition(() => {
|
|
658
|
-
const
|
|
659
|
-
if (
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
647
|
+
const pendingMatch = this.stores.pendingMatchStoresById.get(id);
|
|
648
|
+
if (pendingMatch) {
|
|
649
|
+
pendingMatch.setState(updater);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
const activeMatch = this.stores.activeMatchStoresById.get(id);
|
|
653
|
+
if (activeMatch) {
|
|
654
|
+
activeMatch.setState(updater);
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const cachedMatch = this.stores.cachedMatchStoresById.get(id);
|
|
658
|
+
if (cachedMatch) {
|
|
659
|
+
const next = updater(cachedMatch.state);
|
|
660
|
+
if (next.status === "redirected") {
|
|
661
|
+
if (this.stores.cachedMatchStoresById.delete(id)) this.stores.cachedMatchesId.setState((prev) => prev.filter((matchId) => matchId !== id));
|
|
662
|
+
} else cachedMatch.setState(() => next);
|
|
663
|
+
}
|
|
667
664
|
});
|
|
668
665
|
};
|
|
669
666
|
this.getMatch = (matchId) => {
|
|
670
|
-
|
|
671
|
-
return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
|
|
667
|
+
return this.stores.cachedMatchStoresById.get(matchId)?.state ?? this.stores.pendingMatchStoresById.get(matchId)?.state ?? this.stores.activeMatchStoresById.get(matchId)?.state;
|
|
672
668
|
};
|
|
673
669
|
this.invalidate = (opts) => {
|
|
674
670
|
const invalidate = (d) => {
|
|
@@ -682,12 +678,11 @@ var RouterCore = class {
|
|
|
682
678
|
};
|
|
683
679
|
return d;
|
|
684
680
|
};
|
|
685
|
-
this.
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
}));
|
|
681
|
+
this.batch(() => {
|
|
682
|
+
this.stores.setActiveMatches(this.stores.activeMatchesSnapshot.state.map(invalidate));
|
|
683
|
+
this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.map(invalidate));
|
|
684
|
+
this.stores.setPendingMatches(this.stores.pendingMatchesSnapshot.state.map(invalidate));
|
|
685
|
+
});
|
|
691
686
|
this.shouldViewTransition = false;
|
|
692
687
|
return this.load({ sync: opts?.sync });
|
|
693
688
|
};
|
|
@@ -715,26 +710,17 @@ var RouterCore = class {
|
|
|
715
710
|
};
|
|
716
711
|
this.clearCache = (opts) => {
|
|
717
712
|
const filter = opts?.filter;
|
|
718
|
-
if (filter !== void 0) this.
|
|
719
|
-
|
|
720
|
-
...s,
|
|
721
|
-
cachedMatches: s.cachedMatches.filter((m) => !filter(m))
|
|
722
|
-
};
|
|
723
|
-
});
|
|
724
|
-
else this.__store.setState((s) => {
|
|
725
|
-
return {
|
|
726
|
-
...s,
|
|
727
|
-
cachedMatches: []
|
|
728
|
-
};
|
|
729
|
-
});
|
|
713
|
+
if (filter !== void 0) this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.filter((m) => !filter(m)));
|
|
714
|
+
else this.stores.setCachedMatches([]);
|
|
730
715
|
};
|
|
731
716
|
this.clearExpiredCache = () => {
|
|
717
|
+
const now = Date.now();
|
|
732
718
|
const filter = (d) => {
|
|
733
719
|
const route = this.looseRoutesById[d.routeId];
|
|
734
720
|
if (!route.options.loader) return true;
|
|
735
721
|
const gcTime = (d.preload ? route.options.preloadGcTime ?? this.options.defaultPreloadGcTime : route.options.gcTime ?? this.options.defaultGcTime) ?? 300 * 1e3;
|
|
736
722
|
if (d.status === "error") return true;
|
|
737
|
-
return
|
|
723
|
+
return now - d.updatedAt >= gcTime;
|
|
738
724
|
};
|
|
739
725
|
this.clearCache({ filter });
|
|
740
726
|
};
|
|
@@ -746,16 +732,13 @@ var RouterCore = class {
|
|
|
746
732
|
preload: true,
|
|
747
733
|
dest: opts
|
|
748
734
|
});
|
|
749
|
-
const activeMatchIds = new Set([...this.state
|
|
750
|
-
const loadedMatchIds = new Set([...activeMatchIds, ...this.
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}));
|
|
757
|
-
});
|
|
758
|
-
});
|
|
735
|
+
const activeMatchIds = new Set([...this.stores.matchesId.state, ...this.stores.pendingMatchesId.state]);
|
|
736
|
+
const loadedMatchIds = new Set([...activeMatchIds, ...this.stores.cachedMatchesId.state]);
|
|
737
|
+
const matchesToCache = matches.filter((match) => !loadedMatchIds.has(match.id));
|
|
738
|
+
if (matchesToCache.length) {
|
|
739
|
+
const cachedMatches = this.stores.cachedMatchesSnapshot.state;
|
|
740
|
+
this.stores.setCachedMatches([...cachedMatches, ...matchesToCache]);
|
|
741
|
+
}
|
|
759
742
|
try {
|
|
760
743
|
matches = await loadMatches({
|
|
761
744
|
router: this,
|
|
@@ -788,8 +771,8 @@ var RouterCore = class {
|
|
|
788
771
|
leaveParams: true
|
|
789
772
|
};
|
|
790
773
|
const next = this.buildLocation(matchLocation);
|
|
791
|
-
if (opts?.pending && this.
|
|
792
|
-
const baseLocation = (opts?.pending === void 0 ? !this.
|
|
774
|
+
if (opts?.pending && this.stores.status.state !== "pending") return false;
|
|
775
|
+
const baseLocation = (opts?.pending === void 0 ? !this.stores.isLoading.state : opts.pending) ? this.latestLocation : this.stores.resolvedLocation.state || this.stores.location.state;
|
|
793
776
|
const match = findSingleMatch(next.pathname, opts?.caseSensitive ?? false, opts?.fuzzy ?? false, baseLocation.pathname, this.processedTree);
|
|
794
777
|
if (!match) return false;
|
|
795
778
|
if (location.params) {
|
|
@@ -799,8 +782,9 @@ var RouterCore = class {
|
|
|
799
782
|
return match.rawParams;
|
|
800
783
|
};
|
|
801
784
|
this.hasNotFoundMatch = () => {
|
|
802
|
-
return this.
|
|
785
|
+
return this.stores.activeMatchesSnapshot.state.some((d) => d.status === "notFound" || d.globalNotFound);
|
|
803
786
|
};
|
|
787
|
+
this.getStoreConfig = getStoreConfig;
|
|
804
788
|
this.update({
|
|
805
789
|
defaultPreloadDelay: 50,
|
|
806
790
|
defaultPendingMs: 1e3,
|
|
@@ -822,7 +806,7 @@ var RouterCore = class {
|
|
|
822
806
|
return !!this.options.isPrerendering;
|
|
823
807
|
}
|
|
824
808
|
get state() {
|
|
825
|
-
return this.__store.state;
|
|
809
|
+
return this.stores.__store.state;
|
|
826
810
|
}
|
|
827
811
|
setRoutes({ routesById, routesByPath, processedTree }) {
|
|
828
812
|
this.routesById = routesById;
|
|
@@ -849,7 +833,8 @@ var RouterCore = class {
|
|
|
849
833
|
else isGlobalNotFound = true;
|
|
850
834
|
const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
|
|
851
835
|
const matches = new Array(matchedRoutes.length);
|
|
852
|
-
const
|
|
836
|
+
const previousActiveMatchesByRouteId = /* @__PURE__ */ new Map();
|
|
837
|
+
for (const store of this.stores.activeMatchStoresById.values()) if (store.routeId) previousActiveMatchesByRouteId.set(store.routeId, store.state);
|
|
853
838
|
for (let index = 0; index < matchedRoutes.length; index++) {
|
|
854
839
|
const route = matchedRoutes[index];
|
|
855
840
|
const parentMatch = matches[index - 1];
|
|
@@ -889,7 +874,7 @@ var RouterCore = class {
|
|
|
889
874
|
});
|
|
890
875
|
const matchId = route.id + interpolatedPath + loaderDepsHash;
|
|
891
876
|
const existingMatch = this.getMatch(matchId);
|
|
892
|
-
const previousMatch =
|
|
877
|
+
const previousMatch = previousActiveMatchesByRouteId.get(route.id);
|
|
893
878
|
const strictParams = existingMatch?._strictParams ?? usedParams;
|
|
894
879
|
let paramsError = void 0;
|
|
895
880
|
if (!existingMatch) try {
|
|
@@ -960,7 +945,7 @@ var RouterCore = class {
|
|
|
960
945
|
const match = matches[index];
|
|
961
946
|
const route = this.looseRoutesById[match.routeId];
|
|
962
947
|
const existingMatch = this.getMatch(match.id);
|
|
963
|
-
const previousMatch =
|
|
948
|
+
const previousMatch = previousActiveMatchesByRouteId.get(match.routeId);
|
|
964
949
|
match.params = previousMatch ? nullReplaceEqualDeep(previousMatch.params, routeParams) : routeParams;
|
|
965
950
|
if (!existingMatch) {
|
|
966
951
|
const parentMatch = matches[index - 1];
|
|
@@ -1005,8 +990,9 @@ var RouterCore = class {
|
|
|
1005
990
|
for (const route of matchedRoutes) try {
|
|
1006
991
|
Object.assign(accumulatedSearch, validateSearch(route.options.validateSearch, accumulatedSearch));
|
|
1007
992
|
} catch {}
|
|
1008
|
-
const
|
|
1009
|
-
const
|
|
993
|
+
const lastStateMatchId = last(this.stores.matchesId.state);
|
|
994
|
+
const lastStateMatch = lastStateMatchId && this.stores.activeMatchStoresById.get(lastStateMatchId)?.state;
|
|
995
|
+
const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && lastStateMatch.pathname === location.pathname;
|
|
1010
996
|
let params;
|
|
1011
997
|
if (canReuseParams) params = lastStateMatch.params;
|
|
1012
998
|
else {
|
|
@@ -1051,8 +1037,6 @@ function getInitialRouterState(location) {
|
|
|
1051
1037
|
resolvedLocation: void 0,
|
|
1052
1038
|
location,
|
|
1053
1039
|
matches: [],
|
|
1054
|
-
pendingMatches: [],
|
|
1055
|
-
cachedMatches: [],
|
|
1056
1040
|
statusCode: 200
|
|
1057
1041
|
};
|
|
1058
1042
|
}
|