@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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # `@remix-run/router`
2
2
 
3
+ ## 1.3.3-pre.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Change `invariant` to an `UNSAFE_` export since it's only intended for internal use ([#10066](https://github.com/remix-run/react-router/pull/10066))
8
+ - Ensure status code and headers are maintained for `defer` loader responses in `createStaticHandler`'s `query()` method ([#10077](https://github.com/remix-run/react-router/pull/10077))
9
+ - Add internal API for custom HMR implementations ([#9996](https://github.com/remix-run/react-router/pull/9996))
10
+
3
11
  ## 1.3.2
4
12
 
5
13
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export type { ActionFunction, ActionFunctionArgs, AgnosticDataIndexRouteObject, AgnosticDataNonIndexRouteObject, AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticIndexRouteObject, AgnosticNonIndexRouteObject, AgnosticRouteMatch, AgnosticRouteObject, TrackedPromise, FormEncType, FormMethod, JsonFunction, LoaderFunction, LoaderFunctionArgs, ParamParseKey, Params, PathMatch, PathPattern, RedirectFunction, ShouldRevalidateFunction, Submission, } from "./utils";
2
2
  export { AbortedDeferredError, ErrorResponse, defer, generatePath, getToPathname, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, redirect, resolvePath, resolveTo, stripBasename, warning, } from "./utils";
3
3
  export type { BrowserHistory, BrowserHistoryOptions, HashHistory, HashHistoryOptions, History, InitialEntry, Location, MemoryHistory, MemoryHistoryOptions, Path, To, } from "./history";
4
- export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, invariant, parsePath, } from "./history";
4
+ export { Action, createBrowserHistory, createPath, createHashHistory, createMemoryHistory, parsePath, } from "./history";
5
5
  export * from "./router";
6
6
  /** @internal */
7
7
  export { DeferredData as UNSAFE_DeferredData, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, getPathContributingMatches as UNSAFE_getPathContributingMatches, } from "./utils";
8
+ export { invariant as UNSAFE_invariant } from "./history";
@@ -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
  *
@@ -1489,7 +1489,8 @@ const isServer = !isBrowser; //#endregion
1489
1489
 
1490
1490
  function createRouter(init) {
1491
1491
  invariant(init.routes.length > 0, "You must provide a non-empty routes array to createRouter");
1492
- let dataRoutes = convertRoutesToDataRoutes(init.routes); // Cleanup function for history
1492
+ let dataRoutes = convertRoutesToDataRoutes(init.routes);
1493
+ let inFlightDataRoutes; // Cleanup function for history
1493
1494
 
1494
1495
  let unlistenHistory = null; // Externally-provided functions to call on all state changes
1495
1496
 
@@ -1725,6 +1726,12 @@ function createRouter(init) {
1725
1726
 
1726
1727
 
1727
1728
  let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
1729
+
1730
+ if (inFlightDataRoutes) {
1731
+ dataRoutes = inFlightDataRoutes;
1732
+ inFlightDataRoutes = undefined;
1733
+ }
1734
+
1728
1735
  updateState(_extends({}, newState, {
1729
1736
  // matches, errors, fetchers go through as-is
1730
1737
  actionData,
@@ -1880,8 +1887,9 @@ function createRouter(init) {
1880
1887
 
1881
1888
  saveScrollPosition(state.location, state.matches);
1882
1889
  pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
1890
+ let routesToUse = inFlightDataRoutes || dataRoutes;
1883
1891
  let loadingNavigation = opts && opts.overrideNavigation;
1884
- let matches = matchRoutes(dataRoutes, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing
1892
+ let matches = matchRoutes(routesToUse, location, init.basename); // Short circuit with a 404 on the root error boundary if we match nothing
1885
1893
 
1886
1894
  if (!matches) {
1887
1895
  let error = getInternalRouterError(404, {
@@ -1890,7 +1898,7 @@ function createRouter(init) {
1890
1898
  let {
1891
1899
  matches: notFoundMatches,
1892
1900
  route
1893
- } = getShortCircuitMatches(dataRoutes); // Cancel all pending deferred on 404s since we don't keep any routes
1901
+ } = getShortCircuitMatches(routesToUse); // Cancel all pending deferred on 404s since we don't keep any routes
1894
1902
 
1895
1903
  cancelActiveDeferreds();
1896
1904
  completeNavigation(location, {
@@ -2095,7 +2103,8 @@ function createRouter(init) {
2095
2103
  formData: loadingNavigation.formData,
2096
2104
  formEncType: loadingNavigation.formEncType
2097
2105
  } : undefined;
2098
- 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
2106
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2107
+ 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
2099
2108
  // about to reload. Note that if this is an action reload we would have
2100
2109
  // already cancelled all pending deferreds so this would be a no-op
2101
2110
 
@@ -2212,7 +2221,8 @@ function createRouter(init) {
2212
2221
  }
2213
2222
 
2214
2223
  if (fetchControllers.has(key)) abortFetcher(key);
2215
- let matches = matchRoutes(dataRoutes, href, init.basename);
2224
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2225
+ let matches = matchRoutes(routesToUse, href, init.basename);
2216
2226
 
2217
2227
  if (!matches) {
2218
2228
  setFetcherError(key, routeId, getInternalRouterError(404, {
@@ -2237,9 +2247,7 @@ function createRouter(init) {
2237
2247
 
2238
2248
  fetchLoadMatches.set(key, {
2239
2249
  routeId,
2240
- path,
2241
- match,
2242
- matches
2250
+ path
2243
2251
  });
2244
2252
  handleFetcherLoader(key, routeId, path, match, matches, submission);
2245
2253
  } // Call the action for the matched fetcher.submit(), and then handle redirects,
@@ -2326,7 +2334,8 @@ function createRouter(init) {
2326
2334
 
2327
2335
  let nextLocation = state.navigation.location || state.location;
2328
2336
  let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);
2329
- let matches = state.navigation.state !== "idle" ? matchRoutes(dataRoutes, state.navigation.location, init.basename) : state.matches;
2337
+ let routesToUse = inFlightDataRoutes || dataRoutes;
2338
+ let matches = state.navigation.state !== "idle" ? matchRoutes(routesToUse, state.navigation.location, init.basename) : state.matches;
2330
2339
  invariant(matches, "Didn't find any matches after fetcher action");
2331
2340
  let loadId = ++incrementingLoadId;
2332
2341
  fetchReloadIds.set(key, loadId);
@@ -2339,10 +2348,10 @@ function createRouter(init) {
2339
2348
  });
2340
2349
 
2341
2350
  state.fetchers.set(key, loadFetcher);
2342
- let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, {
2351
+ let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, init.basename, {
2343
2352
  [match.route.id]: actionResult.data
2344
- }, undefined, // No need to send through errors since we short circuit above
2345
- fetchLoadMatches); // Put all revalidating fetchers into the loading state, except for the
2353
+ }, undefined // No need to send through errors since we short circuit above
2354
+ ); // Put all revalidating fetchers into the loading state, except for the
2346
2355
  // current fetcher which we want to keep in it's current loading state which
2347
2356
  // contains it's action submission info + action data
2348
2357
 
@@ -2616,7 +2625,19 @@ function createRouter(init) {
2616
2625
  // Call all navigation loaders and revalidating fetcher loaders in parallel,
2617
2626
  // then slice off the results into separate arrays so we can handle them
2618
2627
  // accordingly
2619
- 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))]);
2628
+ let results = await Promise.all([...matchesToLoad.map(match => callLoaderOrAction("loader", request, match, matches, router.basename)), ...fetchersToLoad.map(f => {
2629
+ if (f.matches && f.match) {
2630
+ return callLoaderOrAction("loader", createClientSideRequest(init.history, f.path, request.signal), f.match, f.matches, router.basename);
2631
+ } else {
2632
+ let error = {
2633
+ type: ResultType.error,
2634
+ error: getInternalRouterError(404, {
2635
+ pathname: f.path
2636
+ })
2637
+ };
2638
+ return error;
2639
+ }
2640
+ })]);
2620
2641
  let loaderResults = results.slice(0, matchesToLoad.length);
2621
2642
  let fetcherResults = results.slice(matchesToLoad.length);
2622
2643
  await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, request.signal, false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, request.signal, true)]);
@@ -2851,6 +2872,10 @@ function createRouter(init) {
2851
2872
  return null;
2852
2873
  }
2853
2874
 
2875
+ function _internalSetRoutes(newRoutes) {
2876
+ inFlightDataRoutes = newRoutes;
2877
+ }
2878
+
2854
2879
  router = {
2855
2880
  get basename() {
2856
2881
  return init.basename;
@@ -2880,7 +2905,10 @@ function createRouter(init) {
2880
2905
  getBlocker,
2881
2906
  deleteBlocker,
2882
2907
  _internalFetchControllers: fetchControllers,
2883
- _internalActiveDeferreds: activeDeferreds
2908
+ _internalActiveDeferreds: activeDeferreds,
2909
+ // TODO: Remove setRoutes, it's temporary to avoid dealing with
2910
+ // updating the tree while validating the update algorithm.
2911
+ _internalSetRoutes
2884
2912
  };
2885
2913
  return router;
2886
2914
  } //#endregion
@@ -3381,7 +3409,7 @@ function getLoaderMatchesUntilBoundary(matches, boundaryId) {
3381
3409
  return boundaryMatches;
3382
3410
  }
3383
3411
 
3384
- function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, pendingActionData, pendingError, fetchLoadMatches) {
3412
+ function getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, routesToUse, basename, pendingActionData, pendingError) {
3385
3413
  let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;
3386
3414
  let currentUrl = history.createURL(state.location);
3387
3415
  let nextUrl = history.createURL(location);
@@ -3420,36 +3448,56 @@ function getMatchesToLoad(history, state, matches, submission, location, isReval
3420
3448
  }); // Pick fetcher.loads that need to be revalidated
3421
3449
 
3422
3450
  let revalidatingFetchers = [];
3423
- fetchLoadMatches && fetchLoadMatches.forEach((f, key) => {
3451
+ fetchLoadMatches.forEach((f, key) => {
3452
+ // Don't revalidate if fetcher won't be present in the subsequent render
3424
3453
  if (!matches.some(m => m.route.id === f.routeId)) {
3425
- // This fetcher is not going to be present in the subsequent render so
3426
- // there's no need to revalidate it
3427
3454
  return;
3428
- } else if (cancelledFetcherLoads.includes(key)) {
3429
- // This fetcher was cancelled from a prior action submission - force reload
3455
+ }
3456
+
3457
+ let fetcherMatches = matchRoutes(routesToUse, f.path, basename); // If the fetcher path no longer matches, push it in with null matches so
3458
+ // we can trigger a 404 in callLoadersAndMaybeResolveData
3459
+
3460
+ if (!fetcherMatches) {
3430
3461
  revalidatingFetchers.push(_extends({
3431
3462
  key
3432
- }, f));
3433
- } else {
3434
- // Revalidating fetchers are decoupled from the route matches since they
3435
- // hit a static href, so they _always_ check shouldRevalidate and the
3436
- // default is strictly if a revalidation is explicitly required (action
3437
- // submissions, useRevalidator, X-Remix-Revalidate).
3438
- let shouldRevalidate = shouldRevalidateLoader(f.match, _extends({
3439
- currentUrl,
3440
- currentParams: state.matches[state.matches.length - 1].params,
3441
- nextUrl,
3442
- nextParams: matches[matches.length - 1].params
3443
- }, submission, {
3444
- actionResult,
3445
- defaultShouldRevalidate
3463
+ }, f, {
3464
+ matches: null,
3465
+ match: null
3446
3466
  }));
3467
+ return;
3468
+ }
3447
3469
 
3448
- if (shouldRevalidate) {
3449
- revalidatingFetchers.push(_extends({
3450
- key
3451
- }, f));
3452
- }
3470
+ let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
3471
+
3472
+ if (cancelledFetcherLoads.includes(key)) {
3473
+ revalidatingFetchers.push(_extends({
3474
+ key,
3475
+ matches: fetcherMatches,
3476
+ match: fetcherMatch
3477
+ }, f));
3478
+ return;
3479
+ } // Revalidating fetchers are decoupled from the route matches since they
3480
+ // hit a static href, so they _always_ check shouldRevalidate and the
3481
+ // default is strictly if a revalidation is explicitly required (action
3482
+ // submissions, useRevalidator, X-Remix-Revalidate).
3483
+
3484
+
3485
+ let shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({
3486
+ currentUrl,
3487
+ currentParams: state.matches[state.matches.length - 1].params,
3488
+ nextUrl,
3489
+ nextParams: matches[matches.length - 1].params
3490
+ }, submission, {
3491
+ actionResult,
3492
+ defaultShouldRevalidate
3493
+ }));
3494
+
3495
+ if (shouldRevalidate) {
3496
+ revalidatingFetchers.push(_extends({
3497
+ key,
3498
+ matches: fetcherMatches,
3499
+ match: fetcherMatch
3500
+ }, f));
3453
3501
  }
3454
3502
  });
3455
3503
  return [navigationMatches, revalidatingFetchers];
@@ -3619,9 +3667,13 @@ async function callLoaderOrAction(type, request, match, matches, basename, isSta
3619
3667
  }
3620
3668
 
3621
3669
  if (result instanceof DeferredData) {
3670
+ var _result$init, _result$init2;
3671
+
3622
3672
  return {
3623
3673
  type: ResultType.deferred,
3624
- deferredData: result
3674
+ deferredData: result,
3675
+ statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status,
3676
+ headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers)
3625
3677
  };
3626
3678
  }
3627
3679
 
@@ -3758,7 +3810,7 @@ function processLoaderData(state, matches, matchesToLoad, results, pendingError,
3758
3810
  let result = fetcherResults[index]; // Process fetcher non-redirect errors
3759
3811
 
3760
3812
  if (isErrorResult(result)) {
3761
- let boundaryMatch = findNearestBoundary(state.matches, match.route.id);
3813
+ let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);
3762
3814
 
3763
3815
  if (!(errors && errors[boundaryMatch.route.id])) {
3764
3816
  errors = _extends({}, errors, {
@@ -3805,7 +3857,9 @@ function mergeLoaderData(loaderData, newLoaderData, matches, errors) {
3805
3857
  if (newLoaderData[id] !== undefined) {
3806
3858
  mergedLoaderData[id] = newLoaderData[id];
3807
3859
  }
3808
- } else if (loaderData[id] !== undefined) {
3860
+ } else if (loaderData[id] !== undefined && match.route.loader) {
3861
+ // Preserve existing keys not included in newLoaderData and where a loader
3862
+ // wasn't removed by HMR
3809
3863
  mergedLoaderData[id] = loaderData[id];
3810
3864
  }
3811
3865
 
@@ -3942,7 +3996,14 @@ function isMutationMethod(method) {
3942
3996
  async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) {
3943
3997
  for (let index = 0; index < results.length; index++) {
3944
3998
  let result = results[index];
3945
- let match = matchesToLoad[index];
3999
+ let match = matchesToLoad[index]; // If we don't have a match, then we can have a deferred result to do
4000
+ // anything with. This is for revalidating fetchers where the route was
4001
+ // removed during HMR
4002
+
4003
+ if (!match) {
4004
+ continue;
4005
+ }
4006
+
3946
4007
  let currentMatch = currentMatches.find(m => m.route.id === match.route.id);
3947
4008
  let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;
3948
4009
 
@@ -4035,6 +4096,7 @@ exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL;
4035
4096
  exports.UNSAFE_DeferredData = DeferredData;
4036
4097
  exports.UNSAFE_convertRoutesToDataRoutes = convertRoutesToDataRoutes;
4037
4098
  exports.UNSAFE_getPathContributingMatches = getPathContributingMatches;
4099
+ exports.UNSAFE_invariant = invariant;
4038
4100
  exports.createBrowserHistory = createBrowserHistory;
4039
4101
  exports.createHashHistory = createHashHistory;
4040
4102
  exports.createMemoryHistory = createMemoryHistory;
@@ -4045,7 +4107,6 @@ exports.defer = defer;
4045
4107
  exports.generatePath = generatePath;
4046
4108
  exports.getStaticContextFromError = getStaticContextFromError;
4047
4109
  exports.getToPathname = getToPathname;
4048
- exports.invariant = invariant;
4049
4110
  exports.isRouteErrorResponse = isRouteErrorResponse;
4050
4111
  exports.joinPaths = joinPaths;
4051
4112
  exports.json = json;