@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/CHANGELOG.md +33 -0
- package/dist/index.d.ts +2 -2
- package/dist/router.cjs.js +194 -204
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +8 -8
- package/dist/router.js +186 -201
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +194 -204
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/dist/utils.d.ts +6 -7
- package/index.ts +7 -6
- package/package.json +1 -1
- package/router.ts +244 -252
- package/utils.ts +14 -8
package/dist/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.
|
|
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.
|
|
1366
|
-
let patchRoutesOnNavigationImpl = init.
|
|
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(
|
|
1451
|
+
initialized = initialMatches.slice(0, idx + 1).every(m => !shouldLoadRouteOnHydration(m.route, loaderData, errors));
|
|
1468
1452
|
} else {
|
|
1469
|
-
initialized = initialMatches.every(
|
|
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
|
-
|
|
1681
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
//
|
|
2295
|
+
// Preserve SSR errors during partial hydration
|
|
2323
2296
|
if (future.v7_partialHydration && initialHydration && state.errors) {
|
|
2324
|
-
|
|
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
|
-
|
|
2375
|
-
let flushSync = (opts && opts.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
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(
|
|
2968
|
+
function shouldBlockNavigation(_ref2) {
|
|
3003
2969
|
let {
|
|
3004
2970
|
currentLocation,
|
|
3005
2971
|
nextLocation,
|
|
3006
2972
|
historyAction
|
|
3007
|
-
} =
|
|
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
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
3656
|
-
let results = await callDataStrategyImpl(
|
|
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
|
-
//
|
|
3738
|
-
if ((to == null || to === "" || to === ".") && activeRouteMatch
|
|
3739
|
-
|
|
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,
|
|
3786
|
-
let [name, value] =
|
|
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
|
-
|
|
3878
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
3892
|
-
|
|
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 (
|
|
3910
|
-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
4078
|
-
|
|
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
|
-
|
|
4085
|
-
|
|
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(
|
|
4127
|
+
async function defaultDataStrategy(_ref4) {
|
|
4138
4128
|
let {
|
|
4139
4129
|
matches
|
|
4140
|
-
} =
|
|
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
|
|
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,
|
|
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 (
|
|
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
|
|
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
|