@remix-run/router 1.7.1 → 1.7.2-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/router.cjs.js +103 -42
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.js +102 -42
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +103 -42
- 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 +4 -1
- package/package.json +1 -1
- package/router.ts +82 -36
- package/utils.ts +22 -3
package/dist/router.umd.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.7.
|
|
2
|
+
* @remix-run/router v1.7.2-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1281,7 +1281,7 @@
|
|
|
1281
1281
|
|
|
1282
1282
|
// We store a little wrapper promise that will be extended with
|
|
1283
1283
|
// _data/_error props upon resolve/reject
|
|
1284
|
-
let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key,
|
|
1284
|
+
let promise = Promise.race([value, this.abortPromise]).then(data => this.onSettle(promise, key, undefined, data), error => this.onSettle(promise, key, error));
|
|
1285
1285
|
|
|
1286
1286
|
// Register rejection listeners to avoid uncaught promise rejections on
|
|
1287
1287
|
// errors or aborted deferred values
|
|
@@ -1304,7 +1304,18 @@
|
|
|
1304
1304
|
// Nothing left to abort!
|
|
1305
1305
|
this.unlistenAbortSignal();
|
|
1306
1306
|
}
|
|
1307
|
-
|
|
1307
|
+
|
|
1308
|
+
// If the promise was resolved/rejected with undefined, we'll throw an error as you
|
|
1309
|
+
// should always resolve with a value or null
|
|
1310
|
+
if (error === undefined && data === undefined) {
|
|
1311
|
+
let undefinedError = new Error("Deferred data for key \"" + key + "\" resolved/rejected with `undefined`, " + "you must resolve/reject with a value or `null`.");
|
|
1312
|
+
Object.defineProperty(promise, "_error", {
|
|
1313
|
+
get: () => undefinedError
|
|
1314
|
+
});
|
|
1315
|
+
this.emit(false, key);
|
|
1316
|
+
return Promise.reject(undefinedError);
|
|
1317
|
+
}
|
|
1318
|
+
if (data === undefined) {
|
|
1308
1319
|
Object.defineProperty(promise, "_error", {
|
|
1309
1320
|
get: () => error
|
|
1310
1321
|
});
|
|
@@ -2266,7 +2277,14 @@
|
|
|
2266
2277
|
// If any loaders returned a redirect Response, start a new REPLACE navigation
|
|
2267
2278
|
let redirect = findRedirect(results);
|
|
2268
2279
|
if (redirect) {
|
|
2269
|
-
|
|
2280
|
+
if (redirect.idx >= matchesToLoad.length) {
|
|
2281
|
+
// If this redirect came from a fetcher make sure we mark it in
|
|
2282
|
+
// fetchRedirectIds so it doesn't get revalidated on the next set of
|
|
2283
|
+
// loader executions
|
|
2284
|
+
let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;
|
|
2285
|
+
fetchRedirectIds.add(fetcherKey);
|
|
2286
|
+
}
|
|
2287
|
+
await startRedirectNavigation(state, redirect.result, {
|
|
2270
2288
|
replace
|
|
2271
2289
|
});
|
|
2272
2290
|
return {
|
|
@@ -2372,6 +2390,7 @@
|
|
|
2372
2390
|
let abortController = new AbortController();
|
|
2373
2391
|
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);
|
|
2374
2392
|
fetchControllers.set(key, abortController);
|
|
2393
|
+
let originatingLoadId = incrementingLoadId;
|
|
2375
2394
|
let actionResult = await callLoaderOrAction("action", fetchRequest, match, requestMatches, manifest, mapRouteProperties, basename);
|
|
2376
2395
|
if (fetchRequest.signal.aborted) {
|
|
2377
2396
|
// We can delete this so long as we weren't aborted by ou our own fetcher
|
|
@@ -2383,16 +2402,29 @@
|
|
|
2383
2402
|
}
|
|
2384
2403
|
if (isRedirectResult(actionResult)) {
|
|
2385
2404
|
fetchControllers.delete(key);
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2405
|
+
if (pendingNavigationLoadId > originatingLoadId) {
|
|
2406
|
+
// A new navigation was kicked off after our action started, so that
|
|
2407
|
+
// should take precedence over this redirect navigation. We already
|
|
2408
|
+
// set isRevalidationRequired so all loaders for the new route should
|
|
2409
|
+
// fire unless opted out via shouldRevalidate
|
|
2410
|
+
let doneFetcher = getDoneFetcher(undefined);
|
|
2411
|
+
state.fetchers.set(key, doneFetcher);
|
|
2412
|
+
updateState({
|
|
2413
|
+
fetchers: new Map(state.fetchers)
|
|
2414
|
+
});
|
|
2415
|
+
return;
|
|
2416
|
+
} else {
|
|
2417
|
+
fetchRedirectIds.add(key);
|
|
2418
|
+
let loadingFetcher = getLoadingFetcher(submission);
|
|
2419
|
+
state.fetchers.set(key, loadingFetcher);
|
|
2420
|
+
updateState({
|
|
2421
|
+
fetchers: new Map(state.fetchers)
|
|
2422
|
+
});
|
|
2423
|
+
return startRedirectNavigation(state, actionResult, {
|
|
2424
|
+
submission,
|
|
2425
|
+
isFetchActionRedirect: true
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2396
2428
|
}
|
|
2397
2429
|
|
|
2398
2430
|
// Process any non-redirect errors thrown
|
|
@@ -2456,7 +2488,14 @@
|
|
|
2456
2488
|
revalidatingFetchers.forEach(r => fetchControllers.delete(r.key));
|
|
2457
2489
|
let redirect = findRedirect(results);
|
|
2458
2490
|
if (redirect) {
|
|
2459
|
-
|
|
2491
|
+
if (redirect.idx >= matchesToLoad.length) {
|
|
2492
|
+
// If this redirect came from a fetcher make sure we mark it in
|
|
2493
|
+
// fetchRedirectIds so it doesn't get revalidated on the next set of
|
|
2494
|
+
// loader executions
|
|
2495
|
+
let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;
|
|
2496
|
+
fetchRedirectIds.add(fetcherKey);
|
|
2497
|
+
}
|
|
2498
|
+
return startRedirectNavigation(state, redirect.result);
|
|
2460
2499
|
}
|
|
2461
2500
|
|
|
2462
2501
|
// Process and commit output from loaders
|
|
@@ -2513,6 +2552,7 @@
|
|
|
2513
2552
|
let abortController = new AbortController();
|
|
2514
2553
|
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);
|
|
2515
2554
|
fetchControllers.set(key, abortController);
|
|
2555
|
+
let originatingLoadId = incrementingLoadId;
|
|
2516
2556
|
let result = await callLoaderOrAction("loader", fetchRequest, match, matches, manifest, mapRouteProperties, basename);
|
|
2517
2557
|
|
|
2518
2558
|
// Deferred isn't supported for fetcher loads, await everything and treat it
|
|
@@ -2534,9 +2574,20 @@
|
|
|
2534
2574
|
|
|
2535
2575
|
// If the loader threw a redirect Response, start a new REPLACE navigation
|
|
2536
2576
|
if (isRedirectResult(result)) {
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2577
|
+
if (pendingNavigationLoadId > originatingLoadId) {
|
|
2578
|
+
// A new navigation was kicked off after our loader started, so that
|
|
2579
|
+
// should take precedence over this redirect navigation
|
|
2580
|
+
let doneFetcher = getDoneFetcher(undefined);
|
|
2581
|
+
state.fetchers.set(key, doneFetcher);
|
|
2582
|
+
updateState({
|
|
2583
|
+
fetchers: new Map(state.fetchers)
|
|
2584
|
+
});
|
|
2585
|
+
return;
|
|
2586
|
+
} else {
|
|
2587
|
+
fetchRedirectIds.add(key);
|
|
2588
|
+
await startRedirectNavigation(state, result);
|
|
2589
|
+
return;
|
|
2590
|
+
}
|
|
2540
2591
|
}
|
|
2541
2592
|
|
|
2542
2593
|
// Process any non-redirect errors thrown
|
|
@@ -3573,7 +3624,9 @@
|
|
|
3573
3624
|
let fetcherMatches = matchRoutes(routesToUse, f.path, basename);
|
|
3574
3625
|
|
|
3575
3626
|
// If the fetcher path no longer matches, push it in with null matches so
|
|
3576
|
-
// we can trigger a 404 in callLoadersAndMaybeResolveData
|
|
3627
|
+
// we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is
|
|
3628
|
+
// currently only a use-case for Remix HMR where the route tree can change
|
|
3629
|
+
// at runtime and remove a route previously loaded via a fetcher
|
|
3577
3630
|
if (!fetcherMatches) {
|
|
3578
3631
|
revalidatingFetchers.push({
|
|
3579
3632
|
key,
|
|
@@ -3587,30 +3640,35 @@
|
|
|
3587
3640
|
}
|
|
3588
3641
|
|
|
3589
3642
|
// Revalidating fetchers are decoupled from the route matches since they
|
|
3590
|
-
// load from a static href. They
|
|
3591
|
-
//
|
|
3592
|
-
//
|
|
3593
|
-
// They automatically revalidate without even calling shouldRevalidate if:
|
|
3594
|
-
// - They were cancelled
|
|
3595
|
-
// - They're in the middle of their first load and therefore this is still
|
|
3596
|
-
// an initial load and not a revalidation
|
|
3597
|
-
//
|
|
3598
|
-
// If neither of those is true, then they _always_ check shouldRevalidate
|
|
3643
|
+
// load from a static href. They revalidate based on explicit revalidation
|
|
3644
|
+
// (submission, useRevalidator, or X-Remix-Revalidate)
|
|
3599
3645
|
let fetcher = state.fetchers.get(key);
|
|
3600
|
-
let isPerformingInitialLoad = fetcher && fetcher.state !== "idle" && fetcher.data === undefined &&
|
|
3601
|
-
// If a fetcher.load redirected then it'll be "loading" without any data
|
|
3602
|
-
// so ensure we're not processing the redirect from this fetcher
|
|
3603
|
-
!fetchRedirectIds.has(key);
|
|
3604
3646
|
let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
|
|
3605
|
-
let shouldRevalidate =
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3647
|
+
let shouldRevalidate = false;
|
|
3648
|
+
if (fetchRedirectIds.has(key)) {
|
|
3649
|
+
// Never trigger a revalidation of an actively redirecting fetcher
|
|
3650
|
+
shouldRevalidate = false;
|
|
3651
|
+
} else if (cancelledFetcherLoads.includes(key)) {
|
|
3652
|
+
// Always revalidate if the fetcher was cancelled
|
|
3653
|
+
shouldRevalidate = true;
|
|
3654
|
+
} else if (fetcher && fetcher.state !== "idle" && fetcher.data === undefined) {
|
|
3655
|
+
// If the fetcher hasn't ever completed loading yet, then this isn't a
|
|
3656
|
+
// revalidation, it would just be a brand new load if an explicit
|
|
3657
|
+
// revalidation is required
|
|
3658
|
+
shouldRevalidate = isRevalidationRequired;
|
|
3659
|
+
} else {
|
|
3660
|
+
// Otherwise fall back on any user-defined shouldRevalidate, defaulting
|
|
3661
|
+
// to explicit revalidations only
|
|
3662
|
+
shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({
|
|
3663
|
+
currentUrl,
|
|
3664
|
+
currentParams: state.matches[state.matches.length - 1].params,
|
|
3665
|
+
nextUrl,
|
|
3666
|
+
nextParams: matches[matches.length - 1].params
|
|
3667
|
+
}, submission, {
|
|
3668
|
+
actionResult,
|
|
3669
|
+
defaultShouldRevalidate: isRevalidationRequired
|
|
3670
|
+
}));
|
|
3671
|
+
}
|
|
3614
3672
|
if (shouldRevalidate) {
|
|
3615
3673
|
revalidatingFetchers.push({
|
|
3616
3674
|
key,
|
|
@@ -4128,7 +4186,10 @@
|
|
|
4128
4186
|
for (let i = results.length - 1; i >= 0; i--) {
|
|
4129
4187
|
let result = results[i];
|
|
4130
4188
|
if (isRedirectResult(result)) {
|
|
4131
|
-
return
|
|
4189
|
+
return {
|
|
4190
|
+
result,
|
|
4191
|
+
idx: i
|
|
4192
|
+
};
|
|
4132
4193
|
}
|
|
4133
4194
|
}
|
|
4134
4195
|
}
|