@remix-run/router 1.3.2 → 1.3.3-pre.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @remix-run/router v1.3.2
2
+ * @remix-run/router v1.3.3-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1491,7 +1491,8 @@
1491
1491
 
1492
1492
  function createRouter(init) {
1493
1493
  invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter");
1494
- let dataRoutes = convertRoutesToDataRoutes(init.routes); // Cleanup function for history
1494
+ let dataRoutes = convertRoutesToDataRoutes(init.routes);
1495
+ let inFlightDataRoutes; // Cleanup function for history
1495
1496
 
1496
1497
  let unlistenHistory = null; // Externally-provided functions to call on all state changes
1497
1498
 
@@ -1727,6 +1728,12 @@
1727
1728
 
1728
1729
 
1729
1730
  let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
1731
+
1732
+ if (inFlightDataRoutes) {
1733
+ dataRoutes = inFlightDataRoutes;
1734
+ inFlightDataRoutes = undefined;
1735
+ }
1736
+
1730
1737
  updateState(_extends({}, newState, {
1731
1738
  // matches, errors, fetchers go through as-is
1732
1739
  actionData,
@@ -1882,8 +1889,9 @@
1882
1889
 
1883
1890
  saveScrollPosition(state.location, state.matches);
1884
1891
  pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
1892
+ let routesToUse = inFlightDataRoutes || dataRoutes;
1885
1893
  let loadingNavigation = opts && opts.overrideNavigation;
1886
- let matches = matchRoutes(dataRoutes, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing
1894
+ let matches = matchRoutes(routesToUse, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing
1887
1895
 
1888
1896
  if (!matches) {
1889
1897
  let error = getInternalRouterError(404, {
@@ -1892,7 +1900,7 @@
1892
1900
  let {
1893
1901
  matches: notFoundMatches,
1894
1902
  route
1895
- } = getShortCircuitMatches(dataRoutes); // Cancel all pending deferred on 404s since we don't keep any routes
1903
+ } = getShortCircuitMatches(routesToUse); // Cancel all pending deferred on 404s since we don't keep any routes
1896
1904
 
1897
1905
  cancelActiveDeferreds();
1898
1906
  completeNavigation(location, {
@@ -2097,7 +2105,8 @@
2097
2105
  formData: loadingNavigation.formData,
2098
2106
  formEncType: loadingNavigation.formEncType
2099
2107
  } : undefined;
2100
- let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches); // Cancel pending deferreds for no-longer-matched routes or routes we're
2108
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2109
+ let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, init.basename, pendingActionData, pendingError); // Cancel pending deferreds for no-longer-matched routes or routes we're
2101
2110
  // about to reload. Note that if this is an action reload we would have
2102
2111
  // already cancelled all pending deferreds so this would be a no-op
2103
2112
 
@@ -2214,7 +2223,8 @@
2214
2223
  }
2215
2224
 
2216
2225
  if (fetchControllers.has(key)) abortFetcher(key);
2217
- let matches = matchRoutes(dataRoutes, href, init.basename);
2226
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2227
+ let matches = matchRoutes(routesToUse, href, init.basename);
2218
2228
 
2219
2229
  if (!matches) {
2220
2230
  setFetcherError(key, routeId, getInternalRouterError(404, {
@@ -2239,9 +2249,7 @@
2239
2249
 
2240
2250
  fetchLoadMatches.set(key, {
2241
2251
  routeId,
2242
- path,
2243
- match,
2244
- matches
2252
+ path
2245
2253
  });
2246
2254
  handleFetcherLoader(key, routeId, path, match, matches, submission);
2247
2255
  } // Call the action for the matched fetcher.submit(), and then handle redirects,
@@ -2328,7 +2336,8 @@
2328
2336
 
2329
2337
  let nextLocation = state.navigation.location || state.location;
2330
2338
  let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
2331
- let matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches;
2339
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2340
+ let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, init.basename) : state.matches;
2332
2341
  invariant(matches, "Didn't find any matches after fetcher action");
2333
2342
  let loadId = ++incrementingLoadId;
2334
2343
  fetchReloadIds.set(key, loadId);
@@ -2341,10 +2350,10 @@
2341
2350
  });
2342
2351
 
2343
2352
  state.fetchers.set(key, loadFetcher);
2344
- let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
2353
+ let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, init.basename, {
2345
2354
  [match.route.id]: actionResult.data
2346
- }, undefined, // No need to send through errors since we short circuit above
2347
- fetchLoadMatches); // Put all revalidating fetchers into the loading state, except for the
2355
+ }, undefined // No need to send through errors since we short circuit above
2356
+ ); // Put all revalidating fetchers into the loading state, except for the
2348
2357
  // current fetcher which we want to keep in it's current loading state which
2349
2358
  // contains it's action submission info + action data
2350
2359
 
@@ -2618,7 +2627,19 @@
2618
2627
  // Call all navigation loaders and revalidating fetcher loaders in parallel,
2619
2628
  // then slice off the results into separate arrays so we can handle them
2620
2629
  // accordingly
2621
- let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f => callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, request.signal), f.match, f.matches, router.basename))]);
2630
+ let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f => {
2631
+ if (f.matches && f.match) {
2632
+ return callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, request.signal), f.match, f.matches, router.basename);
2633
+ } else {
2634
+ let error = {
2635
+ type: ResultType.error,
2636
+ error: getInternalRouterError(404, {
2637
+ pathname: f.path
2638
+ })
2639
+ };
2640
+ return error;
2641
+ }
2642
+ })]);
2622
2643
  let loaderResults = results.slice(0, matchesToLoad.length);
2623
2644
  let fetcherResults = results.slice(matchesToLoad.length);
2624
2645
  await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, request.signal, true)]);
@@ -2853,6 +2874,10 @@
2853
2874
  return null;
2854
2875
  }
2855
2876
 
2877
+ function _internalSetRoutes(newRoutes) {
2878
+ inFlightDataRoutes = newRoutes;
2879
+ }
2880
+
2856
2881
  router = {
2857
2882
  get basename() {
2858
2883
  return init.basename;
@@ -2882,7 +2907,10 @@
2882
2907
  getBlocker,
2883
2908
  deleteBlocker,
2884
2909
  _internalFetchControllers: fetchControllers,
2885
- _internalActiveDeferreds: activeDeferreds
2910
+ _internalActiveDeferreds: activeDeferreds,
2911
+ // TODO: Remove setRoutes, it's temporary to avoid dealing with
2912
+ // updating the tree while validating the update algorithm.
2913
+ _internalSetRoutes
2886
2914
  };
2887
2915
  return router;
2888
2916
  } //#endregion
@@ -3383,7 +3411,7 @@
3383
3411
  return boundaryMatches;
3384
3412
  }
3385
3413
 
3386
- function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
3414
+ function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, basename, pendingActionData, pendingError) {
3387
3415
  let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
3388
3416
  let currentUrl = history.createURL(state.location);
3389
3417
  let nextUrl = history.createURL(location);
@@ -3422,36 +3450,56 @@
3422
3450
  }); // Pick fetcher.loads that need to be revalidated
3423
3451
 
3424
3452
  let revalidatingFetchers = [];
3425
- fetchLoadMatches && fetchLoadMatches.forEach((f, key) => {
3453
+ fetchLoadMatches.forEach((f, key) => {
3454
+ // Don't revalidate if fetcher won't be present in the subsequent render
3426
3455
  if (!matches.some(m => m.route.id === f.routeId)) {
3427
- // This fetcher is not going to be present in the subsequent render so
3428
- // there's no need to revalidate it
3429
3456
  return;
3430
- } else if (cancelledFetcherLoads.includes(key)) {
3431
- // This fetcher was cancelled from a prior action submission - force reload
3457
+ }
3458
+
3459
+ let fetcherMatches = matchRoutes(routesToUse, f.path, basename); // If the fetcher path no longer matches, push it in with null matches so
3460
+ // we can trigger a 404 in callLoadersAndMaybeResolveData
3461
+
3462
+ if (!fetcherMatches) {
3432
3463
  revalidatingFetchers.push(_extends({
3433
3464
  key
3434
- }, f));
3435
- } else {
3436
- // Revalidating fetchers are decoupled from the route matches since they
3437
- // hit a static href, so they _always_ check shouldRevalidate and the
3438
- // default is strictly if a revalidation is explicitly required (action
3439
- // submissions, useRevalidator, X-Remix-Revalidate).
3440
- let shouldRevalidate = shouldRevalidateLoader(f.match, _extends({
3441
- currentUrl,
3442
- currentParams: state.matches[state.matches.length - 1].params,
3443
- nextUrl,
3444
- nextParams: matches[matches.length - 1].params
3445
- }, submission, {
3446
- actionResult,
3447
- defaultShouldRevalidate
3465
+ }, f, {
3466
+ matches: null,
3467
+ match: null
3448
3468
  }));
3469
+ return;
3470
+ }
3449
3471
 
3450
- if (shouldRevalidate) {
3451
- revalidatingFetchers.push(_extends({
3452
- key
3453
- }, f));
3454
- }
3472
+ let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
3473
+
3474
+ if (cancelledFetcherLoads.includes(key)) {
3475
+ revalidatingFetchers.push(_extends({
3476
+ key,
3477
+ matches: fetcherMatches,
3478
+ match: fetcherMatch
3479
+ }, f));
3480
+ return;
3481
+ } // Revalidating fetchers are decoupled from the route matches since they
3482
+ // hit a static href, so they _always_ check shouldRevalidate and the
3483
+ // default is strictly if a revalidation is explicitly required (action
3484
+ // submissions, useRevalidator, X-Remix-Revalidate).
3485
+
3486
+
3487
+ let shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({
3488
+ currentUrl,
3489
+ currentParams: state.matches[state.matches.length - 1].params,
3490
+ nextUrl,
3491
+ nextParams: matches[matches.length - 1].params
3492
+ }, submission, {
3493
+ actionResult,
3494
+ defaultShouldRevalidate
3495
+ }));
3496
+
3497
+ if (shouldRevalidate) {
3498
+ revalidatingFetchers.push(_extends({
3499
+ key,
3500
+ matches: fetcherMatches,
3501
+ match: fetcherMatch
3502
+ }, f));
3455
3503
  }
3456
3504
  });
3457
3505
  return [navigationMatches, revalidatingFetchers];
@@ -3621,9 +3669,13 @@
3621
3669
  }
3622
3670
 
3623
3671
  if (result instanceof DeferredData) {
3672
+ var _result$init, _result$init2;
3673
+
3624
3674
  return {
3625
3675
  type: ResultType.deferred,
3626
- deferredData: result
3676
+ deferredData: result,
3677
+ statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status,
3678
+ headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers)
3627
3679
  };
3628
3680
  }
3629
3681
 
@@ -3760,7 +3812,7 @@
3760
3812
  let result = fetcherResults[index]; // Process fetcher non-redirect errors
3761
3813
 
3762
3814
  if (isErrorResult(result)) {
3763
- let boundaryMatch = findNearestBoundary(state.matches, match.route.id);
3815
+ let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);
3764
3816
 
3765
3817
  if (!(errors && errors[boundaryMatch.route.id])) {
3766
3818
  errors = _extends({}, errors, {
@@ -3807,7 +3859,9 @@
3807
3859
  if (newLoaderData[id] !== undefined) {
3808
3860
  mergedLoaderData[id] = newLoaderData[id];
3809
3861
  }
3810
- } else if (loaderData[id] !== undefined) {
3862
+ } else if (loaderData[id] !== undefined && match.route.loader) {
3863
+ // Preserve existing keys not included in newLoaderData and where a loader
3864
+ // wasn't removed by HMR
3811
3865
  mergedLoaderData[id] = loaderData[id];
3812
3866
  }
3813
3867
 
@@ -3944,7 +3998,14 @@
3944
3998
  async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) {
3945
3999
  for (let index = 0; index < results.length; index++) {
3946
4000
  let result = results[index];
3947
- let match = matchesToLoad[index];
4001
+ let match = matchesToLoad[index]; // If we don't have a match, then we can have a deferred result to do
4002
+ // anything with. This is for revalidating fetchers where the route was
4003
+ // removed during HMR
4004
+
4005
+ if (!match) {
4006
+ continue;
4007
+ }
4008
+
3948
4009
  let currentMatch = currentMatches.find(m => m.route.id === match.route.id);
3949
4010
  let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;
3950
4011
 
@@ -4037,6 +4098,7 @@
4037
4098
  exports.UNSAFE_DeferredData = DeferredData;
4038
4099
  exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes;
4039
4100
  exports.UNSAFE_getPathContributingMatches = getPathContributingMatches;
4101
+ exports.UNSAFE_invariant = invariant;
4040
4102
  exports.createBrowserHistory = createBrowserHistory;
4041
4103
  exports.createHashHistory = createHashHistory;
4042
4104
  exports.createMemoryHistory = createMemoryHistory;
@@ -4047,7 +4109,6 @@
4047
4109
  exports.generatePath = generatePath;
4048
4110
  exports.getStaticContextFromError = getStaticContextFromError;
4049
4111
  exports.getToPathname = getToPathname;
4050
- exports.invariant = invariant;
4051
4112
  exports.isRouteErrorResponse = isRouteErrorResponse;
4052
4113
  exports.joinPaths = joinPaths;
4053
4114
  exports.json = json;