@remix-run/router 1.6.2 → 1.6.3
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 +754 -854
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +1 -0
- package/dist/router.js +440 -946
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +754 -854
- 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 +7 -0
- package/package.json +1 -1
- package/router.ts +49 -31
package/history.ts
CHANGED
|
@@ -634,6 +634,13 @@ function getUrlBasedHistory(
|
|
|
634
634
|
try {
|
|
635
635
|
globalHistory.pushState(historyState, "", url);
|
|
636
636
|
} catch (error) {
|
|
637
|
+
// If the exception is because `state` can't be serialized, let that throw
|
|
638
|
+
// outwards just like a replace call would so the dev knows the cause
|
|
639
|
+
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps
|
|
640
|
+
// https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal
|
|
641
|
+
if (error instanceof DOMException && error.name === "DataCloneError") {
|
|
642
|
+
throw error;
|
|
643
|
+
}
|
|
637
644
|
// They are going to lose state here, but there is no real
|
|
638
645
|
// way to warn them about it since the page will refresh...
|
|
639
646
|
window.location.assign(url);
|
package/package.json
CHANGED
package/router.ts
CHANGED
|
@@ -352,6 +352,7 @@ export interface RouterInit {
|
|
|
352
352
|
mapRouteProperties?: MapRoutePropertiesFunction;
|
|
353
353
|
future?: Partial<FutureConfig>;
|
|
354
354
|
hydrationData?: HydrationState;
|
|
355
|
+
window?: Window;
|
|
355
356
|
}
|
|
356
357
|
|
|
357
358
|
/**
|
|
@@ -661,12 +662,6 @@ export const IDLE_BLOCKER: BlockerUnblocked = {
|
|
|
661
662
|
|
|
662
663
|
const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
663
664
|
|
|
664
|
-
const isBrowser =
|
|
665
|
-
typeof window !== "undefined" &&
|
|
666
|
-
typeof window.document !== "undefined" &&
|
|
667
|
-
typeof window.document.createElement !== "undefined";
|
|
668
|
-
const isServer = !isBrowser;
|
|
669
|
-
|
|
670
665
|
const defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({
|
|
671
666
|
hasErrorBoundary: Boolean(route.hasErrorBoundary),
|
|
672
667
|
});
|
|
@@ -681,6 +676,17 @@ const defaultMapRouteProperties: MapRoutePropertiesFunction = (route) => ({
|
|
|
681
676
|
* Create a router and listen to history POP navigations
|
|
682
677
|
*/
|
|
683
678
|
export function createRouter(init: RouterInit): Router {
|
|
679
|
+
const routerWindow = init.window
|
|
680
|
+
? init.window
|
|
681
|
+
: typeof window !== "undefined"
|
|
682
|
+
? window
|
|
683
|
+
: undefined;
|
|
684
|
+
const isBrowser =
|
|
685
|
+
typeof routerWindow !== "undefined" &&
|
|
686
|
+
typeof routerWindow.document !== "undefined" &&
|
|
687
|
+
typeof routerWindow.document.createElement !== "undefined";
|
|
688
|
+
const isServer = !isBrowser;
|
|
689
|
+
|
|
684
690
|
invariant(
|
|
685
691
|
init.routes.length > 0,
|
|
686
692
|
"You must provide a non-empty routes array to createRouter"
|
|
@@ -1225,13 +1231,15 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1225
1231
|
return;
|
|
1226
1232
|
}
|
|
1227
1233
|
|
|
1228
|
-
// Short circuit if it's only a hash change and not a
|
|
1234
|
+
// Short circuit if it's only a hash change and not a revalidation or
|
|
1235
|
+
// mutation submission.
|
|
1236
|
+
//
|
|
1229
1237
|
// Ignore on initial page loads because since the initial load will always
|
|
1230
|
-
// be "same hash".
|
|
1231
|
-
//
|
|
1232
|
-
// default to a navigation to /page
|
|
1238
|
+
// be "same hash". For example, on /page#hash and submit a <Form method="post">
|
|
1239
|
+
// which will default to a navigation to /page
|
|
1233
1240
|
if (
|
|
1234
1241
|
state.initialized &&
|
|
1242
|
+
!isRevalidationRequired &&
|
|
1235
1243
|
isHashChangeOnly(state.location, location) &&
|
|
1236
1244
|
!(opts && opts.submission && isMutationMethod(opts.submission.formMethod))
|
|
1237
1245
|
) {
|
|
@@ -1775,7 +1783,6 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1775
1783
|
let nextLocation = state.navigation.location || state.location;
|
|
1776
1784
|
let revalidationRequest = createClientSideRequest(
|
|
1777
1785
|
init.history,
|
|
1778
|
-
|
|
1779
1786
|
nextLocation,
|
|
1780
1787
|
abortController.signal
|
|
1781
1788
|
);
|
|
@@ -1886,16 +1893,20 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1886
1893
|
activeDeferreds
|
|
1887
1894
|
);
|
|
1888
1895
|
|
|
1889
|
-
let
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1896
|
+
// Since we let revalidations complete even if the submitting fetcher was
|
|
1897
|
+
// deleted, only put it back to idle if it hasn't been deleted
|
|
1898
|
+
if (state.fetchers.has(key)) {
|
|
1899
|
+
let doneFetcher: FetcherStates["Idle"] = {
|
|
1900
|
+
state: "idle",
|
|
1901
|
+
data: actionResult.data,
|
|
1902
|
+
formMethod: undefined,
|
|
1903
|
+
formAction: undefined,
|
|
1904
|
+
formEncType: undefined,
|
|
1905
|
+
formData: undefined,
|
|
1906
|
+
" _hasFetcherDoneAnything ": true,
|
|
1907
|
+
};
|
|
1908
|
+
state.fetchers.set(key, doneFetcher);
|
|
1909
|
+
}
|
|
1899
1910
|
|
|
1900
1911
|
let didAbortFetchLoads = abortStaleFetchLoads(loadId);
|
|
1901
1912
|
|
|
@@ -1927,7 +1938,9 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1927
1938
|
matches,
|
|
1928
1939
|
errors
|
|
1929
1940
|
),
|
|
1930
|
-
...(didAbortFetchLoads
|
|
1941
|
+
...(didAbortFetchLoads || revalidatingFetchers.length > 0
|
|
1942
|
+
? { fetchers: new Map(state.fetchers) }
|
|
1943
|
+
: {}),
|
|
1931
1944
|
});
|
|
1932
1945
|
isRevalidationRequired = false;
|
|
1933
1946
|
}
|
|
@@ -2085,19 +2098,15 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2085
2098
|
"Expected a location on the redirect navigation"
|
|
2086
2099
|
);
|
|
2087
2100
|
// Check if this an absolute external redirect that goes to a new origin
|
|
2088
|
-
if (
|
|
2089
|
-
ABSOLUTE_URL_REGEX.test(redirect.location) &&
|
|
2090
|
-
isBrowser &&
|
|
2091
|
-
typeof window?.location !== "undefined"
|
|
2092
|
-
) {
|
|
2101
|
+
if (ABSOLUTE_URL_REGEX.test(redirect.location) && isBrowser) {
|
|
2093
2102
|
let url = init.history.createURL(redirect.location);
|
|
2094
2103
|
let isDifferentBasename = stripBasename(url.pathname, basename) == null;
|
|
2095
2104
|
|
|
2096
|
-
if (
|
|
2105
|
+
if (routerWindow.location.origin !== url.origin || isDifferentBasename) {
|
|
2097
2106
|
if (replace) {
|
|
2098
|
-
|
|
2107
|
+
routerWindow.location.replace(redirect.location);
|
|
2099
2108
|
} else {
|
|
2100
|
-
|
|
2109
|
+
routerWindow.location.assign(redirect.location);
|
|
2101
2110
|
}
|
|
2102
2111
|
return;
|
|
2103
2112
|
}
|
|
@@ -2267,7 +2276,16 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2267
2276
|
}
|
|
2268
2277
|
|
|
2269
2278
|
function deleteFetcher(key: string): void {
|
|
2270
|
-
|
|
2279
|
+
let fetcher = state.fetchers.get(key);
|
|
2280
|
+
// Don't abort the controller if this is a deletion of a fetcher.submit()
|
|
2281
|
+
// in it's loading phase since - we don't want to abort the corresponding
|
|
2282
|
+
// revalidation and want them to complete and land
|
|
2283
|
+
if (
|
|
2284
|
+
fetchControllers.has(key) &&
|
|
2285
|
+
!(fetcher && fetcher.state === "loading" && fetchReloadIds.has(key))
|
|
2286
|
+
) {
|
|
2287
|
+
abortFetcher(key);
|
|
2288
|
+
}
|
|
2271
2289
|
fetchLoadMatches.delete(key);
|
|
2272
2290
|
fetchReloadIds.delete(key);
|
|
2273
2291
|
fetchRedirectIds.delete(key);
|