@tanstack/solid-router 2.0.0-alpha.6 → 2.0.0-alpha.7
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/dist/cjs/Asset.cjs +2 -2
- package/dist/cjs/Asset.cjs.map +1 -1
- package/dist/cjs/HeadContent.cjs +11 -1
- package/dist/cjs/HeadContent.cjs.map +1 -1
- package/dist/cjs/HeadContent.dev.cjs +11 -1
- package/dist/cjs/HeadContent.dev.cjs.map +1 -1
- package/dist/cjs/Match.cjs +265 -248
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Match.d.cts +1 -3
- package/dist/cjs/Matches.cjs +35 -34
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/RouterProvider.cjs +12 -8
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +1 -1
- package/dist/cjs/Scripts.cjs +23 -12
- package/dist/cjs/Scripts.cjs.map +1 -1
- package/dist/cjs/Scripts.d.cts +2 -1
- package/dist/cjs/Transitioner.cjs +55 -34
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/headContentUtils.cjs +26 -23
- package/dist/cjs/headContentUtils.cjs.map +1 -1
- package/dist/cjs/headContentUtils.d.cts +2 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.dev.cjs +1 -1
- package/dist/cjs/link.cjs +143 -101
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/matchContext.cjs +7 -5
- package/dist/cjs/matchContext.cjs.map +1 -1
- package/dist/cjs/matchContext.d.cts +8 -2
- package/dist/cjs/not-found.cjs +8 -4
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/not-found.d.cts +1 -1
- package/dist/cjs/router.cjs +2 -1
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/routerStores.cjs +75 -0
- package/dist/cjs/routerStores.cjs.map +1 -0
- package/dist/cjs/routerStores.d.cts +10 -0
- package/dist/cjs/ssr/RouterClient.cjs +1 -1
- package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
- package/dist/cjs/ssr/renderRouterToStream.cjs +1 -1
- package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
- package/dist/cjs/ssr/renderRouterToString.cjs +1 -1
- package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
- package/dist/cjs/useBlocker.cjs +12 -3
- package/dist/cjs/useBlocker.cjs.map +1 -1
- package/dist/cjs/useCanGoBack.cjs +6 -2
- package/dist/cjs/useCanGoBack.cjs.map +1 -1
- package/dist/cjs/useCanGoBack.d.cts +2 -1
- package/dist/cjs/useLoaderDeps.cjs +2 -3
- package/dist/cjs/useLoaderDeps.cjs.map +1 -1
- package/dist/cjs/useLocation.cjs +13 -2
- package/dist/cjs/useLocation.cjs.map +1 -1
- package/dist/cjs/useMatch.cjs +27 -15
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/useParams.cjs +1 -1
- package/dist/cjs/useParams.cjs.map +1 -1
- package/dist/cjs/useRouterState.cjs +12 -30
- package/dist/cjs/useRouterState.cjs.map +1 -1
- package/dist/cjs/useSearch.cjs +2 -1
- package/dist/cjs/useSearch.cjs.map +1 -1
- package/dist/cjs/utils.cjs +3 -17
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +0 -5
- package/dist/esm/Asset.js +6 -6
- package/dist/esm/Asset.js.map +1 -1
- package/dist/esm/HeadContent.dev.js +12 -2
- package/dist/esm/HeadContent.dev.js.map +1 -1
- package/dist/esm/HeadContent.js +12 -2
- package/dist/esm/HeadContent.js.map +1 -1
- package/dist/esm/Match.d.ts +1 -3
- package/dist/esm/Match.js +267 -250
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.js +40 -39
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.d.ts +1 -1
- package/dist/esm/RouterProvider.js +10 -7
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/ScriptOnce.js +2 -2
- package/dist/esm/ScriptOnce.js.map +1 -1
- package/dist/esm/Scripts.d.ts +2 -1
- package/dist/esm/Scripts.js +21 -11
- package/dist/esm/Scripts.js.map +1 -1
- package/dist/esm/Transitioner.js +56 -35
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/headContentUtils.d.ts +2 -1
- package/dist/esm/headContentUtils.js +26 -23
- package/dist/esm/headContentUtils.js.map +1 -1
- package/dist/esm/index.dev.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/link.js +146 -104
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/matchContext.d.ts +8 -2
- package/dist/esm/matchContext.js +7 -4
- package/dist/esm/matchContext.js.map +1 -1
- package/dist/esm/not-found.d.ts +1 -1
- package/dist/esm/not-found.js +6 -3
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/router.js +2 -1
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerStores.d.ts +10 -0
- package/dist/esm/routerStores.js +73 -0
- package/dist/esm/routerStores.js.map +1 -0
- package/dist/esm/scroll-restoration.js +2 -2
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/ssr/RouterClient.js +1 -1
- package/dist/esm/ssr/RouterClient.js.map +1 -1
- package/dist/esm/ssr/renderRouterToStream.js +1 -1
- package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
- package/dist/esm/ssr/renderRouterToString.js +1 -1
- package/dist/esm/ssr/renderRouterToString.js.map +1 -1
- package/dist/esm/useBlocker.js +12 -3
- package/dist/esm/useBlocker.js.map +1 -1
- package/dist/esm/useCanGoBack.d.ts +2 -1
- package/dist/esm/useCanGoBack.js +4 -2
- package/dist/esm/useCanGoBack.js.map +1 -1
- package/dist/esm/useLoaderDeps.js +2 -3
- package/dist/esm/useLoaderDeps.js.map +1 -1
- package/dist/esm/useLocation.js +11 -2
- package/dist/esm/useLocation.js.map +1 -1
- package/dist/esm/useMatch.js +28 -16
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useParams.js +1 -1
- package/dist/esm/useParams.js.map +1 -1
- package/dist/esm/useRouterState.js +11 -30
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/esm/useSearch.js +2 -1
- package/dist/esm/useSearch.js.map +1 -1
- package/dist/esm/utils.d.ts +0 -5
- package/dist/esm/utils.js +4 -17
- package/dist/esm/utils.js.map +1 -1
- package/dist/source/Asset.jsx +3 -3
- package/dist/source/Asset.jsx.map +1 -1
- package/dist/source/HeadContent.dev.jsx +5 -1
- package/dist/source/HeadContent.dev.jsx.map +1 -1
- package/dist/source/HeadContent.jsx +5 -1
- package/dist/source/HeadContent.jsx.map +1 -1
- package/dist/source/Match.d.ts +1 -3
- package/dist/source/Match.jsx +260 -264
- package/dist/source/Match.jsx.map +1 -1
- package/dist/source/Matches.jsx +46 -46
- package/dist/source/Matches.jsx.map +1 -1
- package/dist/source/RouterProvider.d.ts +1 -1
- package/dist/source/RouterProvider.jsx +13 -9
- package/dist/source/RouterProvider.jsx.map +1 -1
- package/dist/source/Scripts.d.ts +2 -1
- package/dist/source/Scripts.jsx +46 -47
- package/dist/source/Scripts.jsx.map +1 -1
- package/dist/source/Transitioner.jsx +78 -42
- package/dist/source/Transitioner.jsx.map +1 -1
- package/dist/source/headContentUtils.d.ts +2 -1
- package/dist/source/headContentUtils.jsx +79 -80
- package/dist/source/headContentUtils.jsx.map +1 -1
- package/dist/source/link.jsx +145 -112
- package/dist/source/link.jsx.map +1 -1
- package/dist/source/matchContext.d.ts +8 -2
- package/dist/source/matchContext.jsx +7 -3
- package/dist/source/matchContext.jsx.map +1 -1
- package/dist/source/not-found.d.ts +1 -1
- package/dist/source/not-found.jsx +6 -5
- package/dist/source/not-found.jsx.map +1 -1
- package/dist/source/router.js +2 -1
- package/dist/source/router.js.map +1 -1
- package/dist/source/routerStores.d.ts +10 -0
- package/dist/source/routerStores.js +82 -0
- package/dist/source/routerStores.js.map +1 -0
- package/dist/source/ssr/RouterClient.jsx +1 -1
- package/dist/source/ssr/RouterClient.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToStream.jsx +1 -1
- package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToString.jsx +1 -1
- package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
- package/dist/source/useBlocker.jsx +19 -8
- package/dist/source/useBlocker.jsx.map +1 -1
- package/dist/source/useCanGoBack.d.ts +2 -1
- package/dist/source/useCanGoBack.js +4 -2
- package/dist/source/useCanGoBack.js.map +1 -1
- package/dist/source/useLoaderDeps.jsx +2 -3
- package/dist/source/useLoaderDeps.jsx.map +1 -1
- package/dist/source/useLocation.jsx +13 -3
- package/dist/source/useLocation.jsx.map +1 -1
- package/dist/source/useMatch.jsx +33 -23
- package/dist/source/useMatch.jsx.map +1 -1
- package/dist/source/useParams.jsx +1 -1
- package/dist/source/useParams.jsx.map +1 -1
- package/dist/source/useRouterState.jsx +14 -55
- package/dist/source/useRouterState.jsx.map +1 -1
- package/dist/source/useSearch.jsx +2 -1
- package/dist/source/useSearch.jsx.map +1 -1
- package/dist/source/utils.d.ts +0 -5
- package/dist/source/utils.js +2 -15
- package/dist/source/utils.js.map +1 -1
- package/package.json +2 -2
- package/skills/solid-router/SKILL.md +2 -0
- package/src/Asset.tsx +3 -3
- package/src/HeadContent.dev.tsx +10 -1
- package/src/HeadContent.tsx +10 -1
- package/src/Match.tsx +395 -349
- package/src/Matches.tsx +55 -54
- package/src/RouterProvider.tsx +13 -10
- package/src/Scripts.tsx +55 -54
- package/src/Transitioner.tsx +101 -58
- package/src/headContentUtils.tsx +104 -96
- package/src/link.tsx +188 -146
- package/src/matchContext.tsx +16 -7
- package/src/not-found.tsx +6 -6
- package/src/router.ts +2 -1
- package/src/routerStores.ts +119 -0
- package/src/ssr/RouterClient.tsx +1 -1
- package/src/ssr/renderRouterToStream.tsx +1 -1
- package/src/ssr/renderRouterToString.tsx +1 -1
- package/src/useBlocker.tsx +80 -63
- package/src/useCanGoBack.ts +6 -2
- package/src/useLoaderDeps.tsx +2 -3
- package/src/useLocation.tsx +18 -5
- package/src/useMatch.tsx +37 -38
- package/src/useParams.tsx +2 -3
- package/src/useRouterState.tsx +21 -67
- package/src/useSearch.tsx +2 -1
- package/src/utils.ts +2 -24
package/dist/source/Match.jsx
CHANGED
|
@@ -5,100 +5,116 @@ import { createControlledPromise, getLocationChangeInfo, isNotFound, isRedirect,
|
|
|
5
5
|
import { isServer } from '@tanstack/router-core/isServer';
|
|
6
6
|
import { Dynamic } from '@solidjs/web';
|
|
7
7
|
import { CatchBoundary, ErrorComponent } from './CatchBoundary';
|
|
8
|
-
import { useRouterState } from './useRouterState';
|
|
9
8
|
import { useRouter } from './useRouter';
|
|
10
9
|
import { CatchNotFound } from './not-found';
|
|
11
|
-
import {
|
|
10
|
+
import { nearestMatchContext } from './matchContext';
|
|
12
11
|
import { SafeFragment } from './SafeFragment';
|
|
13
12
|
import { renderRouteNotFound } from './renderRouteNotFound';
|
|
14
13
|
import { ScrollRestoration } from './scroll-restoration';
|
|
15
|
-
const
|
|
14
|
+
const NearestMatchContext = nearestMatchContext;
|
|
16
15
|
export const Match = (props) => {
|
|
17
16
|
const router = useRouter();
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (!match) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
return {
|
|
27
|
-
routeId: match.routeId,
|
|
28
|
-
ssr: match.ssr,
|
|
29
|
-
_displayPending: match._displayPending,
|
|
30
|
-
};
|
|
31
|
-
},
|
|
17
|
+
const match = Solid.createMemo(() => {
|
|
18
|
+
const id = props.matchId;
|
|
19
|
+
if (!id)
|
|
20
|
+
return undefined;
|
|
21
|
+
return router.stores.activeMatchStoresById.get(id)?.state;
|
|
32
22
|
});
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const ResolvedNotFoundBoundary = () => routeNotFoundComponent() ? CatchNotFound : SafeFragment;
|
|
49
|
-
const resetKey = useRouterState({
|
|
50
|
-
select: (s) => s.loadedAt,
|
|
23
|
+
const rawMatchState = Solid.createMemo(() => {
|
|
24
|
+
const currentMatch = match();
|
|
25
|
+
if (!currentMatch) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const routeId = currentMatch.routeId;
|
|
29
|
+
const parentRouteId = router.routesById[routeId]?.parentRoute
|
|
30
|
+
?.id;
|
|
31
|
+
return {
|
|
32
|
+
matchId: currentMatch.id,
|
|
33
|
+
routeId,
|
|
34
|
+
ssr: currentMatch.ssr,
|
|
35
|
+
_displayPending: currentMatch._displayPending,
|
|
36
|
+
parentRouteId: parentRouteId,
|
|
37
|
+
};
|
|
51
38
|
});
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
39
|
+
const hasPendingMatch = Solid.createMemo(() => {
|
|
40
|
+
const currentRouteId = rawMatchState()?.routeId;
|
|
41
|
+
return currentRouteId
|
|
42
|
+
? Boolean(router.stores.pendingRouteIds.state[currentRouteId])
|
|
43
|
+
: false;
|
|
57
44
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
routeOnCatch()
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
45
|
+
const nearestMatch = {
|
|
46
|
+
matchId: () => rawMatchState()?.matchId,
|
|
47
|
+
routeId: () => rawMatchState()?.routeId,
|
|
48
|
+
match,
|
|
49
|
+
hasPending: hasPendingMatch,
|
|
50
|
+
};
|
|
51
|
+
return (<Solid.Show when={rawMatchState()}>
|
|
52
|
+
{(currentMatchState) => {
|
|
53
|
+
const route = Solid.createMemo(() => router.routesById[currentMatchState().routeId]);
|
|
54
|
+
const resolvePendingComponent = Solid.createMemo(() => route().options.pendingComponent ??
|
|
55
|
+
router.options.defaultPendingComponent);
|
|
56
|
+
const routeErrorComponent = Solid.createMemo(() => route().options.errorComponent ??
|
|
57
|
+
router.options.defaultErrorComponent);
|
|
58
|
+
const routeOnCatch = Solid.createMemo(() => route().options.onCatch ?? router.options.defaultOnCatch);
|
|
59
|
+
const routeNotFoundComponent = Solid.createMemo(() => route().isRoot
|
|
60
|
+
? // If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component
|
|
61
|
+
(route().options.notFoundComponent ??
|
|
62
|
+
router.options.notFoundRoute?.options.component)
|
|
63
|
+
: route().options.notFoundComponent);
|
|
64
|
+
const resolvedNoSsr = Solid.createMemo(() => currentMatchState().ssr === false ||
|
|
65
|
+
currentMatchState().ssr === 'data-only');
|
|
66
|
+
const ResolvedSuspenseBoundary = Solid.createMemo(() => resolvedNoSsr() ? SafeFragment : Solid.Loading);
|
|
67
|
+
const ResolvedCatchBoundary = Solid.createMemo(() => routeErrorComponent() ? CatchBoundary : SafeFragment);
|
|
68
|
+
const ResolvedNotFoundBoundary = Solid.createMemo(() => routeNotFoundComponent() ? CatchNotFound : SafeFragment);
|
|
69
|
+
const ShellComponent = Solid.createMemo(() => route().isRoot
|
|
70
|
+
? (route().options.shellComponent ??
|
|
71
|
+
SafeFragment)
|
|
72
|
+
: SafeFragment);
|
|
73
|
+
return (<Dynamic component={ShellComponent()}>
|
|
74
|
+
<NearestMatchContext value={nearestMatch}>
|
|
75
|
+
<Dynamic component={ResolvedSuspenseBoundary()} fallback={
|
|
76
|
+
// Don't show fallback on server when using no-ssr mode to avoid hydration mismatch
|
|
77
|
+
(isServer ?? router.isServer) &&
|
|
78
|
+
resolvedNoSsr() ? undefined : (<Dynamic component={resolvePendingComponent()}/>)}>
|
|
79
|
+
<Dynamic component={ResolvedCatchBoundary()} getResetKey={() => router.stores.loadedAt.state} errorComponent={routeErrorComponent() || ErrorComponent} onCatch={(error) => {
|
|
80
|
+
// Forward not found errors (we don't want to show the error component for these)
|
|
81
|
+
if (isNotFound(error))
|
|
82
|
+
throw error;
|
|
83
|
+
warning(false, `Error in route match: ${currentMatchState().routeId}`);
|
|
84
|
+
routeOnCatch()?.(error);
|
|
85
|
+
}}>
|
|
86
|
+
<Dynamic component={ResolvedNotFoundBoundary()} fallback={(error) => {
|
|
87
|
+
// If the current not found handler doesn't exist or it has a
|
|
88
|
+
// route ID which doesn't match the current route, rethrow the error
|
|
89
|
+
if (!routeNotFoundComponent() ||
|
|
90
|
+
(error.routeId &&
|
|
91
|
+
error.routeId !== currentMatchState().routeId) ||
|
|
92
|
+
(!error.routeId && !route().isRoot))
|
|
93
|
+
throw error;
|
|
94
|
+
return (<Dynamic component={routeNotFoundComponent()} {...error}/>);
|
|
95
|
+
}}>
|
|
96
|
+
<Solid.Switch>
|
|
97
|
+
<Solid.Match when={resolvedNoSsr()}>
|
|
98
|
+
<Solid.Show when={!(isServer ?? router.isServer)} fallback={<Dynamic component={resolvePendingComponent()}/>}>
|
|
99
|
+
<MatchInner />
|
|
100
|
+
</Solid.Show>
|
|
101
|
+
</Solid.Match>
|
|
102
|
+
<Solid.Match when={!resolvedNoSsr()}>
|
|
103
|
+
<MatchInner />
|
|
104
|
+
</Solid.Match>
|
|
105
|
+
</Solid.Switch>
|
|
106
|
+
</Dynamic>
|
|
107
|
+
</Dynamic>
|
|
108
|
+
</Dynamic>
|
|
109
|
+
</NearestMatchContext>
|
|
96
110
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
111
|
+
{currentMatchState().parentRouteId === rootRouteId ? (<>
|
|
112
|
+
<OnRendered />
|
|
113
|
+
<ScrollRestoration />
|
|
114
|
+
</>) : null}
|
|
115
|
+
</Dynamic>);
|
|
116
|
+
}}
|
|
117
|
+
</Solid.Show>);
|
|
102
118
|
};
|
|
103
119
|
// On Rendered can't happen above the root layout because it actually
|
|
104
120
|
// renders a dummy dom element to track the rendered state of the app.
|
|
@@ -116,12 +132,10 @@ export const Match = (props) => {
|
|
|
116
132
|
const lastOnRenderedKey = new WeakMap();
|
|
117
133
|
function OnRendered() {
|
|
118
134
|
const router = useRouter();
|
|
119
|
-
const location =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
});
|
|
124
|
-
Solid.createEffect(() => [location()], ([location]) => {
|
|
135
|
+
const location = Solid.createMemo(() => router.stores.resolvedLocation.state?.state.__TSR_key);
|
|
136
|
+
const locationState = Solid.createMemo(() => router.stores.location.state);
|
|
137
|
+
const resolvedLocationState = Solid.createMemo(() => router.stores.resolvedLocation.state);
|
|
138
|
+
Solid.createEffect(() => [location(), locationState(), resolvedLocationState()], ([location, currentLocationState, currentResolvedLocationState]) => {
|
|
125
139
|
if (!location)
|
|
126
140
|
return;
|
|
127
141
|
if (lastOnRenderedKey.get(router) === location)
|
|
@@ -129,201 +143,183 @@ function OnRendered() {
|
|
|
129
143
|
lastOnRenderedKey.set(router, location);
|
|
130
144
|
router.emit({
|
|
131
145
|
type: 'onRendered',
|
|
132
|
-
...getLocationChangeInfo(
|
|
146
|
+
...getLocationChangeInfo(currentLocationState, currentResolvedLocationState),
|
|
133
147
|
});
|
|
134
148
|
});
|
|
135
149
|
return null;
|
|
136
150
|
}
|
|
137
|
-
export const MatchInner = (
|
|
151
|
+
export const MatchInner = () => {
|
|
138
152
|
const router = useRouter();
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
const routeId = match.routeId;
|
|
147
|
-
const remountFn = router.routesById[routeId].options.remountDeps ??
|
|
148
|
-
router.options.defaultRemountDeps;
|
|
149
|
-
const remountDeps = remountFn?.({
|
|
150
|
-
routeId,
|
|
151
|
-
loaderDeps: match.loaderDeps,
|
|
152
|
-
params: match._strictParams,
|
|
153
|
-
search: match._strictSearch,
|
|
154
|
-
});
|
|
155
|
-
const key = remountDeps ? JSON.stringify(remountDeps) : undefined;
|
|
156
|
-
return {
|
|
157
|
-
key,
|
|
158
|
-
routeId,
|
|
159
|
-
match: {
|
|
160
|
-
id: match.id,
|
|
161
|
-
status: match.status,
|
|
162
|
-
error: match.error,
|
|
163
|
-
_forcePending: match._forcePending,
|
|
164
|
-
_displayPending: match._displayPending,
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
if (!Solid.untrack(matchState))
|
|
170
|
-
return null;
|
|
171
|
-
const route = () => router.routesById[matchState().routeId];
|
|
172
|
-
const match = () => matchState().match;
|
|
173
|
-
const componentKey = () => matchState().key ?? matchState().match.id;
|
|
174
|
-
const out = () => {
|
|
175
|
-
const currentRoute = Solid.untrack(route);
|
|
176
|
-
const Comp = currentRoute.options.component ?? router.options.defaultComponent;
|
|
177
|
-
if (Comp) {
|
|
178
|
-
return <Comp />;
|
|
153
|
+
const match = Solid.useContext(nearestMatchContext).match;
|
|
154
|
+
const rawMatchState = Solid.createMemo(() => {
|
|
155
|
+
const currentMatch = match();
|
|
156
|
+
if (!currentMatch) {
|
|
157
|
+
return null;
|
|
179
158
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const minPendingPromise = createControlledPromise();
|
|
212
|
-
routerMatch._nonReactive.minPendingPromise = minPendingPromise;
|
|
213
|
-
setTimeout(() => {
|
|
214
|
-
minPendingPromise.resolve();
|
|
215
|
-
// We've handled the minPendingPromise, so we can delete it
|
|
216
|
-
routerMatch._nonReactive.minPendingPromise = undefined;
|
|
217
|
-
}, pendingMinMs);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
const loaderResult = Solid.createMemo(async () => {
|
|
222
|
-
await new Promise((r) => setTimeout(r, 0));
|
|
223
|
-
return router.getMatch(currentMatch.id)?._nonReactive.loadPromise;
|
|
224
|
-
});
|
|
225
|
-
const FallbackComponent = currentRoute.options.pendingComponent ??
|
|
226
|
-
router.options.defaultPendingComponent;
|
|
227
|
-
return (<>
|
|
228
|
-
{FallbackComponent && pendingMinMs > 0 ? (<Dynamic component={FallbackComponent}/>) : null}
|
|
229
|
-
{loaderResult()}
|
|
230
|
-
</>);
|
|
231
|
-
}}
|
|
232
|
-
</Solid.Match>
|
|
233
|
-
<Solid.Match when={match().status === 'notFound'}>
|
|
234
|
-
{(_) => {
|
|
235
|
-
const currentMatch = Solid.untrack(match);
|
|
236
|
-
const currentRoute = Solid.untrack(route);
|
|
237
|
-
const currentRouteId = Solid.untrack(() => matchState().routeId);
|
|
238
|
-
invariant(isNotFound(currentMatch.error), 'Expected a notFound error');
|
|
239
|
-
// Use Show with keyed to ensure re-render when routeId changes
|
|
240
|
-
return (<Solid.Show when={currentRouteId} keyed>
|
|
241
|
-
{(_routeId) => renderRouteNotFound(router, currentRoute, currentMatch.error)}
|
|
242
|
-
</Solid.Show>);
|
|
243
|
-
}}
|
|
244
|
-
</Solid.Match>
|
|
245
|
-
<Solid.Match when={match().status === 'redirected'}>
|
|
246
|
-
{(_) => {
|
|
247
|
-
const matchId = Solid.untrack(() => match().id);
|
|
248
|
-
invariant(isRedirect(Solid.untrack(match).error), 'Expected a redirect error');
|
|
249
|
-
const loaderResult = Solid.createMemo(async () => {
|
|
250
|
-
await new Promise((r) => setTimeout(r, 0));
|
|
251
|
-
return router.getMatch(matchId)?._nonReactive.loadPromise;
|
|
159
|
+
const routeId = currentMatch.routeId;
|
|
160
|
+
const remountFn = router.routesById[routeId].options.remountDeps ??
|
|
161
|
+
router.options.defaultRemountDeps;
|
|
162
|
+
const remountDeps = remountFn?.({
|
|
163
|
+
routeId,
|
|
164
|
+
loaderDeps: currentMatch.loaderDeps,
|
|
165
|
+
params: currentMatch._strictParams,
|
|
166
|
+
search: currentMatch._strictSearch,
|
|
167
|
+
});
|
|
168
|
+
const key = remountDeps ? JSON.stringify(remountDeps) : undefined;
|
|
169
|
+
return {
|
|
170
|
+
key,
|
|
171
|
+
routeId,
|
|
172
|
+
match: {
|
|
173
|
+
id: currentMatch.id,
|
|
174
|
+
status: currentMatch.status,
|
|
175
|
+
error: currentMatch.error,
|
|
176
|
+
_forcePending: currentMatch._forcePending ?? false,
|
|
177
|
+
_displayPending: currentMatch._displayPending ?? false,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
return (<Solid.Show when={rawMatchState()}>
|
|
182
|
+
{(currentMatchState) => {
|
|
183
|
+
const route = Solid.createMemo(() => router.routesById[currentMatchState().routeId]);
|
|
184
|
+
const currentMatch = Solid.createMemo(() => currentMatchState().match);
|
|
185
|
+
const componentKey = Solid.createMemo(() => currentMatchState().key ?? currentMatchState().match.id);
|
|
186
|
+
const Comp = Solid.createMemo(() => route().options.component ?? router.options.defaultComponent);
|
|
187
|
+
const OutComponent = Solid.createMemo(() => {
|
|
188
|
+
const C = Comp();
|
|
189
|
+
return C || Outlet;
|
|
252
190
|
});
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
191
|
+
const RenderOut = () => <Dynamic component={OutComponent()}/>;
|
|
192
|
+
const keyedOut = () => (<Solid.Show when={componentKey()} keyed>
|
|
193
|
+
{(_key) => <RenderOut />}
|
|
194
|
+
</Solid.Show>);
|
|
195
|
+
return (<Solid.Switch>
|
|
196
|
+
<Solid.Match when={currentMatch()._displayPending}>
|
|
197
|
+
{(_) => {
|
|
198
|
+
const displayPendingResult = Solid.createMemo(() => router.getMatch(currentMatch().id)?._nonReactive
|
|
199
|
+
.displayPendingPromise);
|
|
200
|
+
return <>{displayPendingResult()}</>;
|
|
201
|
+
}}
|
|
202
|
+
</Solid.Match>
|
|
203
|
+
<Solid.Match when={currentMatch()._forcePending}>
|
|
204
|
+
{(_) => {
|
|
205
|
+
const minPendingResult = Solid.createMemo(() => router.getMatch(currentMatch().id)?._nonReactive
|
|
206
|
+
.minPendingPromise);
|
|
207
|
+
return <>{minPendingResult()}</>;
|
|
208
|
+
}}
|
|
209
|
+
</Solid.Match>
|
|
210
|
+
<Solid.Match when={currentMatch().status === 'pending'}>
|
|
211
|
+
{(_) => {
|
|
212
|
+
const pendingMinMs = Solid.untrack(() => route().options.pendingMinMs ??
|
|
213
|
+
router.options.defaultPendingMinMs);
|
|
214
|
+
if (pendingMinMs) {
|
|
215
|
+
const routerMatch = Solid.untrack(() => router.getMatch(currentMatch().id));
|
|
216
|
+
if (routerMatch &&
|
|
217
|
+
!routerMatch._nonReactive.minPendingPromise) {
|
|
218
|
+
// Create a promise that will resolve after the minPendingMs
|
|
219
|
+
if (!(isServer ?? router.isServer)) {
|
|
220
|
+
const minPendingPromise = createControlledPromise();
|
|
221
|
+
routerMatch._nonReactive.minPendingPromise =
|
|
222
|
+
minPendingPromise;
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
minPendingPromise.resolve();
|
|
225
|
+
// We've handled the minPendingPromise, so we can delete it
|
|
226
|
+
routerMatch._nonReactive.minPendingPromise = undefined;
|
|
227
|
+
}, pendingMinMs);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
const loaderResult = Solid.createMemo(async () => {
|
|
232
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
233
|
+
return router.getMatch(currentMatch().id)?._nonReactive
|
|
234
|
+
.loadPromise;
|
|
235
|
+
});
|
|
236
|
+
const FallbackComponent = Solid.untrack(() => route().options.pendingComponent ??
|
|
237
|
+
router.options.defaultPendingComponent);
|
|
238
|
+
return (<>
|
|
239
|
+
{FallbackComponent && pendingMinMs > 0 ? (<Dynamic component={FallbackComponent}/>) : null}
|
|
240
|
+
{loaderResult()}
|
|
241
|
+
</>);
|
|
242
|
+
}}
|
|
243
|
+
</Solid.Match>
|
|
244
|
+
<Solid.Match when={currentMatch().status === 'notFound'}>
|
|
245
|
+
{(_) => {
|
|
246
|
+
const matchError = Solid.untrack(() => currentMatch().error);
|
|
247
|
+
invariant(isNotFound(matchError), 'Expected a notFound error');
|
|
248
|
+
// Use Show with keyed to ensure re-render when routeId changes
|
|
249
|
+
return (<Solid.Show when={currentMatchState().routeId} keyed>
|
|
250
|
+
{(_routeId) => Solid.untrack(() => renderRouteNotFound(router, route(), matchError))}
|
|
251
|
+
</Solid.Show>);
|
|
252
|
+
}}
|
|
253
|
+
</Solid.Match>
|
|
254
|
+
<Solid.Match when={currentMatch().status === 'redirected'}>
|
|
255
|
+
{(_) => {
|
|
256
|
+
const matchError = Solid.untrack(() => currentMatch().error);
|
|
257
|
+
invariant(isRedirect(matchError), 'Expected a redirect error');
|
|
258
|
+
return null;
|
|
259
|
+
}}
|
|
260
|
+
</Solid.Match>
|
|
261
|
+
<Solid.Match when={currentMatch().status === 'error'}>
|
|
262
|
+
{(_) => {
|
|
263
|
+
const matchError = Solid.untrack(() => currentMatch().error);
|
|
264
|
+
if (isServer ?? router.isServer) {
|
|
265
|
+
const RouteErrorComponent = (route().options.errorComponent ??
|
|
266
|
+
router.options.defaultErrorComponent) ||
|
|
267
|
+
ErrorComponent;
|
|
268
|
+
return (<RouteErrorComponent error={matchError} info={{
|
|
269
|
+
componentStack: '',
|
|
270
|
+
}}/>);
|
|
271
|
+
}
|
|
272
|
+
throw matchError;
|
|
273
|
+
}}
|
|
274
|
+
</Solid.Match>
|
|
275
|
+
<Solid.Match when={currentMatch().status === 'success'}>
|
|
276
|
+
{keyedOut()}
|
|
277
|
+
</Solid.Match>
|
|
278
|
+
</Solid.Switch>);
|
|
268
279
|
}}
|
|
269
|
-
|
|
270
|
-
<Solid.Match when={match().status === 'success'}>
|
|
271
|
-
{keyedOut()}
|
|
272
|
-
</Solid.Match>
|
|
273
|
-
</Solid.Switch>);
|
|
280
|
+
</Solid.Show>);
|
|
274
281
|
};
|
|
275
282
|
export const Outlet = () => {
|
|
276
283
|
const router = useRouter();
|
|
277
|
-
const
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// Return false to avoid errors - the component will handle this gracefully
|
|
288
|
-
if (!parentMatch) {
|
|
289
|
-
return false;
|
|
290
|
-
}
|
|
291
|
-
return parentMatch.globalNotFound;
|
|
292
|
-
},
|
|
284
|
+
const nearestParentMatch = Solid.useContext(nearestMatchContext);
|
|
285
|
+
const parentMatch = nearestParentMatch.match;
|
|
286
|
+
const routeId = nearestParentMatch.routeId;
|
|
287
|
+
const route = Solid.createMemo(() => routeId() ? router.routesById[routeId()] : undefined);
|
|
288
|
+
const parentGlobalNotFound = Solid.createMemo(() => parentMatch()?.globalNotFound ?? false);
|
|
289
|
+
const childMatchId = Solid.createMemo(() => {
|
|
290
|
+
const currentRouteId = routeId();
|
|
291
|
+
return currentRouteId
|
|
292
|
+
? router.stores.childMatchIdByRouteId.state[currentRouteId]
|
|
293
|
+
: undefined;
|
|
293
294
|
});
|
|
294
|
-
const
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return v;
|
|
300
|
-
},
|
|
295
|
+
const childRouteId = Solid.createMemo(() => {
|
|
296
|
+
const id = childMatchId();
|
|
297
|
+
if (!id)
|
|
298
|
+
return undefined;
|
|
299
|
+
return router.stores.activeMatchStoresById.get(id)?.state.routeId;
|
|
301
300
|
});
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const index = matches.findIndex((d) => d.id === matchId());
|
|
306
|
-
return matches[index + 1]?.routeId;
|
|
307
|
-
},
|
|
301
|
+
const childRoute = Solid.createMemo(() => {
|
|
302
|
+
const id = childRouteId();
|
|
303
|
+
return id ? router.routesById[id] : undefined;
|
|
308
304
|
});
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
305
|
+
const childPendingComponent = Solid.createMemo(() => childRoute()?.options.pendingComponent ??
|
|
306
|
+
router.options.defaultPendingComponent);
|
|
307
|
+
const childMatchStatus = Solid.createMemo(() => {
|
|
308
|
+
const id = childMatchId();
|
|
309
|
+
if (!id)
|
|
310
|
+
return undefined;
|
|
311
|
+
return router.stores.activeMatchStoresById.get(id)?.state.status;
|
|
315
312
|
});
|
|
316
313
|
// Only show not-found if we're not in a redirected state
|
|
317
314
|
const shouldShowNotFound = () => childMatchStatus() !== 'redirected' && parentGlobalNotFound();
|
|
318
|
-
return (<Solid.Show when={!shouldShowNotFound() && childMatchId()} fallback={<Solid.Show when={shouldShowNotFound()}>
|
|
319
|
-
{renderRouteNotFound(router,
|
|
315
|
+
return (<Solid.Show when={!shouldShowNotFound() && childMatchId()} fallback={<Solid.Show when={shouldShowNotFound() && route()}>
|
|
316
|
+
{(resolvedRoute) => Solid.untrack(() => renderRouteNotFound(router, resolvedRoute(), undefined))}
|
|
320
317
|
</Solid.Show>}>
|
|
321
|
-
{(
|
|
322
|
-
|
|
323
|
-
const currentMatchId = Solid.createMemo(() => matchIdAccessor());
|
|
318
|
+
{(childMatchIdAccessor) => {
|
|
319
|
+
const currentMatchId = Solid.createMemo(() => childMatchIdAccessor());
|
|
324
320
|
return (<Solid.Show when={routeId() === rootRouteId} fallback={<Match matchId={currentMatchId()}/>}>
|
|
325
321
|
<Solid.Show when={childRouteId()} keyed>
|
|
326
|
-
{(_routeId) => (<Solid.Loading fallback={<Dynamic component={
|
|
322
|
+
{(_routeId) => (<Solid.Loading fallback={childPendingComponent() ? (<Dynamic component={childPendingComponent()}/>) : null}>
|
|
327
323
|
<Match matchId={currentMatchId()}/>
|
|
328
324
|
</Solid.Loading>)}
|
|
329
325
|
</Solid.Show>
|