@remix-run/router 1.4.0 → 1.5.0-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.4.0
2
+ * @remix-run/router v1.5.0-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1490,7 +1490,12 @@
1490
1490
  let manifest = {}; // Routes in tree format for matching
1491
1491
 
1492
1492
  let dataRoutes = convertRoutesToDataRoutes(init.routes, detectErrorBoundary, undefined, manifest);
1493
- let inFlightDataRoutes; // Cleanup function for history
1493
+ let inFlightDataRoutes; // Config driven behavior flags
1494
+
1495
+ let future = _extends({
1496
+ v7_normalizeFormMethod: false
1497
+ }, init.future); // Cleanup function for history
1498
+
1494
1499
 
1495
1500
  let unlistenHistory = null; // Externally-provided functions to call on all state changes
1496
1501
 
@@ -1654,35 +1659,16 @@
1654
1659
  }
1655
1660
 
1656
1661
  return startNavigation(historyAction, location);
1657
- });
1662
+ }); // Kick off initial data load if needed. Use Pop to avoid modifying history
1663
+ // Note we don't do any handling of lazy here. For SPA's it'll get handled
1664
+ // in the normal navigation flow. For SSR it's expected that lazy modules are
1665
+ // resolved prior to router creation since we can't go into a fallbackElement
1666
+ // UI for SSR'd apps
1658
1667
 
1659
- if (state.initialized) {
1660
- return router;
1661
- }
1662
-
1663
- let lazyMatches = state.matches.filter(m => m.route.lazy);
1664
-
1665
- if (lazyMatches.length === 0) {
1666
- // Kick off initial data load if needed. Use Pop to avoid modifying history
1668
+ if (!state.initialized) {
1667
1669
  startNavigation(exports.Action.Pop, state.location);
1668
- return router;
1669
- } // Load lazy modules, then kick off initial data load if needed
1670
-
1671
-
1672
- let lazyPromises = lazyMatches.map(m => loadLazyRouteModule(m.route, detectErrorBoundary, manifest));
1673
- Promise.all(lazyPromises).then(() => {
1674
- let initialized = !state.matches.some(m => m.route.loader) || init.hydrationData != null;
1670
+ }
1675
1671
 
1676
- if (initialized) {
1677
- // We already have required loaderData so we can just set initialized
1678
- updateState({
1679
- initialized: true
1680
- });
1681
- } else {
1682
- // We still need to kick off initial data loads
1683
- startNavigation(exports.Action.Pop, state.location);
1684
- }
1685
- });
1686
1672
  return router;
1687
1673
  } // Clean up a router and it's side effects
1688
1674
 
@@ -1799,7 +1785,7 @@
1799
1785
  path,
1800
1786
  submission,
1801
1787
  error
1802
- } = normalizeNavigateOptions(to, opts);
1788
+ } = normalizeNavigateOptions(to, future, opts);
1803
1789
  let currentLocation = state.location;
1804
1790
  let nextLocation = createLocation(state.location, path, opts && opts.state); // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded
1805
1791
  // URL from window.location, so we need to encode it here so the behavior
@@ -1991,7 +1977,7 @@
1991
1977
  shortCircuited,
1992
1978
  loaderData,
1993
1979
  errors
1994
- } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.replace, pendingActionData, pendingError);
1980
+ } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, pendingActionData, pendingError);
1995
1981
 
1996
1982
  if (shortCircuited) {
1997
1983
  return;
@@ -2104,7 +2090,7 @@
2104
2090
  // errors, etc.
2105
2091
 
2106
2092
 
2107
- async function handleLoaders(request, location, matches, overrideNavigation, submission, replace, pendingActionData, pendingError) {
2093
+ async function handleLoaders(request, location, matches, overrideNavigation, submission, fetcherSubmission, replace, pendingActionData, pendingError) {
2108
2094
  // Figure out the right navigation we want to use for data loading
2109
2095
  let loadingNavigation = overrideNavigation;
2110
2096
 
@@ -2123,7 +2109,7 @@
2123
2109
  // we have it on the loading navigation so use that if available
2124
2110
 
2125
2111
 
2126
- let activeSubmission = submission ? submission : loadingNavigation.formMethod && loadingNavigation.formAction && loadingNavigation.formData && loadingNavigation.formEncType ? {
2112
+ let activeSubmission = submission || fetcherSubmission ? submission || fetcherSubmission : loadingNavigation.formMethod && loadingNavigation.formAction && loadingNavigation.formData && loadingNavigation.formEncType ? {
2127
2113
  formMethod: loadingNavigation.formMethod,
2128
2114
  formAction: loadingNavigation.formAction,
2129
2115
  formData: loadingNavigation.formData,
@@ -2260,7 +2246,7 @@
2260
2246
  let {
2261
2247
  path,
2262
2248
  submission
2263
- } = normalizeNavigateOptions(href, opts, true);
2249
+ } = normalizeNavigateOptions(href, future, opts, true);
2264
2250
  let match = getTargetMatch(matches, path);
2265
2251
  pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
2266
2252
 
@@ -2340,6 +2326,7 @@
2340
2326
  fetchers: new Map(state.fetchers)
2341
2327
  });
2342
2328
  return startRedirectNavigation(state, actionResult, {
2329
+ submission,
2343
2330
  isFetchActionRedirect: true
2344
2331
  });
2345
2332
  } // Process any non-redirect errors thrown
@@ -2630,6 +2617,22 @@
2630
2617
  // Preserve this flag across redirects
2631
2618
  preventScrollReset: pendingPreventScrollReset
2632
2619
  });
2620
+ } else if (isFetchActionRedirect) {
2621
+ // For a fetch action redirect, we kick off a new loading navigation
2622
+ // without the fetcher submission, but we send it along for shouldRevalidate
2623
+ await startNavigation(redirectHistoryAction, redirectLocation, {
2624
+ overrideNavigation: {
2625
+ state: "loading",
2626
+ location: redirectLocation,
2627
+ formMethod: undefined,
2628
+ formAction: undefined,
2629
+ formEncType: undefined,
2630
+ formData: undefined
2631
+ },
2632
+ fetcherSubmission: submission,
2633
+ // Preserve this flag across redirects
2634
+ preventScrollReset: pendingPreventScrollReset
2635
+ });
2633
2636
  } else {
2634
2637
  // Otherwise, we kick off a new loading navigation, preserving the
2635
2638
  // submission info for the duration of this navigation
@@ -2975,11 +2978,11 @@
2975
2978
  requestContext
2976
2979
  } = _temp2 === void 0 ? {} : _temp2;
2977
2980
  let url = new URL(request.url);
2978
- let method = request.method.toLowerCase();
2981
+ let method = request.method;
2979
2982
  let location = createLocation("", createPath(url), null, "default");
2980
2983
  let matches = matchRoutes(dataRoutes, location, basename); // SSR supports HEAD requests while SPA doesn't
2981
2984
 
2982
- if (!isValidMethod(method) && method !== "head") {
2985
+ if (!isValidMethod(method) && method !== "HEAD") {
2983
2986
  let error = getInternalRouterError(405, {
2984
2987
  method
2985
2988
  });
@@ -3067,11 +3070,11 @@
3067
3070
  requestContext
3068
3071
  } = _temp3 === void 0 ? {} : _temp3;
3069
3072
  let url = new URL(request.url);
3070
- let method = request.method.toLowerCase();
3073
+ let method = request.method;
3071
3074
  let location = createLocation("", createPath(url), null, "default");
3072
3075
  let matches = matchRoutes(dataRoutes, location, basename); // SSR supports HEAD requests while SPA doesn't
3073
3076
 
3074
- if (!isValidMethod(method) && method !== "head" && method !== "options") {
3077
+ if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
3075
3078
  throw getInternalRouterError(405, {
3076
3079
  method
3077
3080
  });
@@ -3364,7 +3367,7 @@
3364
3367
  // URLSearchParams so they behave identically to links with query params
3365
3368
 
3366
3369
 
3367
- function normalizeNavigateOptions(to, opts, isFetcher) {
3370
+ function normalizeNavigateOptions(to, future, opts, isFetcher) {
3368
3371
  if (isFetcher === void 0) {
3369
3372
  isFetcher = false;
3370
3373
  }
@@ -3390,8 +3393,9 @@
3390
3393
  let submission;
3391
3394
 
3392
3395
  if (opts.formData) {
3396
+ let formMethod = opts.formMethod || "get";
3393
3397
  submission = {
3394
- formMethod: opts.formMethod || "get",
3398
+ formMethod: future.v7_normalizeFormMethod ? formMethod.toUpperCase() : formMethod.toLowerCase(),
3395
3399
  formAction: stripHashFromPath(path),
3396
3400
  formEncType: opts && opts.formEncType || "application/x-www-form-urlencoded",
3397
3401
  formData: opts.formData
@@ -3831,7 +3835,10 @@
3831
3835
  formMethod,
3832
3836
  formEncType,
3833
3837
  formData
3834
- } = submission;
3838
+ } = submission; // Didn't think we needed this but it turns out unlike other methods, patch
3839
+ // won't be properly normalized to uppercase and results in a 405 error.
3840
+ // See: https://fetch.spec.whatwg.org/#concept-method
3841
+
3835
3842
  init.method = formMethod.toUpperCase();
3836
3843
  init.body = formEncType === "application/x-www-form-urlencoded" ? convertFormDataToSearchParams(formData) : formData;
3837
3844
  } // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)
@@ -4120,11 +4127,11 @@
4120
4127
  }
4121
4128
 
4122
4129
  function isValidMethod(method) {
4123
- return validRequestMethods.has(method);
4130
+ return validRequestMethods.has(method.toLowerCase());
4124
4131
  }
4125
4132
 
4126
4133
  function isMutationMethod(method) {
4127
- return validMutationMethods.has(method);
4134
+ return validMutationMethods.has(method.toLowerCase());
4128
4135
  }
4129
4136
 
4130
4137
  async function resolveDeferredResults(currentMatches, matchesToLoad, results, signal, isFetcher, currentLoaderData) {