@tanstack/router-core 0.0.1-alpha.8 → 0.0.1-alpha.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/build/cjs/packages/router-core/src/routeMatch.js +6 -5
- package/build/cjs/packages/router-core/src/routeMatch.js.map +1 -1
- package/build/cjs/packages/router-core/src/router.js +43 -26
- package/build/cjs/packages/router-core/src/router.js.map +1 -1
- package/build/esm/index.js +49 -31
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +134 -134
- package/build/types/index.d.ts +15 -6
- package/build/umd/index.development.js +49 -31
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/link.ts +3 -1
- package/src/routeMatch.ts +11 -7
- package/src/router.ts +52 -32
package/build/types/index.d.ts
CHANGED
|
@@ -81,9 +81,10 @@ interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
|
|
|
81
81
|
stringifySearch?: SearchSerializer;
|
|
82
82
|
parseSearch?: SearchParser;
|
|
83
83
|
filterRoutes?: FilterRoutesFn;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
defaultPreload?: false | 'intent';
|
|
85
|
+
defaultPreloadMaxAge?: number;
|
|
86
|
+
defaultPreloadGcMaxAge?: number;
|
|
87
|
+
defaultPreloadDelay?: number;
|
|
87
88
|
useErrorBoundary?: boolean;
|
|
88
89
|
defaultElement?: GetFrameworkGeneric<'Element'>;
|
|
89
90
|
defaultErrorElement?: GetFrameworkGeneric<'Element'>;
|
|
@@ -193,8 +194,10 @@ interface Router<TRouteConfig extends AnyRouteConfig = RouteConfig, TAllRouteInf
|
|
|
193
194
|
matchCache: Record<string, MatchCacheEntry>;
|
|
194
195
|
cleanMatchCache: () => void;
|
|
195
196
|
getRoute: <TId extends keyof TAllRouteInfo['routeInfoById']>(id: TId) => Route<TAllRouteInfo, TAllRouteInfo['routeInfoById'][TId]>;
|
|
196
|
-
loadRoute: (navigateOpts: BuildNextOptions
|
|
197
|
-
|
|
197
|
+
loadRoute: (navigateOpts: BuildNextOptions) => Promise<RouteMatch[]>;
|
|
198
|
+
preloadRoute: (navigateOpts: BuildNextOptions, loaderOpts: {
|
|
199
|
+
maxAge?: number;
|
|
200
|
+
gcMaxAge?: number;
|
|
198
201
|
}) => Promise<RouteMatch[]>;
|
|
199
202
|
matchRoutes: (pathname: string, opts?: {
|
|
200
203
|
strictParseParams?: boolean;
|
|
@@ -204,9 +207,11 @@ interface Router<TRouteConfig extends AnyRouteConfig = RouteConfig, TAllRouteInf
|
|
|
204
207
|
} & ({
|
|
205
208
|
preload: true;
|
|
206
209
|
maxAge: number;
|
|
210
|
+
gcMaxAge: number;
|
|
207
211
|
} | {
|
|
208
212
|
preload?: false;
|
|
209
213
|
maxAge?: never;
|
|
214
|
+
gcMaxAge?: never;
|
|
210
215
|
})) => Promise<void>;
|
|
211
216
|
invalidateRoute: (opts: MatchLocation) => void;
|
|
212
217
|
reload: () => Promise<void>;
|
|
@@ -237,6 +242,7 @@ interface RouteMatch<TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo
|
|
|
237
242
|
routeLoaderData: TRouteInfo['routeLoaderData'];
|
|
238
243
|
isFetching: boolean;
|
|
239
244
|
isPending: boolean;
|
|
245
|
+
invalidAt: number;
|
|
240
246
|
__: {
|
|
241
247
|
element?: GetFrameworkGeneric<'Element'>;
|
|
242
248
|
errorElement?: GetFrameworkGeneric<'Element'>;
|
|
@@ -263,7 +269,9 @@ interface RouteMatch<TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo
|
|
|
263
269
|
resolve: () => void;
|
|
264
270
|
};
|
|
265
271
|
cancel: () => void;
|
|
266
|
-
load: (
|
|
272
|
+
load: (opts?: {
|
|
273
|
+
maxAge?: number;
|
|
274
|
+
}) => Promise<void>;
|
|
267
275
|
invalidate: () => void;
|
|
268
276
|
hasLoaders: () => boolean;
|
|
269
277
|
}
|
|
@@ -523,6 +531,7 @@ declare type LinkOptions<TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRoute
|
|
|
523
531
|
activeOptions?: ActiveOptions;
|
|
524
532
|
preload?: false | 'intent';
|
|
525
533
|
preloadMaxAge?: number;
|
|
534
|
+
preloadGcMaxAge?: number;
|
|
526
535
|
preloadDelay?: number;
|
|
527
536
|
disabled?: boolean;
|
|
528
537
|
};
|
|
@@ -1365,12 +1365,10 @@
|
|
|
1365
1365
|
isPending: false,
|
|
1366
1366
|
isFetching: false,
|
|
1367
1367
|
isInvalid: false,
|
|
1368
|
+
invalidAt: Infinity,
|
|
1368
1369
|
getIsInvalid: () => {
|
|
1369
|
-
var _ref, _routeMatch$options$l;
|
|
1370
|
-
|
|
1371
1370
|
const now = Date.now();
|
|
1372
|
-
|
|
1373
|
-
return routeMatch.isInvalid || routeMatch.updatedAt + maxAge < now;
|
|
1371
|
+
return routeMatch.isInvalid || routeMatch.invalidAt < now;
|
|
1374
1372
|
},
|
|
1375
1373
|
__: {
|
|
1376
1374
|
abortController: new AbortController(),
|
|
@@ -1461,7 +1459,7 @@
|
|
|
1461
1459
|
hasLoaders: () => {
|
|
1462
1460
|
return !!(route.options.loader || route.options.import || elementTypes.some(d => typeof route.options[d] === 'function'));
|
|
1463
1461
|
},
|
|
1464
|
-
load: async
|
|
1462
|
+
load: async opts => {
|
|
1465
1463
|
const id = '' + Date.now() + Math.random();
|
|
1466
1464
|
routeMatch.__.latestId = id; // If the match was in an error state, set it
|
|
1467
1465
|
// to a loading state again. Otherwise, keep it
|
|
@@ -1516,6 +1514,8 @@
|
|
|
1516
1514
|
|
|
1517
1515
|
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
1518
1516
|
try {
|
|
1517
|
+
var _ref, _ref2, _opts$maxAge;
|
|
1518
|
+
|
|
1519
1519
|
if (routeMatch.options.loader) {
|
|
1520
1520
|
const data = await routeMatch.options.loader({
|
|
1521
1521
|
params: routeMatch.params,
|
|
@@ -1533,6 +1533,7 @@
|
|
|
1533
1533
|
routeMatch.error = undefined;
|
|
1534
1534
|
routeMatch.status = 'success';
|
|
1535
1535
|
routeMatch.updatedAt = Date.now();
|
|
1536
|
+
routeMatch.invalidAt = routeMatch.updatedAt + ((_ref = (_ref2 = (_opts$maxAge = opts == null ? void 0 : opts.maxAge) != null ? _opts$maxAge : routeMatch.options.loaderMaxAge) != null ? _ref2 : router.options.defaultLoaderMaxAge) != null ? _ref : 0);
|
|
1536
1537
|
} catch (err) {
|
|
1537
1538
|
if (id !== routeMatch.__.latestId) {
|
|
1538
1539
|
return routeMatch.__.loaderPromise;
|
|
@@ -1655,7 +1656,8 @@
|
|
|
1655
1656
|
const originalOptions = _extends({
|
|
1656
1657
|
defaultLoaderGcMaxAge: 5 * 60 * 1000,
|
|
1657
1658
|
defaultLoaderMaxAge: 0,
|
|
1658
|
-
|
|
1659
|
+
defaultPreloadMaxAge: 2000,
|
|
1660
|
+
defaultPreloadDelay: 50
|
|
1659
1661
|
}, userOptions, {
|
|
1660
1662
|
stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
|
|
1661
1663
|
parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
|
|
@@ -2052,7 +2054,21 @@
|
|
|
2052
2054
|
delete router.matchCache[matchId];
|
|
2053
2055
|
});
|
|
2054
2056
|
},
|
|
2055
|
-
loadRoute: async function loadRoute(navigateOpts
|
|
2057
|
+
loadRoute: async function loadRoute(navigateOpts) {
|
|
2058
|
+
if (navigateOpts === void 0) {
|
|
2059
|
+
navigateOpts = router.location;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
const next = router.buildNext(navigateOpts);
|
|
2063
|
+
const matches = router.matchRoutes(next.pathname, {
|
|
2064
|
+
strictParseParams: true
|
|
2065
|
+
});
|
|
2066
|
+
await router.loadMatches(matches);
|
|
2067
|
+
return matches;
|
|
2068
|
+
},
|
|
2069
|
+
preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
|
|
2070
|
+
var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
|
|
2071
|
+
|
|
2056
2072
|
if (navigateOpts === void 0) {
|
|
2057
2073
|
navigateOpts = router.location;
|
|
2058
2074
|
}
|
|
@@ -2063,7 +2079,8 @@
|
|
|
2063
2079
|
});
|
|
2064
2080
|
await router.loadMatches(matches, {
|
|
2065
2081
|
preload: true,
|
|
2066
|
-
maxAge: loaderOpts.maxAge
|
|
2082
|
+
maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
|
|
2083
|
+
gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
|
|
2067
2084
|
});
|
|
2068
2085
|
return matches;
|
|
2069
2086
|
},
|
|
@@ -2158,31 +2175,30 @@
|
|
|
2158
2175
|
},
|
|
2159
2176
|
loadMatches: async (resolvedMatches, loaderOpts) => {
|
|
2160
2177
|
const now = Date.now();
|
|
2178
|
+
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0;
|
|
2161
2179
|
const matchPromises = resolvedMatches.map(async match => {
|
|
2162
2180
|
// Validate the match (loads search params etc)
|
|
2163
|
-
match.__.validate(); //
|
|
2164
|
-
// if (!match.hasLoaders()) {
|
|
2165
|
-
// return
|
|
2166
|
-
// }
|
|
2167
|
-
// If this is a preload, add it to the preload cache
|
|
2181
|
+
match.__.validate(); // If this is a preload, add it to the preload cache
|
|
2168
2182
|
|
|
2169
2183
|
|
|
2170
|
-
if (loaderOpts != null && loaderOpts.preload &&
|
|
2184
|
+
if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
|
|
2171
2185
|
// If the match is currently active, don't preload it
|
|
2172
2186
|
if (router.state.matches.find(d => d.matchId === match.matchId)) {
|
|
2173
2187
|
return;
|
|
2174
2188
|
}
|
|
2175
2189
|
|
|
2176
2190
|
router.matchCache[match.matchId] = {
|
|
2177
|
-
gc: now + loaderOpts.
|
|
2178
|
-
// TODO: Should this use the route's maxAge?
|
|
2191
|
+
gc: now + loaderOpts.gcMaxAge,
|
|
2179
2192
|
match
|
|
2180
2193
|
};
|
|
2181
2194
|
} // If the match is invalid, errored or idle, trigger it to load
|
|
2182
2195
|
|
|
2183
2196
|
|
|
2184
2197
|
if (match.status === 'success' && match.getIsInvalid() || match.status === 'error' || match.status === 'idle') {
|
|
2185
|
-
|
|
2198
|
+
const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
|
|
2199
|
+
match.load({
|
|
2200
|
+
maxAge
|
|
2201
|
+
});
|
|
2186
2202
|
}
|
|
2187
2203
|
|
|
2188
2204
|
if (match.status === 'loading') {
|
|
@@ -2244,7 +2260,7 @@
|
|
|
2244
2260
|
const next = router.buildNext(location);
|
|
2245
2261
|
return router.commitLocation(next, location.replace);
|
|
2246
2262
|
},
|
|
2247
|
-
navigate: async
|
|
2263
|
+
navigate: async _ref8 => {
|
|
2248
2264
|
let {
|
|
2249
2265
|
from,
|
|
2250
2266
|
to = '.',
|
|
@@ -2252,7 +2268,7 @@
|
|
|
2252
2268
|
hash,
|
|
2253
2269
|
replace,
|
|
2254
2270
|
params
|
|
2255
|
-
} =
|
|
2271
|
+
} = _ref8;
|
|
2256
2272
|
// If this link simply reloads the current route,
|
|
2257
2273
|
// make sure it has a new key so it will trigger a data refresh
|
|
2258
2274
|
// If this `to` is a valid external URL, return
|
|
@@ -2276,8 +2292,8 @@
|
|
|
2276
2292
|
params
|
|
2277
2293
|
});
|
|
2278
2294
|
},
|
|
2279
|
-
buildLink:
|
|
2280
|
-
var _preload,
|
|
2295
|
+
buildLink: _ref9 => {
|
|
2296
|
+
var _preload, _ref10;
|
|
2281
2297
|
|
|
2282
2298
|
let {
|
|
2283
2299
|
from,
|
|
@@ -2290,9 +2306,10 @@
|
|
|
2290
2306
|
activeOptions,
|
|
2291
2307
|
preload,
|
|
2292
2308
|
preloadMaxAge: userPreloadMaxAge,
|
|
2309
|
+
preloadGcMaxAge: userPreloadGcMaxAge,
|
|
2293
2310
|
preloadDelay: userPreloadDelay,
|
|
2294
2311
|
disabled
|
|
2295
|
-
} =
|
|
2312
|
+
} = _ref9;
|
|
2296
2313
|
|
|
2297
2314
|
// If this link simply reloads the current route,
|
|
2298
2315
|
// make sure it has a new key so it will trigger a data refresh
|
|
@@ -2315,9 +2332,8 @@
|
|
|
2315
2332
|
replace
|
|
2316
2333
|
};
|
|
2317
2334
|
const next = router.buildNext(nextOpts);
|
|
2318
|
-
preload = (_preload = preload) != null ? _preload : router.options.
|
|
2319
|
-
const
|
|
2320
|
-
const preloadDelay = (_ref8 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultLinkPreloadDelay) != null ? _ref8 : 0; // Compare path/hash for matches
|
|
2335
|
+
preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
|
|
2336
|
+
const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
|
|
2321
2337
|
|
|
2322
2338
|
const pathIsEqual = router.state.location.pathname === next.pathname;
|
|
2323
2339
|
const currentPathSplit = router.state.location.pathname.split('/');
|
|
@@ -2345,9 +2361,10 @@
|
|
|
2345
2361
|
|
|
2346
2362
|
|
|
2347
2363
|
const handleFocus = e => {
|
|
2348
|
-
if (preload
|
|
2349
|
-
router.
|
|
2350
|
-
maxAge:
|
|
2364
|
+
if (preload) {
|
|
2365
|
+
router.preloadRoute(nextOpts, {
|
|
2366
|
+
maxAge: userPreloadMaxAge,
|
|
2367
|
+
gcMaxAge: userPreloadGcMaxAge
|
|
2351
2368
|
});
|
|
2352
2369
|
}
|
|
2353
2370
|
};
|
|
@@ -2355,15 +2372,16 @@
|
|
|
2355
2372
|
const handleEnter = e => {
|
|
2356
2373
|
const target = e.target || {};
|
|
2357
2374
|
|
|
2358
|
-
if (preload
|
|
2375
|
+
if (preload) {
|
|
2359
2376
|
if (target.preloadTimeout) {
|
|
2360
2377
|
return;
|
|
2361
2378
|
}
|
|
2362
2379
|
|
|
2363
2380
|
target.preloadTimeout = setTimeout(() => {
|
|
2364
2381
|
target.preloadTimeout = null;
|
|
2365
|
-
router.
|
|
2366
|
-
maxAge:
|
|
2382
|
+
router.preloadRoute(nextOpts, {
|
|
2383
|
+
maxAge: userPreloadMaxAge,
|
|
2384
|
+
gcMaxAge: userPreloadGcMaxAge
|
|
2367
2385
|
});
|
|
2368
2386
|
}, preloadDelay);
|
|
2369
2387
|
}
|