@remix-run/router 1.3.0-pre.1 → 1.3.0-pre.2
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 +6 -0
- package/dist/history.d.ts +4 -0
- package/dist/router.cjs.js +248 -28
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +48 -2
- package/dist/router.js +248 -29
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +248 -28
- 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/history.ts +56 -12
- package/package.json +1 -1
- package/router.ts +253 -9
- package/utils.ts +1 -1
package/CHANGELOG.md
CHANGED
package/dist/history.d.ts
CHANGED
|
@@ -68,6 +68,10 @@ export interface Update {
|
|
|
68
68
|
* The new location.
|
|
69
69
|
*/
|
|
70
70
|
location: Location;
|
|
71
|
+
/**
|
|
72
|
+
* The delta between this location and the former location in the history stack
|
|
73
|
+
*/
|
|
74
|
+
delta: number;
|
|
71
75
|
}
|
|
72
76
|
/**
|
|
73
77
|
* A function that receives notifications about location changes.
|
package/dist/router.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.3.0-pre.
|
|
2
|
+
* @remix-run/router v1.3.0-pre.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -137,7 +137,8 @@ function createMemoryHistory(options) {
|
|
|
137
137
|
if (v5Compat && listener) {
|
|
138
138
|
listener({
|
|
139
139
|
action,
|
|
140
|
-
location: nextLocation
|
|
140
|
+
location: nextLocation,
|
|
141
|
+
delta: 1
|
|
141
142
|
});
|
|
142
143
|
}
|
|
143
144
|
},
|
|
@@ -150,19 +151,23 @@ function createMemoryHistory(options) {
|
|
|
150
151
|
if (v5Compat && listener) {
|
|
151
152
|
listener({
|
|
152
153
|
action,
|
|
153
|
-
location: nextLocation
|
|
154
|
+
location: nextLocation,
|
|
155
|
+
delta: 0
|
|
154
156
|
});
|
|
155
157
|
}
|
|
156
158
|
},
|
|
157
159
|
|
|
158
160
|
go(delta) {
|
|
159
161
|
action = exports.Action.Pop;
|
|
160
|
-
|
|
162
|
+
let nextIndex = clampIndex(index + delta);
|
|
163
|
+
let nextLocation = entries[nextIndex];
|
|
164
|
+
index = nextIndex;
|
|
161
165
|
|
|
162
166
|
if (listener) {
|
|
163
167
|
listener({
|
|
164
168
|
action,
|
|
165
|
-
location:
|
|
169
|
+
location: nextLocation,
|
|
170
|
+
delta
|
|
166
171
|
});
|
|
167
172
|
}
|
|
168
173
|
},
|
|
@@ -321,10 +326,11 @@ function createKey() {
|
|
|
321
326
|
*/
|
|
322
327
|
|
|
323
328
|
|
|
324
|
-
function getHistoryState(location) {
|
|
329
|
+
function getHistoryState(location, index) {
|
|
325
330
|
return {
|
|
326
331
|
usr: location.state,
|
|
327
|
-
key: location.key
|
|
332
|
+
key: location.key,
|
|
333
|
+
idx: index
|
|
328
334
|
};
|
|
329
335
|
}
|
|
330
336
|
/**
|
|
@@ -408,15 +414,45 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
408
414
|
let globalHistory = window.history;
|
|
409
415
|
let action = exports.Action.Pop;
|
|
410
416
|
let listener = null;
|
|
417
|
+
let index = getIndex(); // Index should only be null when we initialize. If not, it's because the
|
|
418
|
+
// user called history.pushState or history.replaceState directly, in which
|
|
419
|
+
// case we should log a warning as it will result in bugs.
|
|
420
|
+
|
|
421
|
+
if (index == null) {
|
|
422
|
+
index = 0;
|
|
423
|
+
globalHistory.replaceState(_extends({}, globalHistory.state, {
|
|
424
|
+
idx: index
|
|
425
|
+
}), "");
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function getIndex() {
|
|
429
|
+
let state = globalHistory.state || {
|
|
430
|
+
idx: null
|
|
431
|
+
};
|
|
432
|
+
return state.idx;
|
|
433
|
+
}
|
|
411
434
|
|
|
412
435
|
function handlePop() {
|
|
413
|
-
|
|
436
|
+
let nextAction = exports.Action.Pop;
|
|
437
|
+
let nextIndex = getIndex();
|
|
414
438
|
|
|
415
|
-
if (
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
439
|
+
if (nextIndex != null) {
|
|
440
|
+
let delta = nextIndex - index;
|
|
441
|
+
action = nextAction;
|
|
442
|
+
index = nextIndex;
|
|
443
|
+
|
|
444
|
+
if (listener) {
|
|
445
|
+
listener({
|
|
446
|
+
action,
|
|
447
|
+
location: history.location,
|
|
448
|
+
delta
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
} else {
|
|
452
|
+
warning$1(false, // TODO: Write up a doc that explains our blocking strategy in detail
|
|
453
|
+
// and link to it here so people can understand better what is going on
|
|
454
|
+
// and how to avoid it.
|
|
455
|
+
"You are trying to block a POP navigation to a location that was not " + "created by @remix-run/router. The block will fail silently in " + "production, but in general you should do all navigation with the " + "router (instead of using window.history.pushState directly) " + "to avoid this situation.");
|
|
420
456
|
}
|
|
421
457
|
}
|
|
422
458
|
|
|
@@ -424,7 +460,8 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
424
460
|
action = exports.Action.Push;
|
|
425
461
|
let location = createLocation(history.location, to, state);
|
|
426
462
|
if (validateLocation) validateLocation(location, to);
|
|
427
|
-
|
|
463
|
+
index = getIndex() + 1;
|
|
464
|
+
let historyState = getHistoryState(location, index);
|
|
428
465
|
let url = history.createHref(location); // try...catch because iOS limits us to 100 pushState calls :/
|
|
429
466
|
|
|
430
467
|
try {
|
|
@@ -438,7 +475,8 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
438
475
|
if (v5Compat && listener) {
|
|
439
476
|
listener({
|
|
440
477
|
action,
|
|
441
|
-
location: history.location
|
|
478
|
+
location: history.location,
|
|
479
|
+
delta: 1
|
|
442
480
|
});
|
|
443
481
|
}
|
|
444
482
|
}
|
|
@@ -447,14 +485,16 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options)
|
|
|
447
485
|
action = exports.Action.Replace;
|
|
448
486
|
let location = createLocation(history.location, to, state);
|
|
449
487
|
if (validateLocation) validateLocation(location, to);
|
|
450
|
-
|
|
488
|
+
index = getIndex();
|
|
489
|
+
let historyState = getHistoryState(location, index);
|
|
451
490
|
let url = history.createHref(location);
|
|
452
491
|
globalHistory.replaceState(historyState, "", url);
|
|
453
492
|
|
|
454
493
|
if (v5Compat && listener) {
|
|
455
494
|
listener({
|
|
456
495
|
action,
|
|
457
|
-
location: history.location
|
|
496
|
+
location: history.location,
|
|
497
|
+
delta: 0
|
|
458
498
|
});
|
|
459
499
|
}
|
|
460
500
|
}
|
|
@@ -990,7 +1030,7 @@ function warning(cond, message) {
|
|
|
990
1030
|
if (typeof console !== "undefined") console.warn(message);
|
|
991
1031
|
|
|
992
1032
|
try {
|
|
993
|
-
// Welcome to debugging
|
|
1033
|
+
// Welcome to debugging @remix-run/router!
|
|
994
1034
|
//
|
|
995
1035
|
// This error is thrown as a convenience so you can more easily
|
|
996
1036
|
// find the source for a warning that appears in the console by
|
|
@@ -1433,6 +1473,12 @@ const IDLE_FETCHER = {
|
|
|
1433
1473
|
formEncType: undefined,
|
|
1434
1474
|
formData: undefined
|
|
1435
1475
|
};
|
|
1476
|
+
const IDLE_BLOCKER = {
|
|
1477
|
+
state: "unblocked",
|
|
1478
|
+
proceed: undefined,
|
|
1479
|
+
reset: undefined,
|
|
1480
|
+
location: undefined
|
|
1481
|
+
};
|
|
1436
1482
|
const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
1437
1483
|
const isServer = !isBrowser; //#endregion
|
|
1438
1484
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1497,7 +1543,8 @@ function createRouter(init) {
|
|
|
1497
1543
|
loaderData: init.hydrationData && init.hydrationData.loaderData || {},
|
|
1498
1544
|
actionData: init.hydrationData && init.hydrationData.actionData || null,
|
|
1499
1545
|
errors: init.hydrationData && init.hydrationData.errors || initialErrors,
|
|
1500
|
-
fetchers: new Map()
|
|
1546
|
+
fetchers: new Map(),
|
|
1547
|
+
blockers: new Map()
|
|
1501
1548
|
}; // -- Stateful internal variables to manage navigations --
|
|
1502
1549
|
// Current navigation in progress (to be committed in completeNavigation)
|
|
1503
1550
|
|
|
@@ -1539,7 +1586,16 @@ function createRouter(init) {
|
|
|
1539
1586
|
// promise resolves we update loaderData. If a new navigation starts we
|
|
1540
1587
|
// cancel active deferreds for eliminated routes.
|
|
1541
1588
|
|
|
1542
|
-
let activeDeferreds = new Map(); //
|
|
1589
|
+
let activeDeferreds = new Map(); // We ony support a single active blocker at the moment since we don't have
|
|
1590
|
+
// any compelling use cases for multi-blocker yet
|
|
1591
|
+
|
|
1592
|
+
let activeBlocker = null; // Store blocker functions in a separate Map outside of router state since
|
|
1593
|
+
// we don't need to update UI state if they change
|
|
1594
|
+
|
|
1595
|
+
let blockerFunctions = new Map(); // Flag to ignore the next history update, so we can revert the URL change on
|
|
1596
|
+
// a POP navigation that was blocked by the user without touching router state
|
|
1597
|
+
|
|
1598
|
+
let ignoreNextHistoryUpdate = false; // Initialize the router, all side effects should be kicked off from here.
|
|
1543
1599
|
// Implemented as a Fluent API for ease of:
|
|
1544
1600
|
// let router = createRouter(init).initialize();
|
|
1545
1601
|
|
|
@@ -1549,8 +1605,54 @@ function createRouter(init) {
|
|
|
1549
1605
|
unlistenHistory = init.history.listen(_ref => {
|
|
1550
1606
|
let {
|
|
1551
1607
|
action: historyAction,
|
|
1552
|
-
location
|
|
1608
|
+
location,
|
|
1609
|
+
delta
|
|
1553
1610
|
} = _ref;
|
|
1611
|
+
|
|
1612
|
+
// Ignore this event if it was just us resetting the URL from a
|
|
1613
|
+
// blocked POP navigation
|
|
1614
|
+
if (ignoreNextHistoryUpdate) {
|
|
1615
|
+
ignoreNextHistoryUpdate = false;
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
let blockerKey = shouldBlockNavigation({
|
|
1620
|
+
currentLocation: state.location,
|
|
1621
|
+
nextLocation: location,
|
|
1622
|
+
historyAction
|
|
1623
|
+
});
|
|
1624
|
+
|
|
1625
|
+
if (blockerKey) {
|
|
1626
|
+
// Restore the URL to match the current UI, but don't update router state
|
|
1627
|
+
ignoreNextHistoryUpdate = true;
|
|
1628
|
+
init.history.go(delta * -1); // Put the blocker into a blocked state
|
|
1629
|
+
|
|
1630
|
+
updateBlocker(blockerKey, {
|
|
1631
|
+
state: "blocked",
|
|
1632
|
+
location,
|
|
1633
|
+
|
|
1634
|
+
proceed() {
|
|
1635
|
+
updateBlocker(blockerKey, {
|
|
1636
|
+
state: "proceeding",
|
|
1637
|
+
proceed: undefined,
|
|
1638
|
+
reset: undefined,
|
|
1639
|
+
location
|
|
1640
|
+
}); // Re-do the same POP navigation we just blocked
|
|
1641
|
+
|
|
1642
|
+
init.history.go(delta);
|
|
1643
|
+
},
|
|
1644
|
+
|
|
1645
|
+
reset() {
|
|
1646
|
+
deleteBlocker(blockerKey);
|
|
1647
|
+
updateState({
|
|
1648
|
+
blockers: new Map(router.state.blockers)
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
});
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1554
1656
|
return startNavigation(historyAction, location);
|
|
1555
1657
|
}); // Kick off initial data load if needed. Use Pop to avoid modifying history
|
|
1556
1658
|
|
|
@@ -1570,6 +1672,7 @@ function createRouter(init) {
|
|
|
1570
1672
|
subscribers.clear();
|
|
1571
1673
|
pendingNavigationController && pendingNavigationController.abort();
|
|
1572
1674
|
state.fetchers.forEach((_, key) => deleteFetcher(key));
|
|
1675
|
+
state.blockers.forEach((_, key) => deleteBlocker(key));
|
|
1573
1676
|
} // Subscribe to state updates for the router
|
|
1574
1677
|
|
|
1575
1678
|
|
|
@@ -1616,9 +1719,15 @@ function createRouter(init) {
|
|
|
1616
1719
|
} // Always preserve any existing loaderData from re-used routes
|
|
1617
1720
|
|
|
1618
1721
|
|
|
1619
|
-
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; //
|
|
1722
|
+
let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData; // On a successful navigation we can assume we got through all blockers
|
|
1723
|
+
// so we can start fresh
|
|
1724
|
+
|
|
1725
|
+
for (let [key] of blockerFunctions) {
|
|
1726
|
+
deleteBlocker(key);
|
|
1727
|
+
} // Always respect the user flag. Otherwise don't reset on mutation
|
|
1620
1728
|
// submission navigations unless they redirect
|
|
1621
1729
|
|
|
1730
|
+
|
|
1622
1731
|
let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;
|
|
1623
1732
|
updateState(_extends({}, newState, {
|
|
1624
1733
|
// matches, errors, fetchers go through as-is
|
|
@@ -1630,7 +1739,8 @@ function createRouter(init) {
|
|
|
1630
1739
|
navigation: IDLE_NAVIGATION,
|
|
1631
1740
|
revalidation: "idle",
|
|
1632
1741
|
restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches),
|
|
1633
|
-
preventScrollReset
|
|
1742
|
+
preventScrollReset,
|
|
1743
|
+
blockers: new Map(state.blockers)
|
|
1634
1744
|
}));
|
|
1635
1745
|
|
|
1636
1746
|
if (isUninterruptedRevalidation) ; else if (pendingAction === exports.Action.Pop) ; else if (pendingAction === exports.Action.Push) {
|
|
@@ -1661,13 +1771,14 @@ function createRouter(init) {
|
|
|
1661
1771
|
submission,
|
|
1662
1772
|
error
|
|
1663
1773
|
} = normalizeNavigateOptions(to, opts);
|
|
1664
|
-
let
|
|
1774
|
+
let currentLocation = state.location;
|
|
1775
|
+
let nextLocation = createLocation(state.location, path, opts && opts.state); // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded
|
|
1665
1776
|
// URL from window.location, so we need to encode it here so the behavior
|
|
1666
1777
|
// remains the same as POP and non-data-router usages. new URL() does all
|
|
1667
1778
|
// the same encoding we'd get from a history.pushState/window.location read
|
|
1668
1779
|
// without having to touch history
|
|
1669
1780
|
|
|
1670
|
-
|
|
1781
|
+
nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation));
|
|
1671
1782
|
let userReplace = opts && opts.replace != null ? opts.replace : undefined;
|
|
1672
1783
|
let historyAction = exports.Action.Push;
|
|
1673
1784
|
|
|
@@ -1682,7 +1793,41 @@ function createRouter(init) {
|
|
|
1682
1793
|
}
|
|
1683
1794
|
|
|
1684
1795
|
let preventScrollReset = opts && "preventScrollReset" in opts ? opts.preventScrollReset === true : undefined;
|
|
1685
|
-
|
|
1796
|
+
let blockerKey = shouldBlockNavigation({
|
|
1797
|
+
currentLocation,
|
|
1798
|
+
nextLocation,
|
|
1799
|
+
historyAction
|
|
1800
|
+
});
|
|
1801
|
+
|
|
1802
|
+
if (blockerKey) {
|
|
1803
|
+
// Put the blocker into a blocked state
|
|
1804
|
+
updateBlocker(blockerKey, {
|
|
1805
|
+
state: "blocked",
|
|
1806
|
+
location: nextLocation,
|
|
1807
|
+
|
|
1808
|
+
proceed() {
|
|
1809
|
+
updateBlocker(blockerKey, {
|
|
1810
|
+
state: "proceeding",
|
|
1811
|
+
proceed: undefined,
|
|
1812
|
+
reset: undefined,
|
|
1813
|
+
location: nextLocation
|
|
1814
|
+
}); // Send the same navigation through
|
|
1815
|
+
|
|
1816
|
+
navigate(to, opts);
|
|
1817
|
+
},
|
|
1818
|
+
|
|
1819
|
+
reset() {
|
|
1820
|
+
deleteBlocker(blockerKey);
|
|
1821
|
+
updateState({
|
|
1822
|
+
blockers: new Map(state.blockers)
|
|
1823
|
+
});
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
});
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
return await startNavigation(historyAction, nextLocation, {
|
|
1686
1831
|
submission,
|
|
1687
1832
|
// Send through the formData serialization error if we have one so we can
|
|
1688
1833
|
// render at the right error boundary after we match routes
|
|
@@ -2590,6 +2735,78 @@ function createRouter(init) {
|
|
|
2590
2735
|
return yeetedKeys.length > 0;
|
|
2591
2736
|
}
|
|
2592
2737
|
|
|
2738
|
+
function getBlocker(key, fn) {
|
|
2739
|
+
let blocker = state.blockers.get(key) || IDLE_BLOCKER;
|
|
2740
|
+
|
|
2741
|
+
if (blockerFunctions.get(key) !== fn) {
|
|
2742
|
+
blockerFunctions.set(key, fn);
|
|
2743
|
+
|
|
2744
|
+
if (activeBlocker == null) {
|
|
2745
|
+
// This is now the active blocker
|
|
2746
|
+
activeBlocker = key;
|
|
2747
|
+
} else if (key !== activeBlocker) {
|
|
2748
|
+
warning(false, "A router only supports one blocker at a time");
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
return blocker;
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
function deleteBlocker(key) {
|
|
2756
|
+
state.blockers.delete(key);
|
|
2757
|
+
blockerFunctions.delete(key);
|
|
2758
|
+
|
|
2759
|
+
if (activeBlocker === key) {
|
|
2760
|
+
activeBlocker = null;
|
|
2761
|
+
}
|
|
2762
|
+
} // Utility function to update blockers, ensuring valid state transitions
|
|
2763
|
+
|
|
2764
|
+
|
|
2765
|
+
function updateBlocker(key, newBlocker) {
|
|
2766
|
+
let blocker = state.blockers.get(key) || IDLE_BLOCKER; // Poor mans state machine :)
|
|
2767
|
+
// https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM
|
|
2768
|
+
|
|
2769
|
+
invariant(blocker.state === "unblocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "blocked" || blocker.state === "blocked" && newBlocker.state === "proceeding" || blocker.state === "blocked" && newBlocker.state === "unblocked" || blocker.state === "proceeding" && newBlocker.state === "unblocked", "Invalid blocker state transition: " + blocker.state + " -> " + newBlocker.state);
|
|
2770
|
+
state.blockers.set(key, newBlocker);
|
|
2771
|
+
updateState({
|
|
2772
|
+
blockers: new Map(state.blockers)
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
function shouldBlockNavigation(_ref10) {
|
|
2777
|
+
let {
|
|
2778
|
+
currentLocation,
|
|
2779
|
+
nextLocation,
|
|
2780
|
+
historyAction
|
|
2781
|
+
} = _ref10;
|
|
2782
|
+
|
|
2783
|
+
if (activeBlocker == null) {
|
|
2784
|
+
return;
|
|
2785
|
+
} // We only allow a single blocker at the moment. This will need to be
|
|
2786
|
+
// updated if we enhance to support multiple blockers in the future
|
|
2787
|
+
|
|
2788
|
+
|
|
2789
|
+
let blockerFunction = blockerFunctions.get(activeBlocker);
|
|
2790
|
+
invariant(blockerFunction, "Could not find a function for the active blocker");
|
|
2791
|
+
let blocker = state.blockers.get(activeBlocker);
|
|
2792
|
+
|
|
2793
|
+
if (blocker && blocker.state === "proceeding") {
|
|
2794
|
+
// If the blocker is currently proceeding, we don't need to re-check
|
|
2795
|
+
// it and can let this navigation continue
|
|
2796
|
+
return;
|
|
2797
|
+
} // At this point, we know we're unblocked/blocked so we need to check the
|
|
2798
|
+
// user-provided blocker function
|
|
2799
|
+
|
|
2800
|
+
|
|
2801
|
+
if (blockerFunction({
|
|
2802
|
+
currentLocation,
|
|
2803
|
+
nextLocation,
|
|
2804
|
+
historyAction
|
|
2805
|
+
})) {
|
|
2806
|
+
return activeBlocker;
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2593
2810
|
function cancelActiveDeferreds(predicate) {
|
|
2594
2811
|
let cancelledRouteIds = [];
|
|
2595
2812
|
activeDeferreds.forEach((dfd, routeId) => {
|
|
@@ -2682,6 +2899,8 @@ function createRouter(init) {
|
|
|
2682
2899
|
getFetcher,
|
|
2683
2900
|
deleteFetcher,
|
|
2684
2901
|
dispose,
|
|
2902
|
+
getBlocker,
|
|
2903
|
+
deleteBlocker,
|
|
2685
2904
|
_internalFetchControllers: fetchControllers,
|
|
2686
2905
|
_internalActiveDeferreds: activeDeferreds
|
|
2687
2906
|
};
|
|
@@ -3202,8 +3421,8 @@ function getMatchesToLoad(history, state, matches, submission, location, isReval
|
|
|
3202
3421
|
cancelledDeferredRoutes.some(id => id === match.route.id) || shouldRevalidateLoader(history, state.location, state.matches[index], submission, location, match, isRevalidationRequired, actionResult))); // Pick fetcher.loads that need to be revalidated
|
|
3203
3422
|
|
|
3204
3423
|
let revalidatingFetchers = [];
|
|
3205
|
-
fetchLoadMatches && fetchLoadMatches.forEach((
|
|
3206
|
-
let [href, match, fetchMatches] =
|
|
3424
|
+
fetchLoadMatches && fetchLoadMatches.forEach((_ref11, key) => {
|
|
3425
|
+
let [href, match, fetchMatches] = _ref11;
|
|
3207
3426
|
|
|
3208
3427
|
// This fetcher was cancelled from a prior action submission - force reload
|
|
3209
3428
|
if (cancelledFetcherLoads.includes(key)) {
|
|
@@ -3805,6 +4024,7 @@ function getTargetMatch(matches, location) {
|
|
|
3805
4024
|
|
|
3806
4025
|
exports.AbortedDeferredError = AbortedDeferredError;
|
|
3807
4026
|
exports.ErrorResponse = ErrorResponse;
|
|
4027
|
+
exports.IDLE_BLOCKER = IDLE_BLOCKER;
|
|
3808
4028
|
exports.IDLE_FETCHER = IDLE_FETCHER;
|
|
3809
4029
|
exports.IDLE_NAVIGATION = IDLE_NAVIGATION;
|
|
3810
4030
|
exports.UNSAFE_DEFERRED_SYMBOL = UNSAFE_DEFERRED_SYMBOL;
|