@tanstack/router-core 0.0.1-alpha.7 → 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.
@@ -81,9 +81,10 @@ interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
81
81
  stringifySearch?: SearchSerializer;
82
82
  parseSearch?: SearchParser;
83
83
  filterRoutes?: FilterRoutesFn;
84
- defaultLinkPreload?: false | 'intent';
85
- defaultLinkPreloadMaxAge?: number;
86
- defaultLinkPreloadDelay?: number;
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, loaderOpts: {
197
- maxAge: number;
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: () => Promise<void>;
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
- const maxAge = (_ref = (_routeMatch$options$l = routeMatch.options.loaderMaxAge) != null ? _routeMatch$options$l : router.options.defaultLoaderMaxAge) != null ? _ref : 0;
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
- defaultLinkPreloadDelay: 50
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, loaderOpts) {
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,32 +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(); // If the match doesn't have a loader, don't attempt to load it
2181
+ match.__.validate(); // If this is a preload, add it to the preload cache
2164
2182
 
2165
2183
 
2166
- if (!match.hasLoaders()) {
2167
- return;
2168
- } // If this is a preload, add it to the preload cache
2169
-
2170
-
2171
- if (loaderOpts != null && loaderOpts.preload && (loaderOpts == null ? void 0 : loaderOpts.maxAge) > 0) {
2184
+ if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
2172
2185
  // If the match is currently active, don't preload it
2173
2186
  if (router.state.matches.find(d => d.matchId === match.matchId)) {
2174
2187
  return;
2175
2188
  }
2176
2189
 
2177
2190
  router.matchCache[match.matchId] = {
2178
- gc: now + loaderOpts.maxAge,
2179
- // TODO: Should this use the route's maxAge?
2191
+ gc: now + loaderOpts.gcMaxAge,
2180
2192
  match
2181
2193
  };
2182
2194
  } // If the match is invalid, errored or idle, trigger it to load
2183
2195
 
2184
2196
 
2185
2197
  if (match.status === 'success' && match.getIsInvalid() || match.status === 'error' || match.status === 'idle') {
2186
- match.load();
2198
+ const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
2199
+ match.load({
2200
+ maxAge
2201
+ });
2187
2202
  }
2188
2203
 
2189
2204
  if (match.status === 'loading') {
@@ -2245,7 +2260,7 @@
2245
2260
  const next = router.buildNext(location);
2246
2261
  return router.commitLocation(next, location.replace);
2247
2262
  },
2248
- navigate: async _ref4 => {
2263
+ navigate: async _ref8 => {
2249
2264
  let {
2250
2265
  from,
2251
2266
  to = '.',
@@ -2253,7 +2268,7 @@
2253
2268
  hash,
2254
2269
  replace,
2255
2270
  params
2256
- } = _ref4;
2271
+ } = _ref8;
2257
2272
  // If this link simply reloads the current route,
2258
2273
  // make sure it has a new key so it will trigger a data refresh
2259
2274
  // If this `to` is a valid external URL, return
@@ -2277,8 +2292,8 @@
2277
2292
  params
2278
2293
  });
2279
2294
  },
2280
- buildLink: _ref5 => {
2281
- var _preload, _ref6, _ref7, _ref8;
2295
+ buildLink: _ref9 => {
2296
+ var _preload, _ref10;
2282
2297
 
2283
2298
  let {
2284
2299
  from,
@@ -2291,9 +2306,10 @@
2291
2306
  activeOptions,
2292
2307
  preload,
2293
2308
  preloadMaxAge: userPreloadMaxAge,
2309
+ preloadGcMaxAge: userPreloadGcMaxAge,
2294
2310
  preloadDelay: userPreloadDelay,
2295
2311
  disabled
2296
- } = _ref5;
2312
+ } = _ref9;
2297
2313
 
2298
2314
  // If this link simply reloads the current route,
2299
2315
  // make sure it has a new key so it will trigger a data refresh
@@ -2316,9 +2332,8 @@
2316
2332
  replace
2317
2333
  };
2318
2334
  const next = router.buildNext(nextOpts);
2319
- preload = (_preload = preload) != null ? _preload : router.options.defaultLinkPreload;
2320
- const preloadMaxAge = (_ref6 = (_ref7 = userPreloadMaxAge != null ? userPreloadMaxAge : router.options.defaultLinkPreloadMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0;
2321
- 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
2322
2337
 
2323
2338
  const pathIsEqual = router.state.location.pathname === next.pathname;
2324
2339
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -2346,9 +2361,10 @@
2346
2361
 
2347
2362
 
2348
2363
  const handleFocus = e => {
2349
- if (preload && preloadMaxAge > 0) {
2350
- router.loadRoute(nextOpts, {
2351
- maxAge: preloadMaxAge
2364
+ if (preload) {
2365
+ router.preloadRoute(nextOpts, {
2366
+ maxAge: userPreloadMaxAge,
2367
+ gcMaxAge: userPreloadGcMaxAge
2352
2368
  });
2353
2369
  }
2354
2370
  };
@@ -2356,15 +2372,16 @@
2356
2372
  const handleEnter = e => {
2357
2373
  const target = e.target || {};
2358
2374
 
2359
- if (preload && preloadMaxAge > 0) {
2375
+ if (preload) {
2360
2376
  if (target.preloadTimeout) {
2361
2377
  return;
2362
2378
  }
2363
2379
 
2364
2380
  target.preloadTimeout = setTimeout(() => {
2365
2381
  target.preloadTimeout = null;
2366
- router.loadRoute(nextOpts, {
2367
- maxAge: preloadMaxAge
2382
+ router.preloadRoute(nextOpts, {
2383
+ maxAge: userPreloadMaxAge,
2384
+ gcMaxAge: userPreloadGcMaxAge
2368
2385
  });
2369
2386
  }, preloadDelay);
2370
2387
  }