Ignore:
Timestamp:
12/12/24 17:06:06 (5 weeks ago)
Author:
stefan toskovski <stefantoska84@…>
Branches:
main
Parents:
d565449
Message:

Pred finalna verzija

File:
1 edited

Legend:

Unmodified
Added
Removed
  • imaps-frontend/node_modules/@remix-run/router/dist/router.js

    rd565449 r0c6b92a  
    11/**
    2  * @remix-run/router v1.19.0
     2 * @remix-run/router v1.21.0
    33 *
    44 * Copyright (c) Remix Software Inc.
     
    513513 * Matches the given routes to a location and returns the match data.
    514514 *
    515  * @see https://reactrouter.com/utils/match-routes
     515 * @see https://reactrouter.com/v6/utils/match-routes
    516516 */
    517517function matchRoutes(routes, locationArg, basename) {
     
    738738 * Returns a path with params interpolated.
    739739 *
    740  * @see https://reactrouter.com/utils/generate-path
     740 * @see https://reactrouter.com/v6/utils/generate-path
    741741 */
    742742function generatePath(originalPath, params) {
     
    778778 * the match.
    779779 *
    780  * @see https://reactrouter.com/utils/match-path
     780 * @see https://reactrouter.com/v6/utils/match-path
    781781 */
    782782function matchPath(pattern, pathname) {
     
    890890 * Returns a resolved path object relative to the given pathname.
    891891 *
    892  * @see https://reactrouter.com/utils/resolve-path
     892 * @see https://reactrouter.com/v6/utils/resolve-path
    893893 */
    894894function resolvePath(to, fromPathname) {
     
    10441044 * This is a shortcut for creating `application/json` responses. Converts `data`
    10451045 * to JSON and sets the `Content-Type` header.
     1046 *
     1047 * @deprecated The `json` method is deprecated in favor of returning raw objects.
     1048 * This method will be removed in v7.
    10461049 */
    10471050const json = function json(data, init) {
     
    12121215  return value._data;
    12131216}
     1217/**
     1218 * @deprecated The `defer` method is deprecated in favor of returning raw
     1219 * objects. This method will be removed in v7.
     1220 */
    12141221const defer = function defer(data, init) {
    12151222  if (init === void 0) {
     
    13631370  let inFlightDataRoutes;
    13641371  let basename = init.basename || "/";
    1365   let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;
    1366   let patchRoutesOnMissImpl = init.unstable_patchRoutesOnMiss;
     1372  let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
     1373  let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
    13671374  // Config driven behavior flags
    13681375  let future = _extends({
     
    13931400  let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
    13941401  let initialErrors = null;
    1395   if (initialMatches == null && !patchRoutesOnMissImpl) {
     1402  if (initialMatches == null && !patchRoutesOnNavigationImpl) {
    13961403    // If we do not match a user-provided-route, fall back to the root
    13971404    // to allow the error boundary to take over
     
    14081415    };
    14091416  }
    1410   // In SPA apps, if the user provided a patchRoutesOnMiss implementation and
     1417  // In SPA apps, if the user provided a patchRoutesOnNavigation implementation and
    14111418  // our initial match is a splat route, clear them out so we run through lazy
    14121419  // discovery on hydration in case there's a more accurate lazy route match.
     
    14251432    initialMatches = [];
    14261433    // If partial hydration and fog of war is enabled, we will be running
    1427     // `patchRoutesOnMiss` during hydration so include any partial matches as
     1434    // `patchRoutesOnNavigation` during hydration so include any partial matches as
    14281435    // the initial matches so we can properly render `HydrateFallback`'s
    14291436    if (future.v7_partialHydration) {
     
    14461453    let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
    14471454    let errors = init.hydrationData ? init.hydrationData.errors : null;
    1448     let isRouteInitialized = m => {
    1449       // No loader, nothing to initialize
    1450       if (!m.route.loader) {
    1451         return true;
    1452       }
    1453       // Explicitly opting-in to running on hydration
    1454       if (typeof m.route.loader === "function" && m.route.loader.hydrate === true) {
    1455         return false;
    1456       }
    1457       // Otherwise, initialized if hydrated with data or an error
    1458       return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined;
    1459     };
    14601455    // If errors exist, don't consider routes below the boundary
    14611456    if (errors) {
    14621457      let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined);
    1463       initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);
     1458      initialized = initialMatches.slice(0, idx + 1).every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));
    14641459    } else {
    1465       initialized = initialMatches.every(isRouteInitialized);
     1460      initialized = initialMatches.every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));
    14661461    }
    14671462  } else {
     
    15421537  // we don't need to update UI state if they change
    15431538  let blockerFunctions = new Map();
    1544   // Map of pending patchRoutesOnMiss() promises (keyed by path/matches) so
    1545   // that we only kick them off once for a given combo
    1546   let pendingPatchRoutes = new Map();
    15471539  // Flag to ignore the next history update, so we can revert the URL change on
    15481540  // a POP navigation that was blocked by the user without touching router state
    1549   let ignoreNextHistoryUpdate = false;
     1541  let unblockBlockerHistoryUpdate = undefined;
    15501542  // Initialize the router, all side effects should be kicked off from here.
    15511543  // Implemented as a Fluent API for ease of:
     
    15621554      // Ignore this event if it was just us resetting the URL from a
    15631555      // blocked POP navigation
    1564       if (ignoreNextHistoryUpdate) {
    1565         ignoreNextHistoryUpdate = false;
     1556      if (unblockBlockerHistoryUpdate) {
     1557        unblockBlockerHistoryUpdate();
     1558        unblockBlockerHistoryUpdate = undefined;
    15661559        return;
    15671560      }
     
    15741567      if (blockerKey && delta != null) {
    15751568        // Restore the URL to match the current UI, but don't update router state
    1576         ignoreNextHistoryUpdate = true;
     1569        let nextHistoryUpdatePromise = new Promise(resolve => {
     1570          unblockBlockerHistoryUpdate = resolve;
     1571        });
    15771572        init.history.go(delta * -1);
    15781573        // Put the blocker into a blocked state
     
    15871582              location
    15881583            });
    1589             // Re-do the same POP navigation we just blocked
    1590             init.history.go(delta);
     1584            // Re-do the same POP navigation we just blocked, after the url
     1585            // restoration is also complete.  See:
     1586            // https://github.com/remix-run/react-router/issues/11613
     1587            nextHistoryUpdatePromise.then(() => init.history.go(delta));
    15911588          },
    15921589          reset() {
     
    16691666    [...subscribers].forEach(subscriber => subscriber(state, {
    16701667      deletedFetchers: deletedFetchersKeys,
    1671       unstable_viewTransitionOpts: opts.viewTransitionOpts,
    1672       unstable_flushSync: opts.flushSync === true
     1668      viewTransitionOpts: opts.viewTransitionOpts,
     1669      flushSync: opts.flushSync === true
    16731670    }));
    16741671    // Remove idle fetchers from state since we only care about in-flight fetchers.
     
    18191816    }
    18201817    let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
    1821     let flushSync = (opts && opts.unstable_flushSync) === true;
     1818    let flushSync = (opts && opts.flushSync) === true;
    18221819    let blockerKey = shouldBlockNavigation({
    18231820      currentLocation,
     
    18571854      preventScrollReset,
    18581855      replace: opts && opts.replace,
    1859       enableViewTransition: opts && opts.unstable_viewTransition,
     1856      enableViewTransition: opts && opts.viewTransition,
    18601857      flushSync
    18611858    });
     
    18871884    // revalidation so that history correctly updates once the navigation completes
    18881885    startNavigation(pendingAction || state.historyAction, state.navigation.location, {
    1889       overrideNavigation: state.navigation
     1886      overrideNavigation: state.navigation,
     1887      // Proxy through any rending view transition
     1888      enableViewTransition: pendingViewTransitionEnabled === true
    18901889    });
    18911890  }
     
    19351934    // mutation submission.
    19361935    //
    1937     // Ignore on initial page loads because since the initial load will always
     1936    // Ignore on initial page loads because since the initial hydration will always
    19381937    // be "same hash".  For example, on /page#hash and submit a <Form method="post">
    19391938    // which will default to a navigation to /page
     
    20352034        };
    20362035      } else if (discoverResult.type === "error") {
    2037         let {
    2038           boundaryId,
    2039           error
    2040         } = handleDiscoverRouteError(location.pathname, discoverResult);
     2036        let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
    20412037        return {
    20422038          matches: discoverResult.partialMatches,
    20432039          pendingActionResult: [boundaryId, {
    20442040            type: ResultType.error,
    2045             error
     2041            error: discoverResult.error
    20462042          }]
    20472043        };
     
    20762072      };
    20772073    } else {
    2078       let results = await callDataStrategy("action", request, [actionMatch], matches);
    2079       result = results[0];
     2074      let results = await callDataStrategy("action", state, request, [actionMatch], matches, null);
     2075      result = results[actionMatch.route.id];
    20802076      if (request.signal.aborted) {
    20812077        return {
     
    20952091        replace = location === state.location.pathname + state.location.search;
    20962092      }
    2097       await startRedirectNavigation(request, result, {
     2093      await startRedirectNavigation(request, result, true, {
    20982094        submission,
    20992095        replace
     
    21672163        };
    21682164      } else if (discoverResult.type === "error") {
    2169         let {
    2170           boundaryId,
    2171           error
    2172         } = handleDiscoverRouteError(location.pathname, discoverResult);
     2165        let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
    21732166        return {
    21742167          matches: discoverResult.partialMatches,
    21752168          loaderData: {},
    21762169          errors: {
    2177             [boundaryId]: error
     2170            [boundaryId]: discoverResult.error
    21782171          }
    21792172        };
     
    22392232    }
    22402233    revalidatingFetchers.forEach(rf => {
    2241       if (fetchControllers.has(rf.key)) {
    2242         abortFetcher(rf.key);
    2243       }
     2234      abortFetcher(rf.key);
    22442235      if (rf.controller) {
    22452236        // Fetchers use an independent AbortController so that aborting a fetcher
     
    22572248      loaderResults,
    22582249      fetcherResults
    2259     } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request);
     2250    } = await callLoadersAndMaybeResolveData(state, matches, matchesToLoad, revalidatingFetchers, request);
    22602251    if (request.signal.aborted) {
    22612252      return {
     
    22712262    revalidatingFetchers.forEach(rf => fetchControllers.delete(rf.key));
    22722263    // If any loaders returned a redirect Response, start a new REPLACE navigation
    2273     let redirect = findRedirect([...loaderResults, ...fetcherResults]);
     2264    let redirect = findRedirect(loaderResults);
    22742265    if (redirect) {
    2275       if (redirect.idx >= matchesToLoad.length) {
    2276         // If this redirect came from a fetcher make sure we mark it in
    2277         // fetchRedirectIds so it doesn't get revalidated on the next set of
    2278         // loader executions
    2279         let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;
    2280         fetchRedirectIds.add(fetcherKey);
    2281       }
    2282       await startRedirectNavigation(request, redirect.result, {
     2266      await startRedirectNavigation(request, redirect.result, true, {
     2267        replace
     2268      });
     2269      return {
     2270        shortCircuited: true
     2271      };
     2272    }
     2273    redirect = findRedirect(fetcherResults);
     2274    if (redirect) {
     2275      // If this redirect came from a fetcher make sure we mark it in
     2276      // fetchRedirectIds so it doesn't get revalidated on the next set of
     2277      // loader executions
     2278      fetchRedirectIds.add(redirect.key);
     2279      await startRedirectNavigation(request, redirect.result, true, {
    22832280        replace
    22842281      });
     
    22912288      loaderData,
    22922289      errors
    2293     } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds);
     2290    } = processLoaderData(state, matches, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds);
    22942291    // Wire up subscribers to update loaderData as promises settle
    22952292    activeDeferreds.forEach((deferredData, routeId) => {
     
    23032300      });
    23042301    });
    2305     // During partial hydration, preserve SSR errors for routes that don't re-run
     2302    // Preserve SSR errors during partial hydration
    23062303    if (future.v7_partialHydration && initialHydration && state.errors) {
    2307       Object.entries(state.errors).filter(_ref2 => {
    2308         let [id] = _ref2;
    2309         return !matchesToLoad.some(m => m.route.id === id);
    2310       }).forEach(_ref3 => {
    2311         let [routeId, error] = _ref3;
    2312         errors = Object.assign(errors || {}, {
    2313           [routeId]: error
    2314         });
    2315       });
     2304      errors = _extends({}, state.errors, errors);
    23162305    }
    23172306    let updatedFetchers = markFetchRedirectsDone();
     
    23552344      throw new Error("router.fetch() was called during the server render, but it shouldn't be. " + "You are likely calling a useFetcher() method in the body of your component. " + "Try moving it to a useEffect or a callback.");
    23562345    }
    2357     if (fetchControllers.has(key)) abortFetcher(key);
    2358     let flushSync = (opts && opts.unstable_flushSync) === true;
     2346    abortFetcher(key);
     2347    let flushSync = (opts && opts.flushSync) === true;
    23592348    let routesToUse = inFlightDataRoutes || dataRoutes;
    23602349    let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative);
     
    23842373    }
    23852374    let match = getTargetMatch(matches, path);
    2386     pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
     2375    let preventScrollReset = (opts && opts.preventScrollReset) === true;
    23872376    if (submission && isMutationMethod(submission.formMethod)) {
    2388       handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission);
     2377      handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
    23892378      return;
    23902379    }
     
    23952384      path
    23962385    });
    2397     handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission);
     2386    handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
    23982387  }
    23992388  // Call the action for the matched fetcher.submit(), and then handle redirects,
    24002389  // errors, and revalidation
    2401   async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, submission) {
     2390  async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {
    24022391    interruptActiveLoads();
    24032392    fetchLoadMatches.delete(key);
     
    24312420        return;
    24322421      } else if (discoverResult.type === "error") {
    2433         let {
    2434           error
    2435         } = handleDiscoverRouteError(path, discoverResult);
    2436         setFetcherError(key, routeId, error, {
     2422        setFetcherError(key, routeId, discoverResult.error, {
    24372423          flushSync
    24382424        });
     
    24562442    fetchControllers.set(key, abortController);
    24572443    let originatingLoadId = incrementingLoadId;
    2458     let actionResults = await callDataStrategy("action", fetchRequest, [match], requestMatches);
    2459     let actionResult = actionResults[0];
     2444    let actionResults = await callDataStrategy("action", state, fetchRequest, [match], requestMatches, key);
     2445    let actionResult = actionResults[match.route.id];
    24602446    if (fetchRequest.signal.aborted) {
    24612447      // We can delete this so long as we weren't aborted by our own fetcher
     
    24882474          fetchRedirectIds.add(key);
    24892475          updateFetcherState(key, getLoadingFetcher(submission));
    2490           return startRedirectNavigation(fetchRequest, actionResult, {
    2491             fetcherSubmission: submission
     2476          return startRedirectNavigation(fetchRequest, actionResult, false, {
     2477            fetcherSubmission: submission,
     2478            preventScrollReset
    24922479          });
    24932480        }
     
    25242511      let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined);
    25252512      state.fetchers.set(staleKey, revalidatingFetcher);
    2526       if (fetchControllers.has(staleKey)) {
    2527         abortFetcher(staleKey);
    2528       }
     2513      abortFetcher(staleKey);
    25292514      if (rf.controller) {
    25302515        fetchControllers.set(staleKey, rf.controller);
     
    25392524      loaderResults,
    25402525      fetcherResults
    2541     } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);
     2526    } = await callLoadersAndMaybeResolveData(state, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);
    25422527    if (abortController.signal.aborted) {
    25432528      return;
     
    25472532    fetchControllers.delete(key);
    25482533    revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));
    2549     let redirect = findRedirect([...loaderResults, ...fetcherResults]);
     2534    let redirect = findRedirect(loaderResults);
    25502535    if (redirect) {
    2551       if (redirect.idx >= matchesToLoad.length) {
    2552         // If this redirect came from a fetcher make sure we mark it in
    2553         // fetchRedirectIds so it doesn't get revalidated on the next set of
    2554         // loader executions
    2555         let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;
    2556         fetchRedirectIds.add(fetcherKey);
    2557       }
    2558       return startRedirectNavigation(revalidationRequest, redirect.result);
     2536      return startRedirectNavigation(revalidationRequest, redirect.result, false, {
     2537        preventScrollReset
     2538      });
     2539    }
     2540    redirect = findRedirect(fetcherResults);
     2541    if (redirect) {
     2542      // If this redirect came from a fetcher make sure we mark it in
     2543      // fetchRedirectIds so it doesn't get revalidated on the next set of
     2544      // loader executions
     2545      fetchRedirectIds.add(redirect.key);
     2546      return startRedirectNavigation(revalidationRequest, redirect.result, false, {
     2547        preventScrollReset
     2548      });
    25592549    }
    25602550    // Process and commit output from loaders
     
    25622552      loaderData,
    25632553      errors
    2564     } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);
     2554    } = processLoaderData(state, matches, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);
    25652555    // Since we let revalidations complete even if the submitting fetcher was
    25662556    // deleted, only put it back to idle if it hasn't been deleted
     
    25952585  }
    25962586  // Call the matched loader for fetcher.load(), handling redirects, errors, etc.
    2597   async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, submission) {
     2587  async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {
    25982588    let existingFetcher = state.fetchers.get(key);
    25992589    updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), {
     
    26072597        return;
    26082598      } else if (discoverResult.type === "error") {
    2609         let {
    2610           error
    2611         } = handleDiscoverRouteError(path, discoverResult);
    2612         setFetcherError(key, routeId, error, {
     2599        setFetcherError(key, routeId, discoverResult.error, {
    26132600          flushSync
    26142601        });
     
    26292616    fetchControllers.set(key, abortController);
    26302617    let originatingLoadId = incrementingLoadId;
    2631     let results = await callDataStrategy("loader", fetchRequest, [match], matches);
    2632     let result = results[0];
     2618    let results = await callDataStrategy("loader", state, fetchRequest, [match], matches, key);
     2619    let result = results[match.route.id];
    26332620    // Deferred isn't supported for fetcher loads, await everything and treat it
    26342621    // as a normal load.  resolveDeferredData will return undefined if this
     
    26612648      } else {
    26622649        fetchRedirectIds.add(key);
    2663         await startRedirectNavigation(fetchRequest, result);
     2650        await startRedirectNavigation(fetchRequest, result, false, {
     2651          preventScrollReset
     2652        });
    26642653        return;
    26652654      }
     
    26932682   * the history action from the original navigation (PUSH or REPLACE).
    26942683   */
    2695   async function startRedirectNavigation(request, redirect, _temp2) {
     2684  async function startRedirectNavigation(request, redirect, isNavigation, _temp2) {
    26962685    let {
    26972686      submission,
    26982687      fetcherSubmission,
     2688      preventScrollReset,
    26992689      replace
    27002690    } = _temp2 === void 0 ? {} : _temp2;
     
    27532743          formAction: location
    27542744        }),
    2755         // Preserve this flag across redirects
    2756         preventScrollReset: pendingPreventScrollReset
     2745        // Preserve these flags across redirects
     2746        preventScrollReset: preventScrollReset || pendingPreventScrollReset,
     2747        enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined
    27572748      });
    27582749    } else {
     
    27642755        // Send fetcher submissions through for shouldRevalidate
    27652756        fetcherSubmission,
    2766         // Preserve this flag across redirects
    2767         preventScrollReset: pendingPreventScrollReset
     2757        // Preserve these flags across redirects
     2758        preventScrollReset: preventScrollReset || pendingPreventScrollReset,
     2759        enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined
    27682760      });
    27692761    }
     
    27712763  // Utility wrapper for calling dataStrategy client-side without having to
    27722764  // pass around the manifest, mapRouteProperties, etc.
    2773   async function callDataStrategy(type, request, matchesToLoad, matches) {
     2765  async function callDataStrategy(type, state, request, matchesToLoad, matches, fetcherKey) {
     2766    let results;
     2767    let dataResults = {};
    27742768    try {
    2775       let results = await callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties);
    2776       return await Promise.all(results.map((result, i) => {
    2777         if (isRedirectHandlerResult(result)) {
    2778           let response = result.result;
    2779           return {
    2780             type: ResultType.redirect,
    2781             response: normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath)
    2782           };
    2783         }
    2784         return convertHandlerResultToDataResult(result);
    2785       }));
     2769      results = await callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties);
    27862770    } catch (e) {
    27872771      // If the outer dataStrategy method throws, just return the error for all
    27882772      // matches - and it'll naturally bubble to the root
    2789       return matchesToLoad.map(() => ({
    2790         type: ResultType.error,
    2791         error: e
    2792       }));
    2793     }
    2794   }
    2795   async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) {
    2796     let [loaderResults, ...fetcherResults] = await Promise.all([matchesToLoad.length ? callDataStrategy("loader", request, matchesToLoad, matches) : [], ...fetchersToLoad.map(f => {
     2773      matchesToLoad.forEach(m => {
     2774        dataResults[m.route.id] = {
     2775          type: ResultType.error,
     2776          error: e
     2777        };
     2778      });
     2779      return dataResults;
     2780    }
     2781    for (let [routeId, result] of Object.entries(results)) {
     2782      if (isRedirectDataStrategyResultResult(result)) {
     2783        let response = result.result;
     2784        dataResults[routeId] = {
     2785          type: ResultType.redirect,
     2786          response: normalizeRelativeRoutingRedirectResponse(response, request, routeId, matches, basename, future.v7_relativeSplatPath)
     2787        };
     2788      } else {
     2789        dataResults[routeId] = await convertDataStrategyResultToDataResult(result);
     2790      }
     2791    }
     2792    return dataResults;
     2793  }
     2794  async function callLoadersAndMaybeResolveData(state, matches, matchesToLoad, fetchersToLoad, request) {
     2795    let currentMatches = state.matches;
     2796    // Kick off loaders and fetchers in parallel
     2797    let loaderResultsPromise = callDataStrategy("loader", state, request, matchesToLoad, matches, null);
     2798    let fetcherResultsPromise = Promise.all(fetchersToLoad.map(async f => {
    27972799      if (f.matches && f.match && f.controller) {
    2798         let fetcherRequest = createClientSideRequest(init.history, f.path, f.controller.signal);
    2799         return callDataStrategy("loader", fetcherRequest, [f.match], f.matches).then(r => r[0]);
     2800        let results = await callDataStrategy("loader", state, createClientSideRequest(init.history, f.path, f.controller.signal), [f.match], f.matches, f.key);
     2801        let result = results[f.match.route.id];
     2802        // Fetcher results are keyed by fetcher key from here on out, not routeId
     2803        return {
     2804          [f.key]: result
     2805        };
    28002806      } else {
    28012807        return Promise.resolve({
    2802           type: ResultType.error,
    2803           error: getInternalRouterError(404, {
    2804             pathname: f.path
    2805           })
     2808          [f.key]: {
     2809            type: ResultType.error,
     2810            error: getInternalRouterError(404, {
     2811              pathname: f.path
     2812            })
     2813          }
    28062814        });
    28072815      }
    2808     })]);
    2809     await Promise.all([resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(() => request.signal), false, state.loaderData), resolveDeferredResults(currentMatches, fetchersToLoad.map(f => f.match), fetcherResults, fetchersToLoad.map(f => f.controller ? f.controller.signal : null), true)]);
     2816    }));
     2817    let loaderResults = await loaderResultsPromise;
     2818    let fetcherResults = (await fetcherResultsPromise).reduce((acc, r) => Object.assign(acc, r), {});
     2819    await Promise.all([resolveNavigationDeferredResults(matches, loaderResults, request.signal, currentMatches, state.loaderData), resolveFetcherDeferredResults(matches, fetcherResults, fetchersToLoad)]);
    28102820    return {
    28112821      loaderResults,
     
    28232833      if (fetchControllers.has(key)) {
    28242834        cancelledFetcherLoads.add(key);
    2825         abortFetcher(key);
    2826       }
     2835      }
     2836      abortFetcher(key);
    28272837    });
    28282838  }
     
    28972907  function abortFetcher(key) {
    28982908    let controller = fetchControllers.get(key);
    2899     invariant(controller, "Expected fetch controller: " + key);
    2900     controller.abort();
    2901     fetchControllers.delete(key);
     2909    if (controller) {
     2910      controller.abort();
     2911      fetchControllers.delete(key);
     2912    }
    29022913  }
    29032914  function markFetchersDone(keys) {
     
    29622973    });
    29632974  }
    2964   function shouldBlockNavigation(_ref4) {
     2975  function shouldBlockNavigation(_ref2) {
    29652976    let {
    29662977      currentLocation,
    29672978      nextLocation,
    29682979      historyAction
    2969     } = _ref4;
     2980    } = _ref2;
    29702981    if (blockerFunctions.size === 0) {
    29712982      return;
     
    30113022    };
    30123023  }
    3013   function handleDiscoverRouteError(pathname, discoverResult) {
    3014     return {
    3015       boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,
    3016       error: getInternalRouterError(400, {
    3017         type: "route-discovery",
    3018         pathname,
    3019         message: discoverResult.error != null && "message" in discoverResult.error ? discoverResult.error : String(discoverResult.error)
    3020       })
    3021     };
    3022   }
    30233024  function cancelActiveDeferreds(predicate) {
    30243025    let cancelledRouteIds = [];
     
    30833084  }
    30843085  function checkFogOfWar(matches, routesToUse, pathname) {
    3085     if (patchRoutesOnMissImpl) {
     3086    if (patchRoutesOnNavigationImpl) {
    30863087      if (!matches) {
    30873088        let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
     
    30913092        };
    30923093      } else {
    3093         let leafRoute = matches[matches.length - 1].route;
    3094         if (leafRoute.path && (leafRoute.path === "*" || leafRoute.path.endsWith("/*"))) {
    3095           // If we matched a splat, it might only be because we haven't yet fetched
    3096           // the children that would match with a higher score, so let's fetch
    3097           // around and find out
     3094        if (Object.keys(matches[0].params).length > 0) {
     3095          // If we matched a dynamic param or a splat, it might only be because
     3096          // we haven't yet discovered other routes that would match with a
     3097          // higher score.  Call patchRoutesOnNavigation just to be sure
    30983098          let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
    30993099          return {
     
    31103110  }
    31113111  async function discoverRoutes(matches, pathname, signal) {
     3112    if (!patchRoutesOnNavigationImpl) {
     3113      return {
     3114        type: "success",
     3115        matches
     3116      };
     3117    }
    31123118    let partialMatches = matches;
    3113     let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null;
    31143119    while (true) {
    31153120      let isNonHMR = inFlightDataRoutes == null;
    31163121      let routesToUse = inFlightDataRoutes || dataRoutes;
     3122      let localManifest = manifest;
    31173123      try {
    3118         await loadLazyRouteChildren(patchRoutesOnMissImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal);
     3124        await patchRoutesOnNavigationImpl({
     3125          path: pathname,
     3126          matches: partialMatches,
     3127          patch: (routeId, children) => {
     3128            if (signal.aborted) return;
     3129            patchRoutesImpl(routeId, children, routesToUse, localManifest, mapRouteProperties);
     3130          }
     3131        });
    31193132      } catch (e) {
    31203133        return {
     
    31303143        // HMR will already update the identity and reflow when it lands
    31313144        // `inFlightDataRoutes` in `completeNavigation`
    3132         if (isNonHMR) {
     3145        if (isNonHMR && !signal.aborted) {
    31333146          dataRoutes = [...dataRoutes];
    31343147        }
     
    31403153      }
    31413154      let newMatches = matchRoutes(routesToUse, pathname, basename);
    3142       let matchedSplat = false;
    31433155      if (newMatches) {
    3144         let leafRoute = newMatches[newMatches.length - 1].route;
    3145         if (leafRoute.index) {
    3146           // If we found an index route, we can stop
    3147           return {
    3148             type: "success",
    3149             matches: newMatches
    3150           };
    3151         }
    3152         if (leafRoute.path && leafRoute.path.length > 0) {
    3153           if (leafRoute.path === "*") {
    3154             // If we found a splat route, we can't be sure there's not a
    3155             // higher-scoring route down some partial matches trail so we need
    3156             // to check that out
    3157             matchedSplat = true;
    3158           } else {
    3159             // If we found a non-splat route, we can stop
    3160             return {
    3161               type: "success",
    3162               matches: newMatches
    3163             };
    3164           }
    3165         }
    3166       }
    3167       let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
    3168       // If we are no longer partially matching anything, this was either a
    3169       // legit splat match above, or it's a 404.  Also avoid loops if the
    3170       // second pass results in the same partial matches
    3171       if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) {
    31723156        return {
    31733157          type: "success",
    3174           matches: matchedSplat ? newMatches : null
     3158          matches: newMatches
    31753159        };
    31763160      }
    3177       partialMatches = newPartialMatches;
    3178       route = partialMatches[partialMatches.length - 1].route;
    3179       if (route.path === "*") {
    3180         // The splat is still our most accurate partial, so run with it
     3161      let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
     3162      // Avoid loops if the second pass results in the same partial matches
     3163      if (!newPartialMatches || partialMatches.length === newPartialMatches.length && partialMatches.every((m, i) => m.route.id === newPartialMatches[i].route.id)) {
    31813164        return {
    31823165          type: "success",
    3183           matches: partialMatches
     3166          matches: null
    31843167        };
    31853168      }
     3169      partialMatches = newPartialMatches;
    31863170    }
    31873171  }
     
    33013285      requestContext,
    33023286      skipLoaderErrorBubbling,
    3303       unstable_dataStrategy
     3287      dataStrategy
    33043288    } = _temp3 === void 0 ? {} : _temp3;
    33053289    let url = new URL(request.url);
     
    33533337      };
    33543338    }
    3355     let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, skipLoaderErrorBubbling === true, null);
     3339    let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, skipLoaderErrorBubbling === true, null);
    33563340    if (isResponse(result)) {
    33573341      return result;
     
    33953379      routeId,
    33963380      requestContext,
    3397       unstable_dataStrategy
     3381      dataStrategy
    33983382    } = _temp4 === void 0 ? {} : _temp4;
    33993383    let url = new URL(request.url);
     
    34233407      });
    34243408    }
    3425     let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, false, match);
     3409    let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, false, match);
    34263410    if (isResponse(result)) {
    34273411      return result;
     
    34493433    return undefined;
    34503434  }
    3451   async function queryImpl(request, location, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch) {
     3435  async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch) {
    34523436    invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal");
    34533437    try {
    34543438      if (isMutationMethod(request.method.toLowerCase())) {
    3455         let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch != null);
     3439        let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch != null);
    34563440        return result;
    34573441      }
    3458       let result = await loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch);
     3442      let result = await loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch);
    34593443      return isResponse(result) ? result : _extends({}, result, {
    34603444        actionData: null,
     
    34633447    } catch (e) {
    34643448      // If the user threw/returned a Response in callLoaderOrAction for a
    3465       // `queryRoute` call, we throw the `HandlerResult` to bail out early
     3449      // `queryRoute` call, we throw the `DataStrategyResult` to bail out early
    34663450      // and then return or throw the raw Response here accordingly
    3467       if (isHandlerResult(e) && isResponse(e.result)) {
     3451      if (isDataStrategyResult(e) && isResponse(e.result)) {
    34683452        if (e.type === ResultType.error) {
    34693453          throw e.result;
     
    34793463    }
    34803464  }
    3481   async function submit(request, matches, actionMatch, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
     3465  async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
    34823466    let result;
    34833467    if (!actionMatch.route.action && !actionMatch.route.lazy) {
     
    34953479      };
    34963480    } else {
    3497       let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, unstable_dataStrategy);
    3498       result = results[0];
     3481      let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, dataStrategy);
     3482      result = results[actionMatch.route.id];
    34993483      if (request.signal.aborted) {
    35003484        throwStaticHandlerAbortedError(request, isRouteRequest, future);
     
    35563540      // to call and will commit it when we complete the navigation
    35573541      let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
    3558       let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);
     3542      let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);
    35593543      // action status codes take precedence over loader status codes
    35603544      return _extends({}, context, {
     
    35663550      });
    35673551    }
    3568     let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null);
     3552    let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null);
    35693553    return _extends({}, context, {
    35703554      actionData: {
     
    35793563    });
    35803564  }
    3581   async function loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
     3565  async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
    35823566    let isRouteRequest = routeMatch != null;
    35833567    // Short circuit if we have no loaders to run (queryRoute())
     
    36073591      };
    36083592    }
    3609     let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy);
     3593    let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy);
    36103594    if (request.signal.aborted) {
    36113595      throwStaticHandlerAbortedError(request, isRouteRequest, future);
     
    36133597    // Process and commit output from loaders
    36143598    let activeDeferreds = new Map();
    3615     let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling);
     3599    let context = processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling);
    36163600    // Add a null for any non-loader matches for proper revalidation on the client
    36173601    let executedLoaders = new Set(matchesToLoad.map(match => match.route.id));
     
    36283612  // Utility wrapper for calling dataStrategy server-side without having to
    36293613  // pass around the manifest, mapRouteProperties, etc.
    3630   async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy) {
    3631     let results = await callDataStrategyImpl(unstable_dataStrategy || defaultDataStrategy, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext);
    3632     return await Promise.all(results.map((result, i) => {
    3633       if (isRedirectHandlerResult(result)) {
     3614  async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy) {
     3615    let results = await callDataStrategyImpl(dataStrategy || defaultDataStrategy, type, null, request, matchesToLoad, matches, null, manifest, mapRouteProperties, requestContext);
     3616    let dataResults = {};
     3617    await Promise.all(matches.map(async match => {
     3618      if (!(match.route.id in results)) {
     3619        return;
     3620      }
     3621      let result = results[match.route.id];
     3622      if (isRedirectDataStrategyResultResult(result)) {
    36343623        let response = result.result;
    36353624        // Throw redirects and let the server handle them with an HTTP redirect
    3636         throw normalizeRelativeRoutingRedirectResponse(response, request, matchesToLoad[i].route.id, matches, basename, future.v7_relativeSplatPath);
     3625        throw normalizeRelativeRoutingRedirectResponse(response, request, match.route.id, matches, basename, future.v7_relativeSplatPath);
    36373626      }
    36383627      if (isResponse(result.result) && isRouteRequest) {
     
    36413630        throw result;
    36423631      }
    3643       return convertHandlerResultToDataResult(result);
     3632      dataResults[match.route.id] = await convertDataStrategyResultToDataResult(result);
    36443633    }));
     3634    return dataResults;
    36453635  }
    36463636  return {
     
    37043694    path.hash = location.hash;
    37053695  }
    3706   // Add an ?index param for matched index routes if we don't already have one
    3707   if ((to == null || to === "" || to === ".") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) {
    3708     path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
     3696  // Account for `?index` params when routing to the current location
     3697  if ((to == null || to === "" || to === ".") && activeRouteMatch) {
     3698    let nakedIndex = hasNakedIndexQuery(path.search);
     3699    if (activeRouteMatch.route.index && !nakedIndex) {
     3700      // Add one when we're targeting an index route
     3701      path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
     3702    } else if (!activeRouteMatch.route.index && nakedIndex) {
     3703      // Remove existing ones when we're not
     3704      let params = new URLSearchParams(path.search);
     3705      let indexValues = params.getAll("index");
     3706      params.delete("index");
     3707      indexValues.filter(v => v).forEach(v => params.append("index", v));
     3708      let qs = params.toString();
     3709      path.search = qs ? "?" + qs : "";
     3710    }
    37093711  }
    37103712  // If we're operating within a basename, prepend it to the pathname.  If
     
    37523754      let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ?
    37533755      // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
    3754       Array.from(opts.body.entries()).reduce((acc, _ref5) => {
    3755         let [name, value] = _ref5;
     3756      Array.from(opts.body.entries()).reduce((acc, _ref3) => {
     3757        let [name, value] = _ref3;
    37563758        return "" + acc + name + "=" + value + "\n";
    37573759      }, "") : String(opts.body);
     
    38413843  };
    38423844}
    3843 // Filter out all routes below any caught error as they aren't going to
     3845// Filter out all routes at/below any caught error as they aren't going to
    38443846// render so we don't need to load them
    3845 function getLoaderMatchesUntilBoundary(matches, boundaryId) {
    3846   let boundaryMatches = matches;
    3847   if (boundaryId) {
    3848     let index = matches.findIndex(m => m.route.id === boundaryId);
    3849     if (index >= 0) {
    3850       boundaryMatches = matches.slice(0, index);
    3851     }
    3852   }
    3853   return boundaryMatches;
    3854 }
    3855 function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
     3847function getLoaderMatchesUntilBoundary(matches, boundaryId, includeBoundary) {
     3848  if (includeBoundary === void 0) {
     3849    includeBoundary = false;
     3850  }
     3851  let index = matches.findIndex(m => m.route.id === boundaryId);
     3852  if (index >= 0) {
     3853    return matches.slice(0, includeBoundary ? index + 1 : index);
     3854  }
     3855  return matches;
     3856}
     3857function getMatchesToLoad(history, state, matches, submission, location, initialHydration, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
    38563858  let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined;
    38573859  let currentUrl = history.createURL(state.location);
    38583860  let nextUrl = history.createURL(location);
    38593861  // Pick navigation matches that are net-new or qualify for revalidation
    3860   let boundaryId = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[0] : undefined;
    3861   let boundaryMatches = boundaryId ? getLoaderMatchesUntilBoundary(matches, boundaryId) : matches;
     3862  let boundaryMatches = matches;
     3863  if (initialHydration && state.errors) {
     3864    // On initial hydration, only consider matches up to _and including_ the boundary.
     3865    // This is inclusive to handle cases where a server loader ran successfully,
     3866    // a child server loader bubbled up to this route, but this route has
     3867    // `clientLoader.hydrate` so we want to still run the `clientLoader` so that
     3868    // we have a complete version of `loaderData`
     3869    boundaryMatches = getLoaderMatchesUntilBoundary(matches, Object.keys(state.errors)[0], true);
     3870  } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {
     3871    // If an action threw an error, we call loaders up to, but not including the
     3872    // boundary
     3873    boundaryMatches = getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]);
     3874  }
    38623875  // Don't revalidate loaders by default after action 4xx/5xx responses
    38633876  // when the flag is enabled.  They can still opt-into revalidation via
     
    38763889      return false;
    38773890    }
    3878     if (isInitialLoad) {
    3879       if (typeof route.loader !== "function" || route.loader.hydrate) {
    3880         return true;
    3881       }
    3882       return state.loaderData[route.id] === undefined && (
    3883       // Don't re-run if the loader ran and threw an error
    3884       !state.errors || state.errors[route.id] === undefined);
     3891    if (initialHydration) {
     3892      return shouldLoadRouteOnHydration(route, state.loaderData, state.errors);
    38853893    }
    38863894    // Always call the loader on new route instances and pending defer cancellations
     
    39133921  fetchLoadMatches.forEach((f, key) => {
    39143922    // Don't revalidate:
    3915     //  - on initial load (shouldn't be any fetchers then anyway)
     3923    //  - on initial hydration (shouldn't be any fetchers then anyway)
    39163924    //  - if fetcher won't be present in the subsequent render
    39173925    //    - no longer matches the URL (v7_fetcherPersist=false)
    39183926    //    - was unmounted but persisted due to v7_fetcherPersist=true
    3919     if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {
     3927    if (initialHydration || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {
    39203928      return;
    39213929    }
     
    39813989  return [navigationMatches, revalidatingFetchers];
    39823990}
     3991function shouldLoadRouteOnHydration(route, loaderData, errors) {
     3992  // We dunno if we have a loader - gotta find out!
     3993  if (route.lazy) {
     3994    return true;
     3995  }
     3996  // No loader, nothing to initialize
     3997  if (!route.loader) {
     3998    return false;
     3999  }
     4000  let hasData = loaderData != null && loaderData[route.id] !== undefined;
     4001  let hasError = errors != null && errors[route.id] !== undefined;
     4002  // Don't run if we error'd during SSR
     4003  if (!hasData && hasError) {
     4004    return false;
     4005  }
     4006  // Explicitly opting-in to running on hydration
     4007  if (typeof route.loader === "function" && route.loader.hydrate === true) {
     4008    return true;
     4009  }
     4010  // Otherwise, run if we're not yet initialized with anything
     4011  return !hasData && !hasError;
     4012}
    39834013function isNewLoader(currentLoaderData, currentMatch, match) {
    39844014  let isNew =
     
    40124042  return arg.defaultShouldRevalidate;
    40134043}
    4014 /**
    4015  * Idempotent utility to execute patchRoutesOnMiss() to lazily load route
    4016  * definitions and update the routes/routeManifest
    4017  */
    4018 async function loadLazyRouteChildren(patchRoutesOnMissImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) {
    4019   let key = [path, ...matches.map(m => m.route.id)].join("-");
    4020   try {
    4021     let pending = pendingRouteChildren.get(key);
    4022     if (!pending) {
    4023       pending = patchRoutesOnMissImpl({
    4024         path,
    4025         matches,
    4026         patch: (routeId, children) => {
    4027           if (!signal.aborted) {
    4028             patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties);
    4029           }
    4030         }
    4031       });
    4032       pendingRouteChildren.set(key, pending);
    4033     }
    4034     if (pending && isPromise(pending)) {
    4035       await pending;
    4036     }
    4037   } finally {
    4038     pendingRouteChildren.delete(key);
    4039   }
    4040 }
    40414044function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) {
     4045  var _childrenToPatch;
     4046  let childrenToPatch;
    40424047  if (routeId) {
    4043     var _route$children;
    40444048    let route = manifest[routeId];
    40454049    invariant(route, "No route found to patch children into: routeId = " + routeId);
    4046     let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, [routeId, "patch", String(((_route$children = route.children) == null ? void 0 : _route$children.length) || "0")], manifest);
    4047     if (route.children) {
    4048       route.children.push(...dataChildren);
    4049     } else {
    4050       route.children = dataChildren;
    4051     }
     4050    if (!route.children) {
     4051      route.children = [];
     4052    }
     4053    childrenToPatch = route.children;
    40524054  } else {
    4053     let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest);
    4054     routesToUse.push(...dataChildren);
    4055   }
     4055    childrenToPatch = routesToUse;
     4056  }
     4057  // Don't patch in routes we already know about so that `patch` is idempotent
     4058  // to simplify user-land code. This is useful because we re-call the
     4059  // `patchRoutesOnNavigation` function for matched routes with params.
     4060  let uniqueChildren = children.filter(newRoute => !childrenToPatch.some(existingRoute => isSameRoute(newRoute, existingRoute)));
     4061  let newRoutes = convertRoutesToDataRoutes(uniqueChildren, mapRouteProperties, [routeId || "_", "patch", String(((_childrenToPatch = childrenToPatch) == null ? void 0 : _childrenToPatch.length) || "0")], manifest);
     4062  childrenToPatch.push(...newRoutes);
     4063}
     4064function isSameRoute(newRoute, existingRoute) {
     4065  // Most optimal check is by id
     4066  if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) {
     4067    return true;
     4068  }
     4069  // Second is by pathing differences
     4070  if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {
     4071    return false;
     4072  }
     4073  // Pathless layout routes are trickier since we need to check children.
     4074  // If they have no children then they're the same as far as we can tell
     4075  if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {
     4076    return true;
     4077  }
     4078  // Otherwise, we look to see if every child in the new route is already
     4079  // represented in the existing route's children
     4080  return newRoute.children.every((aChild, i) => {
     4081    var _existingRoute$childr;
     4082    return (_existingRoute$childr = existingRoute.children) == null ? void 0 : _existingRoute$childr.some(bChild => isSameRoute(aChild, bChild));
     4083  });
    40564084}
    40574085/**
     
    41044132}
    41054133// Default implementation of `dataStrategy` which fetches all loaders in parallel
    4106 function defaultDataStrategy(opts) {
    4107   return Promise.all(opts.matches.map(m => m.resolve()));
    4108 }
    4109 async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, manifest, mapRouteProperties, requestContext) {
    4110   let routeIdsToLoad = matchesToLoad.reduce((acc, m) => acc.add(m.route.id), new Set());
    4111   let loadedMatches = new Set();
     4134async function defaultDataStrategy(_ref4) {
     4135  let {
     4136    matches
     4137  } = _ref4;
     4138  let matchesToLoad = matches.filter(m => m.shouldLoad);
     4139  let results = await Promise.all(matchesToLoad.map(m => m.resolve()));
     4140  return results.reduce((acc, result, i) => Object.assign(acc, {
     4141    [matchesToLoad[i].route.id]: result
     4142  }), {});
     4143}
     4144async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties, requestContext) {
     4145  let loadRouteDefinitionsPromises = matches.map(m => m.route.lazy ? loadLazyRouteModule(m.route, mapRouteProperties, manifest) : undefined);
     4146  let dsMatches = matches.map((match, i) => {
     4147    let loadRoutePromise = loadRouteDefinitionsPromises[i];
     4148    let shouldLoad = matchesToLoad.some(m => m.route.id === match.route.id);
     4149    // `resolve` encapsulates route.lazy(), executing the loader/action,
     4150    // and mapping return values/thrown errors to a `DataStrategyResult`.  Users
     4151    // can pass a callback to take fine-grained control over the execution
     4152    // of the loader/action
     4153    let resolve = async handlerOverride => {
     4154      if (handlerOverride && request.method === "GET" && (match.route.lazy || match.route.loader)) {
     4155        shouldLoad = true;
     4156      }
     4157      return shouldLoad ? callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, requestContext) : Promise.resolve({
     4158        type: ResultType.data,
     4159        result: undefined
     4160      });
     4161    };
     4162    return _extends({}, match, {
     4163      shouldLoad,
     4164      resolve
     4165    });
     4166  });
    41124167  // Send all matches here to allow for a middleware-type implementation.
    41134168  // handler will be a no-op for unneeded routes and we filter those results
    41144169  // back out below.
    41154170  let results = await dataStrategyImpl({
    4116     matches: matches.map(match => {
    4117       let shouldLoad = routeIdsToLoad.has(match.route.id);
    4118       // `resolve` encapsulates the route.lazy, executing the
    4119       // loader/action, and mapping return values/thrown errors to a
    4120       // HandlerResult.  Users can pass a callback to take fine-grained control
    4121       // over the execution of the loader/action
    4122       let resolve = handlerOverride => {
    4123         loadedMatches.add(match.route.id);
    4124         return shouldLoad ? callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, requestContext) : Promise.resolve({
    4125           type: ResultType.data,
    4126           result: undefined
    4127         });
    4128       };
    4129       return _extends({}, match, {
    4130         shouldLoad,
    4131         resolve
    4132       });
    4133     }),
     4171    matches: dsMatches,
    41344172    request,
    41354173    params: matches[0].params,
     4174    fetcherKey,
    41364175    context: requestContext
    41374176  });
    4138   // Throw if any loadRoute implementations not called since they are what
    4139   // ensures a route is fully loaded
    4140   matches.forEach(m => invariant(loadedMatches.has(m.route.id), "`match.resolve()` was not called for route id \"" + m.route.id + "\". " + "You must call `match.resolve()` on every match passed to " + "`dataStrategy` to ensure all routes are properly loaded."));
    4141   // Filter out any middleware-only matches for which we didn't need to run handlers
    4142   return results.filter((_, i) => routeIdsToLoad.has(matches[i].route.id));
     4177  // Wait for all routes to load here but 'swallow the error since we want
     4178  // it to bubble up from the `await loadRoutePromise` in `callLoaderOrAction` -
     4179  // called from `match.resolve()`
     4180  try {
     4181    await Promise.all(loadRouteDefinitionsPromises);
     4182  } catch (e) {
     4183    // No-op
     4184  }
     4185  return results;
    41434186}
    41444187// Default logic for calling a loader/action is the user has no specified a dataStrategy
    4145 async function callLoaderOrAction(type, request, match, manifest, mapRouteProperties, handlerOverride, staticContext) {
     4188async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {
    41464189  let result;
    41474190  let onReject;
     
    41494192    // Setup a promise we can race against so that abort signals short circuit
    41504193    let reject;
    4151     // This will never resolve so safe to type it as Promise<HandlerResult> to
     4194    // This will never resolve so safe to type it as Promise<DataStrategyResult> to
    41524195    // satisfy the function return value
    41534196    let abortPromise = new Promise((_, r) => reject = r);
     
    41644207      }, ...(ctx !== undefined ? [ctx] : []));
    41654208    };
    4166     let handlerPromise;
    4167     if (handlerOverride) {
    4168       handlerPromise = handlerOverride(ctx => actualHandler(ctx));
    4169     } else {
    4170       handlerPromise = (async () => {
    4171         try {
    4172           let val = await actualHandler();
    4173           return {
    4174             type: "data",
    4175             result: val
    4176           };
    4177         } catch (e) {
    4178           return {
    4179             type: "error",
    4180             result: e
    4181           };
    4182         }
    4183       })();
    4184     }
     4209    let handlerPromise = (async () => {
     4210      try {
     4211        let val = await (handlerOverride ? handlerOverride(ctx => actualHandler(ctx)) : actualHandler());
     4212        return {
     4213          type: "data",
     4214          result: val
     4215        };
     4216      } catch (e) {
     4217        return {
     4218          type: "error",
     4219          result: e
     4220        };
     4221      }
     4222    })();
    41854223    return Promise.race([handlerPromise, abortPromise]);
    41864224  };
    41874225  try {
    41884226    let handler = match.route[type];
    4189     if (match.route.lazy) {
     4227    // If we have a route.lazy promise, await that first
     4228    if (loadRoutePromise) {
    41904229      if (handler) {
    41914230        // Run statically defined handler in parallel with lazy()
     
    41974236        runHandler(handler).catch(e => {
    41984237          handlerError = e;
    4199         }), loadLazyRouteModule(match.route, mapRouteProperties, manifest)]);
     4238        }), loadRoutePromise]);
    42004239        if (handlerError !== undefined) {
    42014240          throw handlerError;
     
    42044243      } else {
    42054244        // Load lazy route module, then run any returned handler
    4206         await loadLazyRouteModule(match.route, mapRouteProperties, manifest);
     4245        await loadRoutePromise;
    42074246        handler = match.route[type];
    42084247        if (handler) {
     
    42404279  } catch (e) {
    42414280    // We should already be catching and converting normal handler executions to
    4242     // HandlerResults and returning them, so anything that throws here is an
     4281    // DataStrategyResults and returning them, so anything that throws here is an
    42434282    // unexpected error we still need to wrap
    42444283    return {
     
    42534292  return result;
    42544293}
    4255 async function convertHandlerResultToDataResult(handlerResult) {
     4294async function convertDataStrategyResultToDataResult(dataStrategyResult) {
    42564295  let {
    42574296    result,
    42584297    type
    4259   } = handlerResult;
     4298  } = dataStrategyResult;
    42604299  if (isResponse(result)) {
    42614300    let data;
     
    43054344        };
    43064345      }
    4307       // Convert thrown unstable_data() to ErrorResponse instances
     4346      // Convert thrown data() to ErrorResponse instances
    43084347      result = new ErrorResponseImpl(((_result$init2 = result.init) == null ? void 0 : _result$init2.status) || 500, undefined, result.data);
    43094348    }
     
    44104449  return formData;
    44114450}
    4412 function processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) {
     4451function processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, skipLoaderErrorBubbling) {
    44134452  // Fill in loaderData/errors from our loaders
    44144453  let loaderData = {};
     
    44194458  let pendingError = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : undefined;
    44204459  // Process loader results into state.loaderData/state.errors
    4421   results.forEach((result, index) => {
    4422     let id = matchesToLoad[index].route.id;
     4460  matches.forEach(match => {
     4461    if (!(match.route.id in results)) {
     4462      return;
     4463    }
     4464    let id = match.route.id;
     4465    let result = results[id];
    44234466    invariant(!isRedirectResult(result), "Cannot handle redirect results in processLoaderData");
    44244467    if (isErrorResult(result)) {
     
    44954538  };
    44964539}
    4497 function processLoaderData(state, matches, matchesToLoad, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) {
     4540function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) {
    44984541  let {
    44994542    loaderData,
    45004543    errors
    4501   } = processRouteLoaderData(matches, matchesToLoad, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble
     4544  } = processRouteLoaderData(matches, results, pendingActionResult, activeDeferreds, false // This method is only called client side so we always want to bubble
    45024545  );
    45034546  // Process results from our revalidating fetchers
    4504   for (let index = 0; index < revalidatingFetchers.length; index++) {
     4547  revalidatingFetchers.forEach(rf => {
    45054548    let {
    45064549      key,
    45074550      match,
    45084551      controller
    4509     } = revalidatingFetchers[index];
    4510     invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, "Did not find corresponding fetcher result");
    4511     let result = fetcherResults[index];
     4552    } = rf;
     4553    let result = fetcherResults[key];
     4554    invariant(result, "Did not find corresponding fetcher result");
    45124555    // Process fetcher non-redirect errors
    45134556    if (controller && controller.signal.aborted) {
    45144557      // Nothing to do for aborted fetchers
    4515       continue;
     4558      return;
    45164559    } else if (isErrorResult(result)) {
    45174560      let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);
     
    45344577      state.fetchers.set(key, doneFetcher);
    45354578    }
    4536   }
     4579  });
    45374580  return {
    45384581    loaderData,
     
    46074650  if (status === 400) {
    46084651    statusText = "Bad Request";
    4609     if (type === "route-discovery") {
    4610       errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnMiss()` " + ("function threw the following error:\n" + message);
    4611     } else if (method && pathname && routeId) {
     4652    if (method && pathname && routeId) {
    46124653      errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request.";
    46134654    } else if (type === "defer-action") {
     
    46344675// Find any returned redirect errors, starting from the lowest match
    46354676function findRedirect(results) {
    4636   for (let i = results.length - 1; i >= 0; i--) {
    4637     let result = results[i];
     4677  let entries = Object.entries(results);
     4678  for (let i = entries.length - 1; i >= 0; i--) {
     4679    let [key, result] = entries[i];
    46384680    if (isRedirectResult(result)) {
    46394681      return {
    4640         result,
    4641         idx: i
     4682        key,
     4683        result
    46424684      };
    46434685    }
     
    46684710  return false;
    46694711}
    4670 function isPromise(val) {
    4671   return typeof val === "object" && val != null && "then" in val;
    4672 }
    4673 function isHandlerResult(result) {
     4712function isDataStrategyResult(result) {
    46744713  return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error);
    46754714}
    4676 function isRedirectHandlerResult(result) {
     4715function isRedirectDataStrategyResultResult(result) {
    46774716  return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
    46784717}
     
    47104749  return validMutationMethods.has(method.toLowerCase());
    47114750}
    4712 async function resolveDeferredResults(currentMatches, matchesToLoad, results, signals, isFetcher, currentLoaderData) {
    4713   for (let index = 0; index < results.length; index++) {
    4714     let result = results[index];
    4715     let match = matchesToLoad[index];
     4751async function resolveNavigationDeferredResults(matches, results, signal, currentMatches, currentLoaderData) {
     4752  let entries = Object.entries(results);
     4753  for (let index = 0; index < entries.length; index++) {
     4754    let [routeId, result] = entries[index];
     4755    let match = matches.find(m => (m == null ? void 0 : m.route.id) === routeId);
    47164756    // If we don't have a match, then we can have a deferred result to do
    47174757    // anything with.  This is for revalidating fetchers where the route was
     
    47224762    let currentMatch = currentMatches.find(m => m.route.id === match.route.id);
    47234763    let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;
    4724     if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {
     4764    if (isDeferredResult(result) && isRevalidatingLoader) {
    47254765      // Note: we do not have to touch activeDeferreds here since we race them
    47264766      // against the signal in resolveDeferredData and they'll get aborted
    47274767      // there if needed
    4728       let signal = signals[index];
    4729       invariant(signal, "Expected an AbortSignal for revalidating fetcher deferred result");
    4730       await resolveDeferredData(result, signal, isFetcher).then(result => {
     4768      await resolveDeferredData(result, signal, false).then(result => {
    47314769        if (result) {
    4732           results[index] = result || results[index];
     4770          results[routeId] = result;
     4771        }
     4772      });
     4773    }
     4774  }
     4775}
     4776async function resolveFetcherDeferredResults(matches, results, revalidatingFetchers) {
     4777  for (let index = 0; index < revalidatingFetchers.length; index++) {
     4778    let {
     4779      key,
     4780      routeId,
     4781      controller
     4782    } = revalidatingFetchers[index];
     4783    let result = results[key];
     4784    let match = matches.find(m => (m == null ? void 0 : m.route.id) === routeId);
     4785    // If we don't have a match, then we can have a deferred result to do
     4786    // anything with.  This is for revalidating fetchers where the route was
     4787    // removed during HMR
     4788    if (!match) {
     4789      continue;
     4790    }
     4791    if (isDeferredResult(result)) {
     4792      // Note: we do not have to touch activeDeferreds here since we race them
     4793      // against the signal in resolveDeferredData and they'll get aborted
     4794      // there if needed
     4795      invariant(controller, "Expected an AbortController for revalidating fetcher deferred result");
     4796      await resolveDeferredData(result, controller.signal, true).then(result => {
     4797        if (result) {
     4798          results[key] = result;
    47334799        }
    47344800      });
     
    49415007//#endregion
    49425008
    4943 export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, decodePath as UNSAFE_decodePath, getResolveToMatches as UNSAFE_getResolveToMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, defer, generatePath, getStaticContextFromError, getToPathname, isDataWithResponseInit, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, replace, resolvePath, resolveTo, stripBasename, data as unstable_data };
     5009export { AbortedDeferredError, Action, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, UNSAFE_DEFERRED_SYMBOL, DeferredData as UNSAFE_DeferredData, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch, convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes, decodePath as UNSAFE_decodePath, getResolveToMatches as UNSAFE_getResolveToMatches, invariant as UNSAFE_invariant, warning as UNSAFE_warning, createBrowserHistory, createHashHistory, createMemoryHistory, createPath, createRouter, createStaticHandler, data, defer, generatePath, getStaticContextFromError, getToPathname, isDataWithResponseInit, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, replace, resolvePath, resolveTo, stripBasename };
    49445010//# sourceMappingURL=router.js.map
Note: See TracChangeset for help on using the changeset viewer.