@remix-run/router 1.11.0-pre.0 → 1.11.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 +7 -3
- package/dist/router.cjs.js +54 -25
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +1 -0
- package/dist/router.js +52 -25
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +54 -25
- 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/package.json +1 -1
- package/router.ts +56 -24
package/package.json
CHANGED
package/router.ts
CHANGED
|
@@ -409,6 +409,7 @@ export interface RouterSubscriber {
|
|
|
409
409
|
(
|
|
410
410
|
state: RouterState,
|
|
411
411
|
opts: {
|
|
412
|
+
deletedFetchers: string[];
|
|
412
413
|
unstable_viewTransitionOpts?: ViewTransitionOpts;
|
|
413
414
|
}
|
|
414
415
|
): void;
|
|
@@ -887,6 +888,9 @@ export function createRouter(init: RouterInit): Router {
|
|
|
887
888
|
// Most recent href/match for fetcher.load calls for fetchers
|
|
888
889
|
let fetchLoadMatches = new Map<string, FetchLoadMatch>();
|
|
889
890
|
|
|
891
|
+
// Ref-count mounted fetchers so we know when it's ok to clean them up
|
|
892
|
+
let activeFetchers = new Map<string, number>();
|
|
893
|
+
|
|
890
894
|
// Fetchers that have requested a delete when using v7_fetcherPersist,
|
|
891
895
|
// they'll be officially removed after they return to idle
|
|
892
896
|
let deletedFetchers = new Set<string>();
|
|
@@ -1020,27 +1024,39 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1020
1024
|
...state,
|
|
1021
1025
|
...newState,
|
|
1022
1026
|
};
|
|
1023
|
-
subscribers.forEach((subscriber) =>
|
|
1024
|
-
subscriber(state, { unstable_viewTransitionOpts: viewTransitionOpts })
|
|
1025
|
-
);
|
|
1026
1027
|
|
|
1027
|
-
//
|
|
1028
|
+
// Prep fetcher cleanup so we can tell the UI which fetcher data entries
|
|
1029
|
+
// can be removed
|
|
1030
|
+
let completedFetchers: string[] = [];
|
|
1031
|
+
let deletedFetchersKeys: string[] = [];
|
|
1032
|
+
|
|
1028
1033
|
if (future.v7_fetcherPersist) {
|
|
1029
1034
|
state.fetchers.forEach((fetcher, key) => {
|
|
1030
1035
|
if (fetcher.state === "idle") {
|
|
1031
1036
|
if (deletedFetchers.has(key)) {
|
|
1032
|
-
//
|
|
1033
|
-
|
|
1034
|
-
deleteFetcher(key);
|
|
1037
|
+
// Unmounted from the UI and can be totally removed
|
|
1038
|
+
deletedFetchersKeys.push(key);
|
|
1035
1039
|
} else {
|
|
1036
|
-
//
|
|
1037
|
-
//
|
|
1038
|
-
|
|
1039
|
-
state.fetchers.delete(key);
|
|
1040
|
+
// Returned to idle but still mounted in the UI, so semi-remains for
|
|
1041
|
+
// revalidations and such
|
|
1042
|
+
completedFetchers.push(key);
|
|
1040
1043
|
}
|
|
1041
1044
|
}
|
|
1042
1045
|
});
|
|
1043
1046
|
}
|
|
1047
|
+
|
|
1048
|
+
subscribers.forEach((subscriber) =>
|
|
1049
|
+
subscriber(state, {
|
|
1050
|
+
deletedFetchers: deletedFetchersKeys,
|
|
1051
|
+
unstable_viewTransitionOpts: viewTransitionOpts,
|
|
1052
|
+
})
|
|
1053
|
+
);
|
|
1054
|
+
|
|
1055
|
+
// Remove idle fetchers from state since we only care about in-flight fetchers.
|
|
1056
|
+
if (future.v7_fetcherPersist) {
|
|
1057
|
+
completedFetchers.forEach((key) => state.fetchers.delete(key));
|
|
1058
|
+
deletedFetchersKeys.forEach((key) => deleteFetcher(key));
|
|
1059
|
+
}
|
|
1044
1060
|
}
|
|
1045
1061
|
|
|
1046
1062
|
// Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION
|
|
@@ -1749,6 +1765,14 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1749
1765
|
}
|
|
1750
1766
|
|
|
1751
1767
|
function getFetcher<TData = any>(key: string): Fetcher<TData> {
|
|
1768
|
+
if (future.v7_fetcherPersist) {
|
|
1769
|
+
activeFetchers.set(key, (activeFetchers.get(key) || 0) + 1);
|
|
1770
|
+
// If this fetcher was previously marked for deletion, unmark it since we
|
|
1771
|
+
// have a new instance
|
|
1772
|
+
if (deletedFetchers.has(key)) {
|
|
1773
|
+
deletedFetchers.delete(key);
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1752
1776
|
return state.fetchers.get(key) || IDLE_FETCHER;
|
|
1753
1777
|
}
|
|
1754
1778
|
|
|
@@ -1868,7 +1892,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1868
1892
|
);
|
|
1869
1893
|
|
|
1870
1894
|
if (fetchRequest.signal.aborted) {
|
|
1871
|
-
// We can delete this so long as we weren't aborted by
|
|
1895
|
+
// We can delete this so long as we weren't aborted by our own fetcher
|
|
1872
1896
|
// re-submit which would have put _new_ controller is in fetchControllers
|
|
1873
1897
|
if (fetchControllers.get(key) === abortController) {
|
|
1874
1898
|
fetchControllers.delete(key);
|
|
@@ -1876,6 +1900,12 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1876
1900
|
return;
|
|
1877
1901
|
}
|
|
1878
1902
|
|
|
1903
|
+
if (deletedFetchers.has(key)) {
|
|
1904
|
+
state.fetchers.set(key, getDoneFetcher(undefined));
|
|
1905
|
+
updateState({ fetchers: new Map(state.fetchers) });
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1879
1909
|
if (isRedirectResult(actionResult)) {
|
|
1880
1910
|
fetchControllers.delete(key);
|
|
1881
1911
|
if (pendingNavigationLoadId > originatingLoadId) {
|
|
@@ -2127,6 +2157,12 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2127
2157
|
return;
|
|
2128
2158
|
}
|
|
2129
2159
|
|
|
2160
|
+
if (deletedFetchers.has(key)) {
|
|
2161
|
+
state.fetchers.set(key, getDoneFetcher(undefined));
|
|
2162
|
+
updateState({ fetchers: new Map(state.fetchers) });
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2130
2166
|
// If the loader threw a redirect Response, start a new REPLACE navigation
|
|
2131
2167
|
if (isRedirectResult(result)) {
|
|
2132
2168
|
if (pendingNavigationLoadId > originatingLoadId) {
|
|
@@ -2145,17 +2181,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2145
2181
|
|
|
2146
2182
|
// Process any non-redirect errors thrown
|
|
2147
2183
|
if (isErrorResult(result)) {
|
|
2148
|
-
|
|
2149
|
-
state.fetchers.delete(key);
|
|
2150
|
-
// TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -
|
|
2151
|
-
// do we need to behave any differently with our non-redirect errors?
|
|
2152
|
-
// What if it was a non-redirect Response?
|
|
2153
|
-
updateState({
|
|
2154
|
-
fetchers: new Map(state.fetchers),
|
|
2155
|
-
errors: {
|
|
2156
|
-
[boundaryMatch.route.id]: result.error,
|
|
2157
|
-
},
|
|
2158
|
-
});
|
|
2184
|
+
setFetcherError(key, routeId, result.error);
|
|
2159
2185
|
return;
|
|
2160
2186
|
}
|
|
2161
2187
|
|
|
@@ -2404,7 +2430,13 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2404
2430
|
|
|
2405
2431
|
function deleteFetcherAndUpdateState(key: string): void {
|
|
2406
2432
|
if (future.v7_fetcherPersist) {
|
|
2407
|
-
|
|
2433
|
+
let count = (activeFetchers.get(key) || 0) - 1;
|
|
2434
|
+
if (count <= 0) {
|
|
2435
|
+
activeFetchers.delete(key);
|
|
2436
|
+
deletedFetchers.add(key);
|
|
2437
|
+
} else {
|
|
2438
|
+
activeFetchers.set(key, count);
|
|
2439
|
+
}
|
|
2408
2440
|
} else {
|
|
2409
2441
|
deleteFetcher(key);
|
|
2410
2442
|
}
|