tanstack-router-cache 0.1.7 → 0.1.9
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/components/cached-outlet.cjs +12 -0
- package/dist/components/cached-outlet.js +12 -0
- package/dist/components/off-screen-in.cjs +130 -0
- package/dist/components/off-screen-in.js +130 -0
- package/dist/components/off-screen.cjs +8 -0
- package/dist/components/off-screen.js +8 -0
- package/dist/components/restore-cached-href.cjs +28 -0
- package/dist/components/restore-cached-href.js +28 -0
- package/dist/components/route-cache-manager.cjs +485 -0
- package/dist/components/route-cache-manager.js +485 -0
- package/dist/components/router-cache-outlet.cjs +9 -0
- package/dist/components/router-cache-outlet.js +9 -0
- package/dist/contexts/router-cache.cjs +237 -0
- package/dist/contexts/router-cache.d.ts +40 -0
- package/dist/contexts/router-cache.js +235 -0
- package/dist/dom/dismiss-transient-ui.cjs +230 -0
- package/dist/dom/dismiss-transient-ui.js +228 -0
- package/dist/hooks/use-event-listener.cjs +76 -0
- package/dist/hooks/use-event-listener.js +76 -0
- package/dist/hooks/use-route-cache-active.cjs +19 -0
- package/dist/hooks/use-route-cache-active.js +19 -0
- package/dist/hooks/use-route-cache-activity.cjs +12 -0
- package/dist/hooks/use-route-cache-activity.js +12 -0
- package/dist/hooks/use-route-cache-effect.cjs +38 -0
- package/dist/hooks/use-route-cache-effect.js +38 -0
- package/dist/hooks/use-route-cache-error-boundary.cjs +23 -0
- package/dist/hooks/use-route-cache-error-boundary.js +23 -0
- package/dist/hooks/use-route-cache-navigation.cjs +36 -0
- package/dist/hooks/use-route-cache-navigation.js +36 -0
- package/dist/hooks/use-router-cache-debug.cjs +85 -0
- package/dist/hooks/use-router-cache-debug.js +85 -0
- package/dist/hooks/use-router-cache.cjs +32 -0
- package/dist/hooks/use-router-cache.js +32 -0
- package/dist/hooks/use-update.cjs +8 -0
- package/dist/hooks/use-update.js +8 -0
- package/dist/index.cjs +18 -1402
- package/dist/index.d.ts +9 -1
- package/dist/index.js +10 -1395
- package/dist/pathname.cjs +8 -0
- package/dist/pathname.js +8 -0
- package/dist/route-cache-static-data.cjs +43 -0
- package/dist/route-cache-static-data.d.ts +45 -0
- package/dist/route-cache-static-data.js +41 -0
- package/dist/types.d.ts +28 -0
- package/docs/architecture.md +8 -5
- package/docs/cache-behavior.md +17 -0
- package/docs/components.md +1 -2
- package/docs/getting-started.md +38 -3
- package/docs/types.md +6 -0
- package/package.json +2 -2
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
const require_pathname = require("../pathname.cjs");
|
|
2
|
+
const require_route_cache_static_data = require("../route-cache-static-data.cjs");
|
|
3
|
+
const require_router_cache = require("../contexts/router-cache.cjs");
|
|
4
|
+
const require_use_event_listener = require("../hooks/use-event-listener.cjs");
|
|
5
|
+
const require_use_router_cache_debug = require("../hooks/use-router-cache-debug.cjs");
|
|
6
|
+
const require_cached_outlet = require("./cached-outlet.cjs");
|
|
7
|
+
const require_off_screen = require("./off-screen.cjs");
|
|
8
|
+
const require_restore_cached_href = require("./restore-cached-href.cjs");
|
|
9
|
+
let _tanstack_react_router = require("@tanstack/react-router");
|
|
10
|
+
let react = require("react");
|
|
11
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
12
|
+
//#region src/components/route-cache-manager.tsx
|
|
13
|
+
const LIVE_ROUTER_METHODS = [
|
|
14
|
+
"buildLocation",
|
|
15
|
+
"commitLocation",
|
|
16
|
+
"invalidate",
|
|
17
|
+
"loadRouteChunk",
|
|
18
|
+
"navigate",
|
|
19
|
+
"preloadRoute"
|
|
20
|
+
];
|
|
21
|
+
const routerSnapshotUpdaters = /* @__PURE__ */ new WeakMap();
|
|
22
|
+
function createSnapshotStore(value) {
|
|
23
|
+
let currentValue = value;
|
|
24
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
25
|
+
return {
|
|
26
|
+
get: () => currentValue,
|
|
27
|
+
set: (nextValue) => {
|
|
28
|
+
if (Object.is(currentValue, nextValue)) return;
|
|
29
|
+
currentValue = nextValue;
|
|
30
|
+
for (const listener of listeners) listener(currentValue);
|
|
31
|
+
},
|
|
32
|
+
subscribe: (listener) => {
|
|
33
|
+
if (listener) listeners.add(listener);
|
|
34
|
+
return { unsubscribe: listener ? () => {
|
|
35
|
+
listeners.delete(listener);
|
|
36
|
+
} : () => void 0 };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function createRouterSnapshotData({ matches, router, routerLocation, routerResolvedLocation }) {
|
|
41
|
+
const snapshotMatches = matches.reduce((snapshot, match) => {
|
|
42
|
+
const nextMatch = snapshotMatch(match, routerLocation);
|
|
43
|
+
if (isRouterMatch(nextMatch)) snapshot.push(nextMatch);
|
|
44
|
+
return snapshot;
|
|
45
|
+
}, []);
|
|
46
|
+
return {
|
|
47
|
+
matches: snapshotMatches,
|
|
48
|
+
state: {
|
|
49
|
+
...router.stores.__store.get(),
|
|
50
|
+
matches: snapshotMatches,
|
|
51
|
+
location: routerLocation,
|
|
52
|
+
resolvedLocation: routerResolvedLocation
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function createMatchStore(match) {
|
|
57
|
+
return Object.assign(createSnapshotStore(match), { routeId: match.routeId });
|
|
58
|
+
}
|
|
59
|
+
function syncRouterSnapshot(routerSnapshot, input) {
|
|
60
|
+
const update = routerSnapshotUpdaters.get(routerSnapshot);
|
|
61
|
+
if (!update) return false;
|
|
62
|
+
update(input);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
function getLiveRouterMethodDescriptors(router) {
|
|
66
|
+
return Object.fromEntries(LIVE_ROUTER_METHODS.flatMap((methodName) => {
|
|
67
|
+
const method = router[methodName];
|
|
68
|
+
if (typeof method !== "function") return [];
|
|
69
|
+
return [[methodName, { value: method.bind(router) }]];
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
function toRouterLocation(location) {
|
|
73
|
+
return { ...location };
|
|
74
|
+
}
|
|
75
|
+
function isReadyCachedRoute(route) {
|
|
76
|
+
return Boolean(route && require_route_cache_static_data.isRouteCacheEnabled(route.staticData) && !require_route_cache_static_data.isCachedRouteStale(route) && route.ready && route.matchId && route.routerSnapshot);
|
|
77
|
+
}
|
|
78
|
+
function hasErroredRouteMatch(matches) {
|
|
79
|
+
return matches.some((match) => match?.status === "error");
|
|
80
|
+
}
|
|
81
|
+
function hasRetainedRouteError(erroredRouteCounts, pathname) {
|
|
82
|
+
return (erroredRouteCounts[pathname] ?? 0) > 0;
|
|
83
|
+
}
|
|
84
|
+
function hasCurrentRouterMatchError({ matches, resolvedPathname, routerPathname }) {
|
|
85
|
+
return routerPathname === resolvedPathname && hasErroredRouteMatch(matches);
|
|
86
|
+
}
|
|
87
|
+
function hasCurrentRouteError({ erroredRouteCounts, matches, resolvedPathname, routerPathname }) {
|
|
88
|
+
return hasRetainedRouteError(erroredRouteCounts, routerPathname) || hasCurrentRouterMatchError({
|
|
89
|
+
matches,
|
|
90
|
+
resolvedPathname,
|
|
91
|
+
routerPathname
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function isRouterMatch(match) {
|
|
95
|
+
return Boolean(match?.id && match.routeId);
|
|
96
|
+
}
|
|
97
|
+
function snapshotMatch(match, routerLocation) {
|
|
98
|
+
if (!isRouterMatch(match)) return;
|
|
99
|
+
const isLocationMatch = match.pathname ? require_pathname.normalizeCachedRoutePathname(match.pathname) === require_pathname.normalizeCachedRoutePathname(routerLocation.pathname) : false;
|
|
100
|
+
return {
|
|
101
|
+
...match,
|
|
102
|
+
...isLocationMatch ? {
|
|
103
|
+
_strictSearch: routerLocation.search,
|
|
104
|
+
search: routerLocation.search
|
|
105
|
+
} : {},
|
|
106
|
+
_nonReactive: { ...match._nonReactive }
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function isCurrentUnmanagedCachedRoute(route, routerHref) {
|
|
110
|
+
return Boolean(route && require_route_cache_static_data.isRouteCacheEnabled(route.staticData) && route.ready && route.routerSnapshot && route.href === routerHref);
|
|
111
|
+
}
|
|
112
|
+
function syncReadyCachedRoute({ matchId, matches, routeId, route, routerLocation, router, routerResolvedLocation, routerHref, routerPathname, setCachedRoutes, staticData }) {
|
|
113
|
+
const routerSnapshotInput = {
|
|
114
|
+
matches,
|
|
115
|
+
router,
|
|
116
|
+
routerLocation,
|
|
117
|
+
routerResolvedLocation
|
|
118
|
+
};
|
|
119
|
+
let routerSnapshot = matchId ? route?.routerSnapshot : void 0;
|
|
120
|
+
if (routerSnapshot && !syncRouterSnapshot(routerSnapshot, routerSnapshotInput)) {
|
|
121
|
+
if (isCurrentUnmanagedCachedRoute(route, routerHref)) return;
|
|
122
|
+
routerSnapshot = void 0;
|
|
123
|
+
}
|
|
124
|
+
if (matchId && !routerSnapshot) routerSnapshot = createRouterSnapshot(routerSnapshotInput);
|
|
125
|
+
setCachedRoutes(routerPathname, {
|
|
126
|
+
href: routerHref,
|
|
127
|
+
matchId,
|
|
128
|
+
routeId,
|
|
129
|
+
ready: true,
|
|
130
|
+
routerSnapshot,
|
|
131
|
+
staticData
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
function syncCachedRouteState({ isCurrentMatchReady, isCurrentMatchResolved, deleteCachedRoutes, isCurrentRouteErrored, matchId, matches, route, routeId, router, routerHref, routerLocation, routerPathname, routerResolvedLocation, setCachedRoutes, staticData }) {
|
|
135
|
+
if (isCurrentRouteErrored) {
|
|
136
|
+
if (route) deleteCachedRoutes([routerPathname]);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (!isCurrentMatchResolved) return;
|
|
140
|
+
if (staticData && require_route_cache_static_data.isRouteCacheEnabled(staticData)) {
|
|
141
|
+
if (!isCurrentMatchReady) return;
|
|
142
|
+
syncReadyCachedRoute({
|
|
143
|
+
matchId,
|
|
144
|
+
matches,
|
|
145
|
+
routeId,
|
|
146
|
+
route,
|
|
147
|
+
routerLocation,
|
|
148
|
+
router,
|
|
149
|
+
routerResolvedLocation,
|
|
150
|
+
routerHref,
|
|
151
|
+
routerPathname,
|
|
152
|
+
setCachedRoutes,
|
|
153
|
+
staticData
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (route) deleteCachedRoutes([routerPathname]);
|
|
158
|
+
}
|
|
159
|
+
function createRouterSnapshot(input) {
|
|
160
|
+
const { router, routerLocation, routerResolvedLocation } = input;
|
|
161
|
+
const snapshotData = createRouterSnapshotData(input);
|
|
162
|
+
const snapshotMatches = snapshotData.matches;
|
|
163
|
+
const matchStores = new Map(snapshotMatches.map((match) => [match.id, createMatchStore(match)]));
|
|
164
|
+
const routeMatchStoreCache = /* @__PURE__ */ new Map();
|
|
165
|
+
const stores = {
|
|
166
|
+
...router.stores,
|
|
167
|
+
status: createSnapshotStore(router.stores.status.get()),
|
|
168
|
+
loadedAt: createSnapshotStore(router.stores.loadedAt.get()),
|
|
169
|
+
isLoading: createSnapshotStore(router.stores.isLoading.get()),
|
|
170
|
+
isTransitioning: createSnapshotStore(router.stores.isTransitioning.get()),
|
|
171
|
+
location: createSnapshotStore(routerLocation),
|
|
172
|
+
resolvedLocation: createSnapshotStore(routerResolvedLocation),
|
|
173
|
+
statusCode: createSnapshotStore(router.stores.statusCode.get()),
|
|
174
|
+
redirect: createSnapshotStore(router.stores.redirect.get()),
|
|
175
|
+
matchesId: createSnapshotStore(snapshotMatches.map((match) => match.id)),
|
|
176
|
+
pendingIds: createSnapshotStore([]),
|
|
177
|
+
cachedIds: createSnapshotStore([]),
|
|
178
|
+
matches: createSnapshotStore(snapshotMatches),
|
|
179
|
+
pendingMatches: createSnapshotStore([]),
|
|
180
|
+
cachedMatches: createSnapshotStore([]),
|
|
181
|
+
firstId: createSnapshotStore(snapshotMatches[0]?.id),
|
|
182
|
+
hasPending: createSnapshotStore(snapshotMatches.some((match) => match.status === "pending")),
|
|
183
|
+
matchRouteDeps: createSnapshotStore({
|
|
184
|
+
locationHref: routerLocation.href,
|
|
185
|
+
resolvedLocationHref: routerResolvedLocation?.href,
|
|
186
|
+
status: snapshotData.state.status
|
|
187
|
+
}),
|
|
188
|
+
__store: createSnapshotStore(snapshotData.state),
|
|
189
|
+
matchStores,
|
|
190
|
+
pendingMatchStores: /* @__PURE__ */ new Map(),
|
|
191
|
+
cachedMatchStores: /* @__PURE__ */ new Map(),
|
|
192
|
+
getRouteMatchStore: (routeId) => {
|
|
193
|
+
let cached = routeMatchStoreCache.get(routeId);
|
|
194
|
+
if (!cached) {
|
|
195
|
+
cached = createSnapshotStore(snapshotMatches.find((match) => match.routeId === routeId));
|
|
196
|
+
routeMatchStoreCache.set(routeId, cached);
|
|
197
|
+
}
|
|
198
|
+
return cached;
|
|
199
|
+
},
|
|
200
|
+
setMatches: () => void 0,
|
|
201
|
+
setPending: () => void 0,
|
|
202
|
+
setCached: () => void 0
|
|
203
|
+
};
|
|
204
|
+
const updateSnapshot = (nextInput) => {
|
|
205
|
+
const nextData = createRouterSnapshotData(nextInput);
|
|
206
|
+
const nextMatches = nextData.matches;
|
|
207
|
+
const nextMatchIds = new Set(nextMatches.map((match) => match.id));
|
|
208
|
+
const nextMatchesByRouteId = new Map(nextMatches.map((match) => [match.routeId, match]));
|
|
209
|
+
for (const match of nextMatches) {
|
|
210
|
+
const store = matchStores.get(match.id);
|
|
211
|
+
if (store) {
|
|
212
|
+
store.set(match);
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
matchStores.set(match.id, createMatchStore(match));
|
|
216
|
+
}
|
|
217
|
+
for (const [matchId] of matchStores) if (!nextMatchIds.has(matchId)) matchStores.delete(matchId);
|
|
218
|
+
stores.status.set(nextInput.router.stores.status.get());
|
|
219
|
+
stores.loadedAt.set(nextInput.router.stores.loadedAt.get());
|
|
220
|
+
stores.isLoading.set(nextInput.router.stores.isLoading.get());
|
|
221
|
+
stores.isTransitioning.set(nextInput.router.stores.isTransitioning.get());
|
|
222
|
+
stores.location.set(nextInput.routerLocation);
|
|
223
|
+
stores.resolvedLocation.set(nextInput.routerResolvedLocation);
|
|
224
|
+
stores.statusCode.set(nextInput.router.stores.statusCode.get());
|
|
225
|
+
stores.redirect.set(nextInput.router.stores.redirect.get());
|
|
226
|
+
stores.matchesId.set(nextMatches.map((match) => match.id));
|
|
227
|
+
stores.pendingIds.set([]);
|
|
228
|
+
stores.cachedIds.set([]);
|
|
229
|
+
stores.matches.set(nextMatches);
|
|
230
|
+
stores.pendingMatches.set([]);
|
|
231
|
+
stores.cachedMatches.set([]);
|
|
232
|
+
stores.firstId.set(nextMatches[0]?.id);
|
|
233
|
+
stores.hasPending.set(nextMatches.some((match) => match.status === "pending"));
|
|
234
|
+
stores.matchRouteDeps.set({
|
|
235
|
+
locationHref: nextInput.routerLocation.href,
|
|
236
|
+
resolvedLocationHref: nextInput.routerResolvedLocation?.href,
|
|
237
|
+
status: nextData.state.status
|
|
238
|
+
});
|
|
239
|
+
stores.__store.set(nextData.state);
|
|
240
|
+
for (const [routeId, store] of routeMatchStoreCache) store.set(nextMatchesByRouteId.get(routeId));
|
|
241
|
+
};
|
|
242
|
+
const routerSnapshot = Object.create(router);
|
|
243
|
+
Object.defineProperties(routerSnapshot, {
|
|
244
|
+
stores: { value: stores },
|
|
245
|
+
latestLocation: { get: () => stores.location.get() },
|
|
246
|
+
getMatch: { value: (matchId) => matchStores.get(matchId)?.get() },
|
|
247
|
+
updateMatch: { value: () => void 0 },
|
|
248
|
+
...getLiveRouterMethodDescriptors(router)
|
|
249
|
+
});
|
|
250
|
+
routerSnapshotUpdaters.set(routerSnapshot, updateSnapshot);
|
|
251
|
+
return routerSnapshot;
|
|
252
|
+
}
|
|
253
|
+
function getRouterCacheStaticData(childMatches, isCurrentMatchResolved) {
|
|
254
|
+
if (!isCurrentMatchResolved) return;
|
|
255
|
+
for (let i = childMatches.length - 1; i >= 0; i--) {
|
|
256
|
+
const match = childMatches[i];
|
|
257
|
+
if (match?.staticData && require_route_cache_static_data.isRouteCacheEnabled(match.staticData)) return match.staticData;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function restoreCachedHref(router, href) {
|
|
261
|
+
router.navigate({
|
|
262
|
+
href,
|
|
263
|
+
replace: true,
|
|
264
|
+
resetScroll: false
|
|
265
|
+
}).catch(() => void 0);
|
|
266
|
+
}
|
|
267
|
+
function renderCachedRoute({ bypassCachedPathname, pathname, route, routerPathname }) {
|
|
268
|
+
if (pathname === bypassCachedPathname) return null;
|
|
269
|
+
if (require_route_cache_static_data.isCachedRouteStale(route)) return null;
|
|
270
|
+
const content = route.matchId && route.routerSnapshot ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_cached_outlet.default, {
|
|
271
|
+
matchId: route.matchId,
|
|
272
|
+
routerSnapshot: route.routerSnapshot
|
|
273
|
+
}) : null;
|
|
274
|
+
if (!content) return null;
|
|
275
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_off_screen.default, {
|
|
276
|
+
mode: routerPathname === pathname ? "visible" : "hidden",
|
|
277
|
+
pathname,
|
|
278
|
+
children: content
|
|
279
|
+
}, pathname);
|
|
280
|
+
}
|
|
281
|
+
function getStaleCachedRoutePathnames(cachedRoutes) {
|
|
282
|
+
const now = Date.now();
|
|
283
|
+
return Object.entries(cachedRoutes).flatMap(([pathname, route]) => require_route_cache_static_data.isCachedRouteStale(route, now) ? [pathname] : []);
|
|
284
|
+
}
|
|
285
|
+
function buildRouteCacheModes(cachedRoutes, routerPathname) {
|
|
286
|
+
const nextModes = /* @__PURE__ */ new Map();
|
|
287
|
+
for (const pathname of Object.keys(cachedRoutes)) nextModes.set(pathname, routerPathname === pathname ? "visible" : "hidden");
|
|
288
|
+
return nextModes;
|
|
289
|
+
}
|
|
290
|
+
function syncCachedRouteActivityEvents(params) {
|
|
291
|
+
const nextModes = buildRouteCacheModes(params.cachedRoutes, params.routerPathname);
|
|
292
|
+
for (const [pathname, mode] of nextModes) {
|
|
293
|
+
const previousMode = params.previousRouteCacheModes.get(pathname);
|
|
294
|
+
if (previousMode === void 0 && mode === "hidden") continue;
|
|
295
|
+
if (previousMode === mode) continue;
|
|
296
|
+
params.eventListener.emit("activeChange", {
|
|
297
|
+
pathname,
|
|
298
|
+
mode
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
for (const [pathname] of params.previousRouteCacheModes) {
|
|
302
|
+
if (nextModes.has(pathname)) continue;
|
|
303
|
+
params.eventListener.emit("activeChange", {
|
|
304
|
+
pathname,
|
|
305
|
+
mode: "hidden"
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return nextModes;
|
|
309
|
+
}
|
|
310
|
+
function RouteCacheManager() {
|
|
311
|
+
const { cachedRoutes, deleteCachedRoutes, erroredRouteCounts, setCachedRoutes, touchCachedRoutes } = require_router_cache.useRouterCacheContext();
|
|
312
|
+
const { eventListener } = require_use_event_listener.useEventListener();
|
|
313
|
+
const pendingCachedNavigationRef = (0, react.useRef)(null);
|
|
314
|
+
const previousPathnameRef = (0, react.useRef)(void 0);
|
|
315
|
+
const previousHrefRef = (0, react.useRef)(void 0);
|
|
316
|
+
const previousRouteCacheModesRef = (0, react.useRef)(null);
|
|
317
|
+
previousRouteCacheModesRef.current ??= /* @__PURE__ */ new Map();
|
|
318
|
+
const previousVisiblePathnameRef = (0, react.useRef)(void 0);
|
|
319
|
+
const routerLocation = (0, _tanstack_react_router.useRouterState)({ select: (state) => toRouterLocation(state.location) });
|
|
320
|
+
const routerHref = routerLocation.href;
|
|
321
|
+
const routerPathname = require_pathname.normalizeCachedRoutePathname(routerLocation.pathname);
|
|
322
|
+
const routerResolvedLocation = (0, _tanstack_react_router.useRouterState)({ select: (state) => state.resolvedLocation ? toRouterLocation(state.resolvedLocation) : void 0 });
|
|
323
|
+
const resolvedPathname = require_pathname.normalizeCachedRoutePathname(routerResolvedLocation?.pathname ?? routerPathname);
|
|
324
|
+
const destinationRoute = cachedRoutes[routerPathname];
|
|
325
|
+
const matches = (0, _tanstack_react_router.useMatches)();
|
|
326
|
+
const childMatches = (0, _tanstack_react_router.useChildMatches)();
|
|
327
|
+
const router = (0, _tanstack_react_router.useRouter)();
|
|
328
|
+
const currentMatch = matches.length ? matches.at(-1) : void 0;
|
|
329
|
+
const outletRootMatch = childMatches.length ? childMatches[0] : currentMatch;
|
|
330
|
+
const isCurrentMatchResolved = (currentMatch?.pathname ? require_pathname.normalizeCachedRoutePathname(currentMatch.pathname) : void 0) === routerPathname;
|
|
331
|
+
const isCurrentMatchReady = isCurrentMatchResolved && currentMatch?.status === "success";
|
|
332
|
+
const staticData = getRouterCacheStaticData(childMatches, isCurrentMatchResolved);
|
|
333
|
+
const matchId = isCurrentMatchResolved && outletRootMatch ? outletRootMatch.id : void 0;
|
|
334
|
+
const routeId = isCurrentMatchResolved && outletRootMatch ? outletRootMatch.routeId : void 0;
|
|
335
|
+
const currentCachedRoute = cachedRoutes[routerPathname];
|
|
336
|
+
const isCurrentRouteErrored = hasCurrentRouteError({
|
|
337
|
+
erroredRouteCounts,
|
|
338
|
+
matches,
|
|
339
|
+
resolvedPathname,
|
|
340
|
+
routerPathname
|
|
341
|
+
});
|
|
342
|
+
const bypassCachedPathname = isCurrentRouteErrored ? routerPathname : void 0;
|
|
343
|
+
const previousPathname = previousPathnameRef.current;
|
|
344
|
+
previousHrefRef.current;
|
|
345
|
+
const shouldRestoreDestinationHref = require_restore_cached_href.shouldRestoreCachedHref({
|
|
346
|
+
cachedHref: destinationRoute?.href,
|
|
347
|
+
currentHref: routerHref,
|
|
348
|
+
currentPathname: routerPathname,
|
|
349
|
+
isRouteCacheEnabled: require_route_cache_static_data.isRouteCacheEnabled(destinationRoute?.staticData),
|
|
350
|
+
previousPathname
|
|
351
|
+
});
|
|
352
|
+
(0, react.useLayoutEffect)(() => {
|
|
353
|
+
const stalePathnames = getStaleCachedRoutePathnames(cachedRoutes);
|
|
354
|
+
if (stalePathnames.length > 0) deleteCachedRoutes(stalePathnames);
|
|
355
|
+
}, [cachedRoutes, deleteCachedRoutes]);
|
|
356
|
+
(0, react.useLayoutEffect)(() => {
|
|
357
|
+
if (shouldRestoreDestinationHref) return;
|
|
358
|
+
syncCachedRouteState({
|
|
359
|
+
isCurrentMatchReady,
|
|
360
|
+
isCurrentMatchResolved,
|
|
361
|
+
isCurrentRouteErrored,
|
|
362
|
+
matchId,
|
|
363
|
+
matches,
|
|
364
|
+
routeId,
|
|
365
|
+
route: currentCachedRoute,
|
|
366
|
+
routerLocation,
|
|
367
|
+
router,
|
|
368
|
+
routerResolvedLocation,
|
|
369
|
+
routerHref,
|
|
370
|
+
routerPathname,
|
|
371
|
+
deleteCachedRoutes,
|
|
372
|
+
setCachedRoutes,
|
|
373
|
+
staticData
|
|
374
|
+
});
|
|
375
|
+
}, [
|
|
376
|
+
currentCachedRoute,
|
|
377
|
+
deleteCachedRoutes,
|
|
378
|
+
isCurrentRouteErrored,
|
|
379
|
+
isCurrentMatchReady,
|
|
380
|
+
isCurrentMatchResolved,
|
|
381
|
+
matchId,
|
|
382
|
+
matches,
|
|
383
|
+
routeId,
|
|
384
|
+
router,
|
|
385
|
+
routerLocation,
|
|
386
|
+
routerResolvedLocation,
|
|
387
|
+
routerHref,
|
|
388
|
+
routerPathname,
|
|
389
|
+
staticData,
|
|
390
|
+
setCachedRoutes,
|
|
391
|
+
shouldRestoreDestinationHref
|
|
392
|
+
]);
|
|
393
|
+
(0, react.useLayoutEffect)(() => {
|
|
394
|
+
const lastVisitedPathname = previousPathnameRef.current;
|
|
395
|
+
const pendingNavigation = pendingCachedNavigationRef.current;
|
|
396
|
+
if (pendingNavigation && pendingNavigation.pathname !== routerPathname) {
|
|
397
|
+
eventListener.emit("cachedNavigationCancel", pendingNavigation);
|
|
398
|
+
pendingCachedNavigationRef.current = null;
|
|
399
|
+
}
|
|
400
|
+
if (!lastVisitedPathname || lastVisitedPathname === routerPathname) return;
|
|
401
|
+
if (!isReadyCachedRoute(destinationRoute)) return;
|
|
402
|
+
if (pendingCachedNavigationRef.current?.pathname === routerPathname) return;
|
|
403
|
+
const nextNavigation = {
|
|
404
|
+
pathname: routerPathname,
|
|
405
|
+
startedAt: performance.now()
|
|
406
|
+
};
|
|
407
|
+
pendingCachedNavigationRef.current = nextNavigation;
|
|
408
|
+
eventListener.emit("cachedNavigationStart", nextNavigation);
|
|
409
|
+
}, [
|
|
410
|
+
destinationRoute,
|
|
411
|
+
eventListener,
|
|
412
|
+
routerPathname
|
|
413
|
+
]);
|
|
414
|
+
(0, react.useLayoutEffect)(() => {
|
|
415
|
+
previousRouteCacheModesRef.current ??= /* @__PURE__ */ new Map();
|
|
416
|
+
previousRouteCacheModesRef.current = syncCachedRouteActivityEvents({
|
|
417
|
+
cachedRoutes,
|
|
418
|
+
eventListener,
|
|
419
|
+
previousRouteCacheModes: previousRouteCacheModesRef.current,
|
|
420
|
+
routerPathname
|
|
421
|
+
});
|
|
422
|
+
}, [
|
|
423
|
+
cachedRoutes,
|
|
424
|
+
eventListener,
|
|
425
|
+
routerPathname
|
|
426
|
+
]);
|
|
427
|
+
(0, react.useLayoutEffect)(() => {
|
|
428
|
+
if (previousVisiblePathnameRef.current === routerPathname || !cachedRoutes[routerPathname]) {
|
|
429
|
+
previousVisiblePathnameRef.current = routerPathname;
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
previousVisiblePathnameRef.current = routerPathname;
|
|
433
|
+
touchCachedRoutes([routerPathname]);
|
|
434
|
+
}, [
|
|
435
|
+
cachedRoutes,
|
|
436
|
+
touchCachedRoutes,
|
|
437
|
+
routerPathname
|
|
438
|
+
]);
|
|
439
|
+
(0, react.useEffect)(() => {
|
|
440
|
+
const pendingNavigation = pendingCachedNavigationRef.current;
|
|
441
|
+
if (routerPathname !== pendingNavigation?.pathname) return;
|
|
442
|
+
let firstFrameId = 0;
|
|
443
|
+
let secondFrameId = 0;
|
|
444
|
+
firstFrameId = globalThis.requestAnimationFrame(() => {
|
|
445
|
+
const visibleAt = performance.now();
|
|
446
|
+
secondFrameId = globalThis.requestAnimationFrame(() => {
|
|
447
|
+
const paintedAt = performance.now();
|
|
448
|
+
if (pendingCachedNavigationRef.current?.pathname !== pendingNavigation.pathname) return;
|
|
449
|
+
pendingCachedNavigationRef.current = null;
|
|
450
|
+
eventListener.emit("cachedNavigationComplete", {
|
|
451
|
+
...pendingNavigation,
|
|
452
|
+
duration: paintedAt - pendingNavigation.startedAt,
|
|
453
|
+
paintedAt,
|
|
454
|
+
visibleAt
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
return () => {
|
|
459
|
+
globalThis.cancelAnimationFrame(firstFrameId);
|
|
460
|
+
globalThis.cancelAnimationFrame(secondFrameId);
|
|
461
|
+
};
|
|
462
|
+
}, [eventListener, routerPathname]);
|
|
463
|
+
(0, react.useLayoutEffect)(() => {
|
|
464
|
+
if (!(shouldRestoreDestinationHref && destinationRoute?.href)) return;
|
|
465
|
+
restoreCachedHref(router, destinationRoute.href);
|
|
466
|
+
}, [
|
|
467
|
+
destinationRoute?.href,
|
|
468
|
+
router,
|
|
469
|
+
shouldRestoreDestinationHref
|
|
470
|
+
]);
|
|
471
|
+
(0, react.useEffect)(() => {
|
|
472
|
+
previousPathnameRef.current = routerPathname;
|
|
473
|
+
previousHrefRef.current = routerHref;
|
|
474
|
+
}, [routerHref, routerPathname]);
|
|
475
|
+
const shouldRenderLiveOutlet = routerPathname === bypassCachedPathname || !isReadyCachedRoute(destinationRoute);
|
|
476
|
+
require_use_router_cache_debug.useRouterCacheDebug(cachedRoutes, routerPathname);
|
|
477
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [Object.entries(cachedRoutes).map(([pathname, route]) => renderCachedRoute({
|
|
478
|
+
bypassCachedPathname,
|
|
479
|
+
pathname,
|
|
480
|
+
route,
|
|
481
|
+
routerPathname
|
|
482
|
+
})), shouldRenderLiveOutlet ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tanstack_react_router.Outlet, {}, `live-${routerPathname}`) : null] });
|
|
483
|
+
}
|
|
484
|
+
//#endregion
|
|
485
|
+
exports.default = RouteCacheManager;
|