@remix-run/router 1.19.2 → 1.20.0-pre.1

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/dist/router.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @remix-run/router v1.19.2
2
+ * @remix-run/router v1.20.0-pre.1
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1362,8 +1362,8 @@ function createRouter(init) {
1362
1362
  let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest);
1363
1363
  let inFlightDataRoutes;
1364
1364
  let basename = init.basename || "/";
1365
- let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;
1366
- let patchRoutesOnNavigationImpl = init.unstable_patchRoutesOnNavigation;
1365
+ let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
1366
+ let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
1367
1367
  // Config driven behavior flags
1368
1368
  let future = _extends({
1369
1369
  v7_fetcherPersist: false,
@@ -1377,10 +1377,6 @@ function createRouter(init) {
1377
1377
  let unlistenHistory = null;
1378
1378
  // Externally-provided functions to call on all state changes
1379
1379
  let subscribers = new Set();
1380
- // FIFO queue of previously discovered routes to prevent re-calling on
1381
- // subsequent navigations to the same path
1382
- let discoveredRoutesMaxSize = 1000;
1383
- let discoveredRoutes = new Set();
1384
1380
  // Externally-provided object to hold scroll restoration locations during routing
1385
1381
  let savedScrollPositions = null;
1386
1382
  // Externally-provided function to get scroll restoration keys
@@ -1449,24 +1445,12 @@ function createRouter(init) {
1449
1445
  // were marked for explicit hydration
1450
1446
  let loaderData = init.hydrationData ? init.hydrationData.loaderData : null;
1451
1447
  let errors = init.hydrationData ? init.hydrationData.errors : null;
1452
- let isRouteInitialized = m => {
1453
- // No loader, nothing to initialize
1454
- if (!m.route.loader) {
1455
- return true;
1456
- }
1457
- // Explicitly opting-in to running on hydration
1458
- if (typeof m.route.loader === "function" && m.route.loader.hydrate === true) {
1459
- return false;
1460
- }
1461
- // Otherwise, initialized if hydrated with data or an error
1462
- return loaderData && loaderData[m.route.id] !== undefined || errors && errors[m.route.id] !== undefined;
1463
- };
1464
1448
  // If errors exist, don't consider routes below the boundary
1465
1449
  if (errors) {
1466
1450
  let idx = initialMatches.findIndex(m => errors[m.route.id] !== undefined);
1467
- initialized = initialMatches.slice(0, idx + 1).every(isRouteInitialized);
1451
+ initialized = initialMatches.slice(0, idx + 1).every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));
1468
1452
  } else {
1469
- initialized = initialMatches.every(isRouteInitialized);
1453
+ initialized = initialMatches.every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));
1470
1454
  }
1471
1455
  } else {
1472
1456
  // Without partial hydration - we're initialized if we were provided any
@@ -1545,9 +1529,6 @@ function createRouter(init) {
1545
1529
  // Store blocker functions in a separate Map outside of router state since
1546
1530
  // we don't need to update UI state if they change
1547
1531
  let blockerFunctions = new Map();
1548
- // Map of pending patchRoutesOnNavigation() promises (keyed by path/matches) so
1549
- // that we only kick them off once for a given combo
1550
- let pendingPatchRoutes = new Map();
1551
1532
  // Flag to ignore the next history update, so we can revert the URL change on
1552
1533
  // a POP navigation that was blocked by the user without touching router state
1553
1534
  let unblockBlockerHistoryUpdate = undefined;
@@ -1677,8 +1658,8 @@ function createRouter(init) {
1677
1658
  // we don't get ourselves into a loop calling the new subscriber immediately
1678
1659
  [...subscribers].forEach(subscriber => subscriber(state, {
1679
1660
  deletedFetchers: deletedFetchersKeys,
1680
- unstable_viewTransitionOpts: opts.viewTransitionOpts,
1681
- unstable_flushSync: opts.flushSync === true
1661
+ viewTransitionOpts: opts.viewTransitionOpts,
1662
+ flushSync: opts.flushSync === true
1682
1663
  }));
1683
1664
  // Remove idle fetchers from state since we only care about in-flight fetchers.
1684
1665
  if (future.v7_fetcherPersist) {
@@ -1827,7 +1808,7 @@ function createRouter(init) {
1827
1808
  historyAction = Action.Replace;
1828
1809
  }
1829
1810
  let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
1830
- let flushSync = (opts && opts.unstable_flushSync) === true;
1811
+ let flushSync = (opts && opts.flushSync) === true;
1831
1812
  let blockerKey = shouldBlockNavigation({
1832
1813
  currentLocation,
1833
1814
  nextLocation,
@@ -1865,7 +1846,7 @@ function createRouter(init) {
1865
1846
  pendingError: error,
1866
1847
  preventScrollReset,
1867
1848
  replace: opts && opts.replace,
1868
- enableViewTransition: opts && opts.unstable_viewTransition,
1849
+ enableViewTransition: opts && opts.viewTransition,
1869
1850
  flushSync
1870
1851
  });
1871
1852
  }
@@ -1945,7 +1926,7 @@ function createRouter(init) {
1945
1926
  // Short circuit if it's only a hash change and not a revalidation or
1946
1927
  // mutation submission.
1947
1928
  //
1948
- // Ignore on initial page loads because since the initial load will always
1929
+ // Ignore on initial page loads because since the initial hydration will always
1949
1930
  // be "same hash". For example, on /page#hash and submit a <Form method="post">
1950
1931
  // which will default to a navigation to /page
1951
1932
  if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {
@@ -2045,15 +2026,12 @@ function createRouter(init) {
2045
2026
  shortCircuited: true
2046
2027
  };
2047
2028
  } else if (discoverResult.type === "error") {
2048
- let {
2049
- boundaryId,
2050
- error
2051
- } = handleDiscoverRouteError(location.pathname, discoverResult);
2029
+ let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
2052
2030
  return {
2053
2031
  matches: discoverResult.partialMatches,
2054
2032
  pendingActionResult: [boundaryId, {
2055
2033
  type: ResultType.error,
2056
- error
2034
+ error: discoverResult.error
2057
2035
  }]
2058
2036
  };
2059
2037
  } else if (!discoverResult.matches) {
@@ -2177,15 +2155,12 @@ function createRouter(init) {
2177
2155
  shortCircuited: true
2178
2156
  };
2179
2157
  } else if (discoverResult.type === "error") {
2180
- let {
2181
- boundaryId,
2182
- error
2183
- } = handleDiscoverRouteError(location.pathname, discoverResult);
2158
+ let boundaryId = findNearestBoundary(discoverResult.partialMatches).route.id;
2184
2159
  return {
2185
2160
  matches: discoverResult.partialMatches,
2186
2161
  loaderData: {},
2187
2162
  errors: {
2188
- [boundaryId]: error
2163
+ [boundaryId]: discoverResult.error
2189
2164
  }
2190
2165
  };
2191
2166
  } else if (!discoverResult.matches) {
@@ -2249,9 +2224,7 @@ function createRouter(init) {
2249
2224
  });
2250
2225
  }
2251
2226
  revalidatingFetchers.forEach(rf => {
2252
- if (fetchControllers.has(rf.key)) {
2253
- abortFetcher(rf.key);
2254
- }
2227
+ abortFetcher(rf.key);
2255
2228
  if (rf.controller) {
2256
2229
  // Fetchers use an independent AbortController so that aborting a fetcher
2257
2230
  // (via deleteFetcher) does not abort the triggering navigation that
@@ -2307,7 +2280,7 @@ function createRouter(init) {
2307
2280
  let {
2308
2281
  loaderData,
2309
2282
  errors
2310
- } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds);
2283
+ } = processLoaderData(state, matches, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds);
2311
2284
  // Wire up subscribers to update loaderData as promises settle
2312
2285
  activeDeferreds.forEach((deferredData, routeId) => {
2313
2286
  deferredData.subscribe(aborted => {
@@ -2319,17 +2292,9 @@ function createRouter(init) {
2319
2292
  }
2320
2293
  });
2321
2294
  });
2322
- // During partial hydration, preserve SSR errors for routes that don't re-run
2295
+ // Preserve SSR errors during partial hydration
2323
2296
  if (future.v7_partialHydration && initialHydration && state.errors) {
2324
- Object.entries(state.errors).filter(_ref2 => {
2325
- let [id] = _ref2;
2326
- return !matchesToLoad.some(m => m.route.id === id);
2327
- }).forEach(_ref3 => {
2328
- let [routeId, error] = _ref3;
2329
- errors = Object.assign(errors || {}, {
2330
- [routeId]: error
2331
- });
2332
- });
2297
+ errors = _extends({}, state.errors, errors);
2333
2298
  }
2334
2299
  let updatedFetchers = markFetchRedirectsDone();
2335
2300
  let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);
@@ -2371,8 +2336,8 @@ function createRouter(init) {
2371
2336
  if (isServer) {
2372
2337
  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.");
2373
2338
  }
2374
- if (fetchControllers.has(key)) abortFetcher(key);
2375
- let flushSync = (opts && opts.unstable_flushSync) === true;
2339
+ abortFetcher(key);
2340
+ let flushSync = (opts && opts.flushSync) === true;
2376
2341
  let routesToUse = inFlightDataRoutes || dataRoutes;
2377
2342
  let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, future.v7_relativeSplatPath, routeId, opts == null ? void 0 : opts.relative);
2378
2343
  let matches = matchRoutes(routesToUse, normalizedPath, basename);
@@ -2400,9 +2365,9 @@ function createRouter(init) {
2400
2365
  return;
2401
2366
  }
2402
2367
  let match = getTargetMatch(matches, path);
2403
- pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
2368
+ let preventScrollReset = (opts && opts.preventScrollReset) === true;
2404
2369
  if (submission && isMutationMethod(submission.formMethod)) {
2405
- handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission);
2370
+ handleFetcherAction(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
2406
2371
  return;
2407
2372
  }
2408
2373
  // Store off the match so we can call it's shouldRevalidate on subsequent
@@ -2411,11 +2376,11 @@ function createRouter(init) {
2411
2376
  routeId,
2412
2377
  path
2413
2378
  });
2414
- handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, submission);
2379
+ handleFetcherLoader(key, routeId, path, match, matches, fogOfWar.active, flushSync, preventScrollReset, submission);
2415
2380
  }
2416
2381
  // Call the action for the matched fetcher.submit(), and then handle redirects,
2417
2382
  // errors, and revalidation
2418
- async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, submission) {
2383
+ async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {
2419
2384
  interruptActiveLoads();
2420
2385
  fetchLoadMatches.delete(key);
2421
2386
  function detectAndHandle405Error(m) {
@@ -2447,10 +2412,7 @@ function createRouter(init) {
2447
2412
  if (discoverResult.type === "aborted") {
2448
2413
  return;
2449
2414
  } else if (discoverResult.type === "error") {
2450
- let {
2451
- error
2452
- } = handleDiscoverRouteError(path, discoverResult);
2453
- setFetcherError(key, routeId, error, {
2415
+ setFetcherError(key, routeId, discoverResult.error, {
2454
2416
  flushSync
2455
2417
  });
2456
2418
  return;
@@ -2505,7 +2467,8 @@ function createRouter(init) {
2505
2467
  fetchRedirectIds.add(key);
2506
2468
  updateFetcherState(key, getLoadingFetcher(submission));
2507
2469
  return startRedirectNavigation(fetchRequest, actionResult, false, {
2508
- fetcherSubmission: submission
2470
+ fetcherSubmission: submission,
2471
+ preventScrollReset
2509
2472
  });
2510
2473
  }
2511
2474
  }
@@ -2540,9 +2503,7 @@ function createRouter(init) {
2540
2503
  let existingFetcher = state.fetchers.get(staleKey);
2541
2504
  let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined);
2542
2505
  state.fetchers.set(staleKey, revalidatingFetcher);
2543
- if (fetchControllers.has(staleKey)) {
2544
- abortFetcher(staleKey);
2545
- }
2506
+ abortFetcher(staleKey);
2546
2507
  if (rf.controller) {
2547
2508
  fetchControllers.set(staleKey, rf.controller);
2548
2509
  }
@@ -2565,7 +2526,9 @@ function createRouter(init) {
2565
2526
  revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));
2566
2527
  let redirect = findRedirect(loaderResults);
2567
2528
  if (redirect) {
2568
- return startRedirectNavigation(revalidationRequest, redirect.result, false);
2529
+ return startRedirectNavigation(revalidationRequest, redirect.result, false, {
2530
+ preventScrollReset
2531
+ });
2569
2532
  }
2570
2533
  redirect = findRedirect(fetcherResults);
2571
2534
  if (redirect) {
@@ -2573,13 +2536,15 @@ function createRouter(init) {
2573
2536
  // fetchRedirectIds so it doesn't get revalidated on the next set of
2574
2537
  // loader executions
2575
2538
  fetchRedirectIds.add(redirect.key);
2576
- return startRedirectNavigation(revalidationRequest, redirect.result, false);
2539
+ return startRedirectNavigation(revalidationRequest, redirect.result, false, {
2540
+ preventScrollReset
2541
+ });
2577
2542
  }
2578
2543
  // Process and commit output from loaders
2579
2544
  let {
2580
2545
  loaderData,
2581
2546
  errors
2582
- } = processLoaderData(state, matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);
2547
+ } = processLoaderData(state, matches, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);
2583
2548
  // Since we let revalidations complete even if the submitting fetcher was
2584
2549
  // deleted, only put it back to idle if it hasn't been deleted
2585
2550
  if (state.fetchers.has(key)) {
@@ -2612,7 +2577,7 @@ function createRouter(init) {
2612
2577
  }
2613
2578
  }
2614
2579
  // Call the matched loader for fetcher.load(), handling redirects, errors, etc.
2615
- async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, submission) {
2580
+ async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {
2616
2581
  let existingFetcher = state.fetchers.get(key);
2617
2582
  updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined), {
2618
2583
  flushSync
@@ -2624,10 +2589,7 @@ function createRouter(init) {
2624
2589
  if (discoverResult.type === "aborted") {
2625
2590
  return;
2626
2591
  } else if (discoverResult.type === "error") {
2627
- let {
2628
- error
2629
- } = handleDiscoverRouteError(path, discoverResult);
2630
- setFetcherError(key, routeId, error, {
2592
+ setFetcherError(key, routeId, discoverResult.error, {
2631
2593
  flushSync
2632
2594
  });
2633
2595
  return;
@@ -2678,7 +2640,9 @@ function createRouter(init) {
2678
2640
  return;
2679
2641
  } else {
2680
2642
  fetchRedirectIds.add(key);
2681
- await startRedirectNavigation(fetchRequest, result, false);
2643
+ await startRedirectNavigation(fetchRequest, result, false, {
2644
+ preventScrollReset
2645
+ });
2682
2646
  return;
2683
2647
  }
2684
2648
  }
@@ -2714,6 +2678,7 @@ function createRouter(init) {
2714
2678
  let {
2715
2679
  submission,
2716
2680
  fetcherSubmission,
2681
+ preventScrollReset,
2717
2682
  replace
2718
2683
  } = _temp2 === void 0 ? {} : _temp2;
2719
2684
  if (redirect.response.headers.has("X-Remix-Revalidate")) {
@@ -2771,7 +2736,7 @@ function createRouter(init) {
2771
2736
  formAction: location
2772
2737
  }),
2773
2738
  // Preserve these flags across redirects
2774
- preventScrollReset: pendingPreventScrollReset,
2739
+ preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2775
2740
  enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined
2776
2741
  });
2777
2742
  } else {
@@ -2783,7 +2748,7 @@ function createRouter(init) {
2783
2748
  // Send fetcher submissions through for shouldRevalidate
2784
2749
  fetcherSubmission,
2785
2750
  // Preserve these flags across redirects
2786
- preventScrollReset: pendingPreventScrollReset,
2751
+ preventScrollReset: preventScrollReset || pendingPreventScrollReset,
2787
2752
  enableViewTransition: isNavigation ? pendingViewTransitionEnabled : undefined
2788
2753
  });
2789
2754
  }
@@ -2860,8 +2825,8 @@ function createRouter(init) {
2860
2825
  fetchLoadMatches.forEach((_, key) => {
2861
2826
  if (fetchControllers.has(key)) {
2862
2827
  cancelledFetcherLoads.add(key);
2863
- abortFetcher(key);
2864
2828
  }
2829
+ abortFetcher(key);
2865
2830
  });
2866
2831
  }
2867
2832
  function updateFetcherState(key, fetcher, opts) {
@@ -2934,9 +2899,10 @@ function createRouter(init) {
2934
2899
  }
2935
2900
  function abortFetcher(key) {
2936
2901
  let controller = fetchControllers.get(key);
2937
- invariant(controller, "Expected fetch controller: " + key);
2938
- controller.abort();
2939
- fetchControllers.delete(key);
2902
+ if (controller) {
2903
+ controller.abort();
2904
+ fetchControllers.delete(key);
2905
+ }
2940
2906
  }
2941
2907
  function markFetchersDone(keys) {
2942
2908
  for (let key of keys) {
@@ -2999,12 +2965,12 @@ function createRouter(init) {
2999
2965
  blockers
3000
2966
  });
3001
2967
  }
3002
- function shouldBlockNavigation(_ref4) {
2968
+ function shouldBlockNavigation(_ref2) {
3003
2969
  let {
3004
2970
  currentLocation,
3005
2971
  nextLocation,
3006
2972
  historyAction
3007
- } = _ref4;
2973
+ } = _ref2;
3008
2974
  if (blockerFunctions.size === 0) {
3009
2975
  return;
3010
2976
  }
@@ -3048,16 +3014,6 @@ function createRouter(init) {
3048
3014
  error
3049
3015
  };
3050
3016
  }
3051
- function handleDiscoverRouteError(pathname, discoverResult) {
3052
- return {
3053
- boundaryId: findNearestBoundary(discoverResult.partialMatches).route.id,
3054
- error: getInternalRouterError(400, {
3055
- type: "route-discovery",
3056
- pathname,
3057
- message: discoverResult.error != null && "message" in discoverResult.error ? discoverResult.error : String(discoverResult.error)
3058
- })
3059
- };
3060
- }
3061
3017
  function cancelActiveDeferreds(predicate) {
3062
3018
  let cancelledRouteIds = [];
3063
3019
  activeDeferreds.forEach((dfd, routeId) => {
@@ -3121,15 +3077,6 @@ function createRouter(init) {
3121
3077
  }
3122
3078
  function checkFogOfWar(matches, routesToUse, pathname) {
3123
3079
  if (patchRoutesOnNavigationImpl) {
3124
- // Don't bother re-calling patchRouteOnMiss for a path we've already
3125
- // processed. the last execution would have patched the route tree
3126
- // accordingly so `matches` here are already accurate.
3127
- if (discoveredRoutes.has(pathname)) {
3128
- return {
3129
- active: false,
3130
- matches
3131
- };
3132
- }
3133
3080
  if (!matches) {
3134
3081
  let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
3135
3082
  return {
@@ -3155,12 +3102,26 @@ function createRouter(init) {
3155
3102
  };
3156
3103
  }
3157
3104
  async function discoverRoutes(matches, pathname, signal) {
3105
+ if (!patchRoutesOnNavigationImpl) {
3106
+ return {
3107
+ type: "success",
3108
+ matches
3109
+ };
3110
+ }
3158
3111
  let partialMatches = matches;
3159
3112
  while (true) {
3160
3113
  let isNonHMR = inFlightDataRoutes == null;
3161
3114
  let routesToUse = inFlightDataRoutes || dataRoutes;
3115
+ let localManifest = manifest;
3162
3116
  try {
3163
- await loadLazyRouteChildren(patchRoutesOnNavigationImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal);
3117
+ await patchRoutesOnNavigationImpl({
3118
+ path: pathname,
3119
+ matches: partialMatches,
3120
+ patch: (routeId, children) => {
3121
+ if (signal.aborted) return;
3122
+ patchRoutesImpl(routeId, children, routesToUse, localManifest, mapRouteProperties);
3123
+ }
3124
+ });
3164
3125
  } catch (e) {
3165
3126
  return {
3166
3127
  type: "error",
@@ -3174,7 +3135,7 @@ function createRouter(init) {
3174
3135
  // trigger a re-run of memoized `router.routes` dependencies.
3175
3136
  // HMR will already update the identity and reflow when it lands
3176
3137
  // `inFlightDataRoutes` in `completeNavigation`
3177
- if (isNonHMR) {
3138
+ if (isNonHMR && !signal.aborted) {
3178
3139
  dataRoutes = [...dataRoutes];
3179
3140
  }
3180
3141
  }
@@ -3185,7 +3146,6 @@ function createRouter(init) {
3185
3146
  }
3186
3147
  let newMatches = matchRoutes(routesToUse, pathname, basename);
3187
3148
  if (newMatches) {
3188
- addToFifoQueue(pathname, discoveredRoutes);
3189
3149
  return {
3190
3150
  type: "success",
3191
3151
  matches: newMatches
@@ -3194,7 +3154,6 @@ function createRouter(init) {
3194
3154
  let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
3195
3155
  // Avoid loops if the second pass results in the same partial matches
3196
3156
  if (!newPartialMatches || partialMatches.length === newPartialMatches.length && partialMatches.every((m, i) => m.route.id === newPartialMatches[i].route.id)) {
3197
- addToFifoQueue(pathname, discoveredRoutes);
3198
3157
  return {
3199
3158
  type: "success",
3200
3159
  matches: null
@@ -3203,13 +3162,6 @@ function createRouter(init) {
3203
3162
  partialMatches = newPartialMatches;
3204
3163
  }
3205
3164
  }
3206
- function addToFifoQueue(path, queue) {
3207
- if (queue.size >= discoveredRoutesMaxSize) {
3208
- let first = queue.values().next().value;
3209
- queue.delete(first);
3210
- }
3211
- queue.add(path);
3212
- }
3213
3165
  function _internalSetRoutes(newRoutes) {
3214
3166
  manifest = {};
3215
3167
  inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest);
@@ -3325,7 +3277,7 @@ function createStaticHandler(routes, opts) {
3325
3277
  let {
3326
3278
  requestContext,
3327
3279
  skipLoaderErrorBubbling,
3328
- unstable_dataStrategy
3280
+ dataStrategy
3329
3281
  } = _temp3 === void 0 ? {} : _temp3;
3330
3282
  let url = new URL(request.url);
3331
3283
  let method = request.method;
@@ -3377,7 +3329,7 @@ function createStaticHandler(routes, opts) {
3377
3329
  activeDeferreds: null
3378
3330
  };
3379
3331
  }
3380
- let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, skipLoaderErrorBubbling === true, null);
3332
+ let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, skipLoaderErrorBubbling === true, null);
3381
3333
  if (isResponse(result)) {
3382
3334
  return result;
3383
3335
  }
@@ -3419,7 +3371,7 @@ function createStaticHandler(routes, opts) {
3419
3371
  let {
3420
3372
  routeId,
3421
3373
  requestContext,
3422
- unstable_dataStrategy
3374
+ dataStrategy
3423
3375
  } = _temp4 === void 0 ? {} : _temp4;
3424
3376
  let url = new URL(request.url);
3425
3377
  let method = request.method;
@@ -3447,7 +3399,7 @@ function createStaticHandler(routes, opts) {
3447
3399
  pathname: location.pathname
3448
3400
  });
3449
3401
  }
3450
- let result = await queryImpl(request, location, matches, requestContext, unstable_dataStrategy || null, false, match);
3402
+ let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, false, match);
3451
3403
  if (isResponse(result)) {
3452
3404
  return result;
3453
3405
  }
@@ -3473,14 +3425,14 @@ function createStaticHandler(routes, opts) {
3473
3425
  }
3474
3426
  return undefined;
3475
3427
  }
3476
- async function queryImpl(request, location, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch) {
3428
+ async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch) {
3477
3429
  invariant(request.signal, "query()/queryRoute() requests must contain an AbortController signal");
3478
3430
  try {
3479
3431
  if (isMutationMethod(request.method.toLowerCase())) {
3480
- let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch != null);
3432
+ let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch != null);
3481
3433
  return result;
3482
3434
  }
3483
- let result = await loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch);
3435
+ let result = await loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch);
3484
3436
  return isResponse(result) ? result : _extends({}, result, {
3485
3437
  actionData: null,
3486
3438
  actionHeaders: {}
@@ -3503,7 +3455,7 @@ function createStaticHandler(routes, opts) {
3503
3455
  throw e;
3504
3456
  }
3505
3457
  }
3506
- async function submit(request, matches, actionMatch, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
3458
+ async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
3507
3459
  let result;
3508
3460
  if (!actionMatch.route.action && !actionMatch.route.lazy) {
3509
3461
  let error = getInternalRouterError(405, {
@@ -3519,7 +3471,7 @@ function createStaticHandler(routes, opts) {
3519
3471
  error
3520
3472
  };
3521
3473
  } else {
3522
- let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, unstable_dataStrategy);
3474
+ let results = await callDataStrategy("action", request, [actionMatch], matches, isRouteRequest, requestContext, dataStrategy);
3523
3475
  result = results[actionMatch.route.id];
3524
3476
  if (request.signal.aborted) {
3525
3477
  throwStaticHandlerAbortedError(request, isRouteRequest, future);
@@ -3580,7 +3532,7 @@ function createStaticHandler(routes, opts) {
3580
3532
  // Store off the pending error - we use it to determine which loaders
3581
3533
  // to call and will commit it when we complete the navigation
3582
3534
  let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3583
- let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);
3535
+ let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null, [boundaryMatch.route.id, result]);
3584
3536
  // action status codes take precedence over loader status codes
3585
3537
  return _extends({}, context, {
3586
3538
  statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
@@ -3590,7 +3542,7 @@ function createStaticHandler(routes, opts) {
3590
3542
  } : {})
3591
3543
  });
3592
3544
  }
3593
- let context = await loadRouteData(loaderRequest, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, null);
3545
+ let context = await loadRouteData(loaderRequest, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, null);
3594
3546
  return _extends({}, context, {
3595
3547
  actionData: {
3596
3548
  [actionMatch.route.id]: result.data
@@ -3603,7 +3555,7 @@ function createStaticHandler(routes, opts) {
3603
3555
  } : {}
3604
3556
  });
3605
3557
  }
3606
- async function loadRouteData(request, matches, requestContext, unstable_dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
3558
+ async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
3607
3559
  let isRouteRequest = routeMatch != null;
3608
3560
  // Short circuit if we have no loaders to run (queryRoute())
3609
3561
  if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) {
@@ -3631,7 +3583,7 @@ function createStaticHandler(routes, opts) {
3631
3583
  activeDeferreds: null
3632
3584
  };
3633
3585
  }
3634
- let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy);
3586
+ let results = await callDataStrategy("loader", request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy);
3635
3587
  if (request.signal.aborted) {
3636
3588
  throwStaticHandlerAbortedError(request, isRouteRequest, future);
3637
3589
  }
@@ -3652,8 +3604,8 @@ function createStaticHandler(routes, opts) {
3652
3604
  }
3653
3605
  // Utility wrapper for calling dataStrategy server-side without having to
3654
3606
  // pass around the manifest, mapRouteProperties, etc.
3655
- async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, unstable_dataStrategy) {
3656
- let results = await callDataStrategyImpl(unstable_dataStrategy || defaultDataStrategy, type, null, request, matchesToLoad, matches, null, manifest, mapRouteProperties, requestContext);
3607
+ async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy) {
3608
+ let results = await callDataStrategyImpl(dataStrategy || defaultDataStrategy, type, null, request, matchesToLoad, matches, null, manifest, mapRouteProperties, requestContext);
3657
3609
  let dataResults = {};
3658
3610
  await Promise.all(matches.map(async match => {
3659
3611
  if (!(match.route.id in results)) {
@@ -3734,9 +3686,21 @@ function normalizeTo(location, matches, basename, prependBasename, to, v7_relati
3734
3686
  path.search = location.search;
3735
3687
  path.hash = location.hash;
3736
3688
  }
3737
- // Add an ?index param for matched index routes if we don't already have one
3738
- if ((to == null || to === "" || to === ".") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) {
3739
- path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
3689
+ // Account for `?index` params when routing to the current location
3690
+ if ((to == null || to === "" || to === ".") && activeRouteMatch) {
3691
+ let nakedIndex = hasNakedIndexQuery(path.search);
3692
+ if (activeRouteMatch.route.index && !nakedIndex) {
3693
+ // Add one when we're targeting an index route
3694
+ path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
3695
+ } else if (!activeRouteMatch.route.index && nakedIndex) {
3696
+ // Remove existing ones when we're not
3697
+ let params = new URLSearchParams(path.search);
3698
+ let indexValues = params.getAll("index");
3699
+ params.delete("index");
3700
+ indexValues.filter(v => v).forEach(v => params.append("index", v));
3701
+ let qs = params.toString();
3702
+ path.search = qs ? "?" + qs : "";
3703
+ }
3740
3704
  }
3741
3705
  // If we're operating within a basename, prepend it to the pathname. If
3742
3706
  // this is a root navigation, then just use the raw basename which allows
@@ -3782,8 +3746,8 @@ function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) {
3782
3746
  }
3783
3747
  let text = typeof opts.body === "string" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ?
3784
3748
  // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data
3785
- Array.from(opts.body.entries()).reduce((acc, _ref5) => {
3786
- let [name, value] = _ref5;
3749
+ Array.from(opts.body.entries()).reduce((acc, _ref3) => {
3750
+ let [name, value] = _ref3;
3787
3751
  return "" + acc + name + "=" + value + "\n";
3788
3752
  }, "") : String(opts.body);
3789
3753
  return {
@@ -3871,25 +3835,36 @@ function normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) {
3871
3835
  submission
3872
3836
  };
3873
3837
  }
3874
- // Filter out all routes below any caught error as they aren't going to
3838
+ // Filter out all routes at/below any caught error as they aren't going to
3875
3839
  // render so we don't need to load them
3876
- function getLoaderMatchesUntilBoundary(matches, boundaryId) {
3877
- let boundaryMatches = matches;
3878
- if (boundaryId) {
3879
- let index = matches.findIndex(m => m.route.id === boundaryId);
3880
- if (index >= 0) {
3881
- boundaryMatches = matches.slice(0, index);
3882
- }
3840
+ function getLoaderMatchesUntilBoundary(matches, boundaryId, includeBoundary) {
3841
+ if (includeBoundary === void 0) {
3842
+ includeBoundary = false;
3883
3843
  }
3884
- return boundaryMatches;
3844
+ let index = matches.findIndex(m => m.route.id === boundaryId);
3845
+ if (index >= 0) {
3846
+ return matches.slice(0, includeBoundary ? index + 1 : index);
3847
+ }
3848
+ return matches;
3885
3849
  }
3886
- function getMatchesToLoad(history, state, matches, submission, location, isInitialLoad, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
3850
+ function getMatchesToLoad(history, state, matches, submission, location, initialHydration, skipActionErrorRevalidation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, deletedFetchers, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
3887
3851
  let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : undefined;
3888
3852
  let currentUrl = history.createURL(state.location);
3889
3853
  let nextUrl = history.createURL(location);
3890
3854
  // Pick navigation matches that are net-new or qualify for revalidation
3891
- let boundaryId = pendingActionResult && isErrorResult(pendingActionResult[1]) ? pendingActionResult[0] : undefined;
3892
- let boundaryMatches = boundaryId ? getLoaderMatchesUntilBoundary(matches, boundaryId) : matches;
3855
+ let boundaryMatches = matches;
3856
+ if (initialHydration && state.errors) {
3857
+ // On initial hydration, only consider matches up to _and including_ the boundary.
3858
+ // This is inclusive to handle cases where a server loader ran successfully,
3859
+ // a child server loader bubbled up to this route, but this route has
3860
+ // `clientLoader.hydrate` so we want to still run the `clientLoader` so that
3861
+ // we have a complete version of `loaderData`
3862
+ boundaryMatches = getLoaderMatchesUntilBoundary(matches, Object.keys(state.errors)[0], true);
3863
+ } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {
3864
+ // If an action threw an error, we call loaders up to, but not including the
3865
+ // boundary
3866
+ boundaryMatches = getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]);
3867
+ }
3893
3868
  // Don't revalidate loaders by default after action 4xx/5xx responses
3894
3869
  // when the flag is enabled. They can still opt-into revalidation via
3895
3870
  // `shouldRevalidate` via `actionResult`
@@ -3906,13 +3881,8 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
3906
3881
  if (route.loader == null) {
3907
3882
  return false;
3908
3883
  }
3909
- if (isInitialLoad) {
3910
- if (typeof route.loader !== "function" || route.loader.hydrate) {
3911
- return true;
3912
- }
3913
- return state.loaderData[route.id] === undefined && (
3914
- // Don't re-run if the loader ran and threw an error
3915
- !state.errors || state.errors[route.id] === undefined);
3884
+ if (initialHydration) {
3885
+ return shouldLoadRouteOnHydration(route, state.loaderData, state.errors);
3916
3886
  }
3917
3887
  // Always call the loader on new route instances and pending defer cancellations
3918
3888
  if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some(id => id === match.route.id)) {
@@ -3943,11 +3913,11 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
3943
3913
  let revalidatingFetchers = [];
3944
3914
  fetchLoadMatches.forEach((f, key) => {
3945
3915
  // Don't revalidate:
3946
- // - on initial load (shouldn't be any fetchers then anyway)
3916
+ // - on initial hydration (shouldn't be any fetchers then anyway)
3947
3917
  // - if fetcher won't be present in the subsequent render
3948
3918
  // - no longer matches the URL (v7_fetcherPersist=false)
3949
3919
  // - was unmounted but persisted due to v7_fetcherPersist=true
3950
- if (isInitialLoad || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {
3920
+ if (initialHydration || !matches.some(m => m.route.id === f.routeId) || deletedFetchers.has(key)) {
3951
3921
  return;
3952
3922
  }
3953
3923
  let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
@@ -4011,6 +3981,28 @@ function getMatchesToLoad(history, state, matches, submission, location, isIniti
4011
3981
  });
4012
3982
  return [navigationMatches, revalidatingFetchers];
4013
3983
  }
3984
+ function shouldLoadRouteOnHydration(route, loaderData, errors) {
3985
+ // We dunno if we have a loader - gotta find out!
3986
+ if (route.lazy) {
3987
+ return true;
3988
+ }
3989
+ // No loader, nothing to initialize
3990
+ if (!route.loader) {
3991
+ return false;
3992
+ }
3993
+ let hasData = loaderData != null && loaderData[route.id] !== undefined;
3994
+ let hasError = errors != null && errors[route.id] !== undefined;
3995
+ // Don't run if we error'd during SSR
3996
+ if (!hasData && hasError) {
3997
+ return false;
3998
+ }
3999
+ // Explicitly opting-in to running on hydration
4000
+ if (typeof route.loader === "function" && route.loader.hydrate === true) {
4001
+ return true;
4002
+ }
4003
+ // Otherwise, run if we're not yet initialized with anything
4004
+ return !hasData && !hasError;
4005
+ }
4014
4006
  function isNewLoader(currentLoaderData, currentMatch, match) {
4015
4007
  let isNew =
4016
4008
  // [a] -> [a, b]
@@ -4042,48 +4034,46 @@ function shouldRevalidateLoader(loaderMatch, arg) {
4042
4034
  }
4043
4035
  return arg.defaultShouldRevalidate;
4044
4036
  }
4045
- /**
4046
- * Idempotent utility to execute patchRoutesOnNavigation() to lazily load route
4047
- * definitions and update the routes/routeManifest
4048
- */
4049
- async function loadLazyRouteChildren(patchRoutesOnNavigationImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) {
4050
- let key = [path, ...matches.map(m => m.route.id)].join("-");
4051
- try {
4052
- let pending = pendingRouteChildren.get(key);
4053
- if (!pending) {
4054
- pending = patchRoutesOnNavigationImpl({
4055
- path,
4056
- matches,
4057
- patch: (routeId, children) => {
4058
- if (!signal.aborted) {
4059
- patchRoutesImpl(routeId, children, routes, manifest, mapRouteProperties);
4060
- }
4061
- }
4062
- });
4063
- pendingRouteChildren.set(key, pending);
4064
- }
4065
- if (pending && isPromise(pending)) {
4066
- await pending;
4067
- }
4068
- } finally {
4069
- pendingRouteChildren.delete(key);
4070
- }
4071
- }
4072
4037
  function patchRoutesImpl(routeId, children, routesToUse, manifest, mapRouteProperties) {
4038
+ var _childrenToPatch;
4039
+ let childrenToPatch;
4073
4040
  if (routeId) {
4074
- var _route$children;
4075
4041
  let route = manifest[routeId];
4076
4042
  invariant(route, "No route found to patch children into: routeId = " + routeId);
4077
- let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, [routeId, "patch", String(((_route$children = route.children) == null ? void 0 : _route$children.length) || "0")], manifest);
4078
- if (route.children) {
4079
- route.children.push(...dataChildren);
4080
- } else {
4081
- route.children = dataChildren;
4043
+ if (!route.children) {
4044
+ route.children = [];
4082
4045
  }
4046
+ childrenToPatch = route.children;
4083
4047
  } else {
4084
- let dataChildren = convertRoutesToDataRoutes(children, mapRouteProperties, ["patch", String(routesToUse.length || "0")], manifest);
4085
- routesToUse.push(...dataChildren);
4048
+ childrenToPatch = routesToUse;
4049
+ }
4050
+ // Don't patch in routes we already know about so that `patch` is idempotent
4051
+ // to simplify user-land code. This is useful because we re-call the
4052
+ // `patchRoutesOnNavigation` function for matched routes with params.
4053
+ let uniqueChildren = children.filter(newRoute => !childrenToPatch.some(existingRoute => isSameRoute(newRoute, existingRoute)));
4054
+ let newRoutes = convertRoutesToDataRoutes(uniqueChildren, mapRouteProperties, [routeId || "_", "patch", String(((_childrenToPatch = childrenToPatch) == null ? void 0 : _childrenToPatch.length) || "0")], manifest);
4055
+ childrenToPatch.push(...newRoutes);
4056
+ }
4057
+ function isSameRoute(newRoute, existingRoute) {
4058
+ // Most optimal check is by id
4059
+ if ("id" in newRoute && "id" in existingRoute && newRoute.id === existingRoute.id) {
4060
+ return true;
4061
+ }
4062
+ // Second is by pathing differences
4063
+ if (!(newRoute.index === existingRoute.index && newRoute.path === existingRoute.path && newRoute.caseSensitive === existingRoute.caseSensitive)) {
4064
+ return false;
4086
4065
  }
4066
+ // Pathless layout routes are trickier since we need to check children.
4067
+ // If they have no children then they're the same as far as we can tell
4068
+ if ((!newRoute.children || newRoute.children.length === 0) && (!existingRoute.children || existingRoute.children.length === 0)) {
4069
+ return true;
4070
+ }
4071
+ // Otherwise, we look to see if every child in the new route is already
4072
+ // represented in the existing route's children
4073
+ return newRoute.children.every((aChild, i) => {
4074
+ var _existingRoute$childr;
4075
+ return (_existingRoute$childr = existingRoute.children) == null ? void 0 : _existingRoute$childr.some(bChild => isSameRoute(aChild, bChild));
4076
+ });
4087
4077
  }
4088
4078
  /**
4089
4079
  * Execute route.lazy() methods to lazily load route modules (loader, action,
@@ -4134,10 +4124,10 @@ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {
4134
4124
  }));
4135
4125
  }
4136
4126
  // Default implementation of `dataStrategy` which fetches all loaders in parallel
4137
- async function defaultDataStrategy(_ref6) {
4127
+ async function defaultDataStrategy(_ref4) {
4138
4128
  let {
4139
4129
  matches
4140
- } = _ref6;
4130
+ } = _ref4;
4141
4131
  let matchesToLoad = matches.filter(m => m.shouldLoad);
4142
4132
  let results = await Promise.all(matchesToLoad.map(m => m.resolve()));
4143
4133
  return results.reduce((acc, result, i) => Object.assign(acc, {
@@ -4346,7 +4336,7 @@ async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4346
4336
  statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status
4347
4337
  };
4348
4338
  }
4349
- // Convert thrown unstable_data() to ErrorResponse instances
4339
+ // Convert thrown data() to ErrorResponse instances
4350
4340
  result = new ErrorResponseImpl(((_result$init2 = result.init) == null ? void 0 : _result$init2.status) || 500, undefined, result.data);
4351
4341
  }
4352
4342
  return {
@@ -4540,7 +4530,7 @@ function processRouteLoaderData(matches, results, pendingActionResult, activeDef
4540
4530
  loaderHeaders
4541
4531
  };
4542
4532
  }
4543
- function processLoaderData(state, matches, matchesToLoad, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) {
4533
+ function processLoaderData(state, matches, results, pendingActionResult, revalidatingFetchers, fetcherResults, activeDeferreds) {
4544
4534
  let {
4545
4535
  loaderData,
4546
4536
  errors
@@ -4652,9 +4642,7 @@ function getInternalRouterError(status, _temp5) {
4652
4642
  let errorMessage = "Unknown @remix-run/router error";
4653
4643
  if (status === 400) {
4654
4644
  statusText = "Bad Request";
4655
- if (type === "route-discovery") {
4656
- errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnNavigation()` " + ("function threw the following error:\n" + message);
4657
- } else if (method && pathname && routeId) {
4645
+ if (method && pathname && routeId) {
4658
4646
  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.";
4659
4647
  } else if (type === "defer-action") {
4660
4648
  errorMessage = "defer() is not supported in actions";
@@ -4714,9 +4702,6 @@ function isHashChangeOnly(a, b) {
4714
4702
  // /page#hash -> /page
4715
4703
  return false;
4716
4704
  }
4717
- function isPromise(val) {
4718
- return typeof val === "object" && val != null && "then" in val;
4719
- }
4720
4705
  function isDataStrategyResult(result) {
4721
4706
  return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error);
4722
4707
  }
@@ -5014,5 +4999,5 @@ function persistAppliedTransitions(_window, transitions) {
5014
4999
  }
5015
5000
  //#endregion
5016
5001
 
5017
- 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 };
5002
+ 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, data, defer, generatePath, getStaticContextFromError, getToPathname, isDataWithResponseInit, isDeferredData, isRouteErrorResponse, joinPaths, json, matchPath, matchRoutes, normalizePathname, parsePath, redirect, redirectDocument, replace, resolvePath, resolveTo, stripBasename };
5018
5003
  //# sourceMappingURL=router.js.map