@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/src/Matches.tsx
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import * as Solid from 'solid-js'
|
|
2
2
|
import warning from 'tiny-warning'
|
|
3
|
-
import { rootRouteId } from '@tanstack/router-core'
|
|
3
|
+
import { replaceEqualDeep, rootRouteId } from '@tanstack/router-core'
|
|
4
4
|
import { isServer } from '@tanstack/router-core/isServer'
|
|
5
5
|
import { CatchBoundary, ErrorComponent } from './CatchBoundary'
|
|
6
|
-
import { useRouterState } from './useRouterState'
|
|
7
6
|
import { useRouter } from './useRouter'
|
|
8
7
|
import { Transitioner } from './Transitioner'
|
|
9
|
-
import {
|
|
8
|
+
import { nearestMatchContext } from './matchContext'
|
|
10
9
|
import { SafeFragment } from './SafeFragment'
|
|
11
10
|
import { Match } from './Match'
|
|
12
11
|
import type {
|
|
@@ -24,11 +23,10 @@ import type {
|
|
|
24
23
|
ResolveRelativePath,
|
|
25
24
|
ResolveRoute,
|
|
26
25
|
RouteByPath,
|
|
27
|
-
RouterState,
|
|
28
26
|
ToSubOptionsProps,
|
|
29
27
|
} from '@tanstack/router-core'
|
|
30
28
|
|
|
31
|
-
const
|
|
29
|
+
const NearestMatchContext = nearestMatchContext as unknown as Solid.Component<{
|
|
32
30
|
value: any
|
|
33
31
|
children: any
|
|
34
32
|
}>
|
|
@@ -77,15 +75,23 @@ export function Matches() {
|
|
|
77
75
|
|
|
78
76
|
function MatchesInner() {
|
|
79
77
|
const router = useRouter()
|
|
80
|
-
const matchId =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
const matchId = () => router.stores.firstMatchId.state
|
|
79
|
+
const routeId = () => (matchId() ? rootRouteId : undefined)
|
|
80
|
+
const match = () =>
|
|
81
|
+
routeId()
|
|
82
|
+
? router.stores.getMatchStoreByRouteId(rootRouteId).state
|
|
83
|
+
: undefined
|
|
84
|
+
const hasPendingMatch = () =>
|
|
85
|
+
routeId()
|
|
86
|
+
? Boolean(router.stores.pendingRouteIds.state[rootRouteId])
|
|
87
|
+
: false
|
|
88
|
+
const resetKey = () => router.stores.loadedAt.state
|
|
89
|
+
const nearestMatch = {
|
|
90
|
+
matchId,
|
|
91
|
+
routeId,
|
|
92
|
+
match,
|
|
93
|
+
hasPending: hasPendingMatch,
|
|
94
|
+
}
|
|
89
95
|
|
|
90
96
|
const matchContent = () => (
|
|
91
97
|
<Solid.Show when={matchId()}>
|
|
@@ -96,11 +102,15 @@ function MatchesInner() {
|
|
|
96
102
|
if (router.options.disableGlobalCatchBoundary) {
|
|
97
103
|
// When disableGlobalCatchBoundary is true, render without any internal
|
|
98
104
|
// error boundary so errors bubble up freely to an external Errored boundary.
|
|
99
|
-
return
|
|
105
|
+
return (
|
|
106
|
+
<NearestMatchContext value={nearestMatch}>
|
|
107
|
+
{matchContent()}
|
|
108
|
+
</NearestMatchContext>
|
|
109
|
+
)
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
return (
|
|
103
|
-
<
|
|
113
|
+
<NearestMatchContext value={nearestMatch}>
|
|
104
114
|
<CatchBoundary
|
|
105
115
|
getResetKey={() => resetKey()}
|
|
106
116
|
errorComponent={ErrorComponent}
|
|
@@ -109,8 +119,7 @@ function MatchesInner() {
|
|
|
109
119
|
? (error) => {
|
|
110
120
|
warning(
|
|
111
121
|
false,
|
|
112
|
-
`The following error wasn't caught by any route! At the very
|
|
113
|
-
t, consider setting an 'errorComponent' in your RootRoute!`,
|
|
122
|
+
`The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`,
|
|
114
123
|
)
|
|
115
124
|
warning(false, error.message || error.toString())
|
|
116
125
|
}
|
|
@@ -119,7 +128,7 @@ function MatchesInner() {
|
|
|
119
128
|
>
|
|
120
129
|
{matchContent()}
|
|
121
130
|
</CatchBoundary>
|
|
122
|
-
</
|
|
131
|
+
</NearestMatchContext>
|
|
123
132
|
)
|
|
124
133
|
}
|
|
125
134
|
|
|
@@ -138,10 +147,6 @@ export type UseMatchRouteOptions<
|
|
|
138
147
|
export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
|
|
139
148
|
const router = useRouter()
|
|
140
149
|
|
|
141
|
-
const status = useRouterState({
|
|
142
|
-
select: (s) => s.status,
|
|
143
|
-
})
|
|
144
|
-
|
|
145
150
|
return <
|
|
146
151
|
const TFrom extends string = string,
|
|
147
152
|
const TTo extends string | undefined = undefined,
|
|
@@ -152,10 +157,10 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
|
|
|
152
157
|
): Solid.Accessor<
|
|
153
158
|
false | Expand<ResolveRoute<TRouter, TFrom, TTo>['types']['allParams']>
|
|
154
159
|
> => {
|
|
155
|
-
|
|
160
|
+
return Solid.createMemo(() => {
|
|
161
|
+
const { pending, caseSensitive, fuzzy, includeSearch, ...rest } = opts
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
status()
|
|
163
|
+
router.stores.matchRouteReactivity.state
|
|
159
164
|
return router.matchRoute(rest as any, {
|
|
160
165
|
pending,
|
|
161
166
|
caseSensitive,
|
|
@@ -163,8 +168,6 @@ export function useMatchRoute<TRouter extends AnyRouter = RegisteredRouter>() {
|
|
|
163
168
|
includeSearch,
|
|
164
169
|
})
|
|
165
170
|
})
|
|
166
|
-
|
|
167
|
-
return matchRoute
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
|
|
@@ -193,24 +196,21 @@ export function MatchRoute<
|
|
|
193
196
|
const TMaskFrom extends string = TFrom,
|
|
194
197
|
const TMaskTo extends string = '',
|
|
195
198
|
>(props: MakeMatchRouteOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): any {
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
})
|
|
199
|
+
const matchRoute = useMatchRoute()
|
|
200
|
+
const params = matchRoute(props as any)
|
|
199
201
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const matchRoute = useMatchRoute()
|
|
204
|
-
const params = matchRoute(props as any)() as boolean
|
|
205
|
-
const child = props.children
|
|
206
|
-
if (typeof child === 'function') {
|
|
207
|
-
return (child as any)(params)
|
|
208
|
-
}
|
|
202
|
+
const renderedChild = Solid.createMemo(() => {
|
|
203
|
+
const matchedParams = params()
|
|
204
|
+
const child = props.children
|
|
209
205
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
if (typeof child === 'function') {
|
|
207
|
+
return (child as any)(matchedParams)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return matchedParams ? child : null
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
return <>{renderedChild()}</>
|
|
214
214
|
}
|
|
215
215
|
|
|
216
216
|
export interface UseMatchesBaseOptions<TRouter extends AnyRouter, TSelected> {
|
|
@@ -228,14 +228,15 @@ export function useMatches<
|
|
|
228
228
|
>(
|
|
229
229
|
opts?: UseMatchesBaseOptions<TRouter, TSelected>,
|
|
230
230
|
): Solid.Accessor<UseMatchesResult<TRouter, TSelected>> {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
231
|
+
const router = useRouter<TRouter>()
|
|
232
|
+
return Solid.createMemo((prev: TSelected | undefined) => {
|
|
233
|
+
const matches = router.stores.activeMatchesSnapshot.state as Array<
|
|
234
|
+
MakeRouteMatchUnion<TRouter>
|
|
235
|
+
>
|
|
236
|
+
const res = opts?.select ? opts.select(matches) : matches
|
|
237
|
+
if (prev === undefined) return res
|
|
238
|
+
return replaceEqualDeep(prev, res) as any
|
|
239
|
+
}) as Solid.Accessor<UseMatchesResult<TRouter, TSelected>>
|
|
239
240
|
}
|
|
240
241
|
|
|
241
242
|
export function useParentMatches<
|
|
@@ -244,7 +245,7 @@ export function useParentMatches<
|
|
|
244
245
|
>(
|
|
245
246
|
opts?: UseMatchesBaseOptions<TRouter, TSelected>,
|
|
246
247
|
): Solid.Accessor<UseMatchesResult<TRouter, TSelected>> {
|
|
247
|
-
const contextMatchId = Solid.useContext(
|
|
248
|
+
const contextMatchId = Solid.useContext(nearestMatchContext).matchId
|
|
248
249
|
|
|
249
250
|
return useMatches({
|
|
250
251
|
select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {
|
|
@@ -263,7 +264,7 @@ export function useChildMatches<
|
|
|
263
264
|
>(
|
|
264
265
|
opts?: UseMatchesBaseOptions<TRouter, TSelected>,
|
|
265
266
|
): Solid.Accessor<UseMatchesResult<TRouter, TSelected>> {
|
|
266
|
-
const contextMatchId = Solid.useContext(
|
|
267
|
+
const contextMatchId = Solid.useContext(nearestMatchContext).matchId
|
|
267
268
|
|
|
268
269
|
return useMatches({
|
|
269
270
|
select: (matches: Array<MakeRouteMatchUnion<TRouter>>) => {
|
package/src/RouterProvider.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as Solid from 'solid-js'
|
|
1
2
|
import { routerContext } from './routerContext'
|
|
2
3
|
import { SafeFragment } from './SafeFragment'
|
|
3
4
|
import { Matches } from './Matches'
|
|
@@ -6,7 +7,6 @@ import type {
|
|
|
6
7
|
RegisteredRouter,
|
|
7
8
|
RouterOptions,
|
|
8
9
|
} from '@tanstack/router-core'
|
|
9
|
-
import type * as Solid from 'solid-js'
|
|
10
10
|
|
|
11
11
|
const RouterContext = routerContext as unknown as Solid.Component<{
|
|
12
12
|
value: any
|
|
@@ -23,15 +23,18 @@ export function RouterContextProvider<
|
|
|
23
23
|
}: RouterProps<TRouter, TDehydrated> & {
|
|
24
24
|
children: () => Solid.JSX.Element
|
|
25
25
|
}) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
if (Object.keys(rest).length > 0) {
|
|
27
|
+
Solid.runWithOwner(null, () => {
|
|
28
|
+
router.update({
|
|
29
|
+
...router.options,
|
|
30
|
+
...rest,
|
|
31
|
+
context: {
|
|
32
|
+
...router.options.context,
|
|
33
|
+
...rest.context,
|
|
34
|
+
},
|
|
35
|
+
} as any)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
35
38
|
|
|
36
39
|
const OptionalWrapper = router.options.Wrap || SafeFragment
|
|
37
40
|
|
package/src/Scripts.tsx
CHANGED
|
@@ -1,77 +1,78 @@
|
|
|
1
1
|
import { NoHydration } from '@solidjs/web'
|
|
2
|
+
import * as Solid from 'solid-js'
|
|
2
3
|
import { Asset } from './Asset'
|
|
3
|
-
import { useRouterState } from './useRouterState'
|
|
4
4
|
import { useRouter } from './useRouter'
|
|
5
5
|
import type { RouterManagedTag } from '@tanstack/router-core'
|
|
6
6
|
|
|
7
7
|
export const Scripts = () => {
|
|
8
8
|
const router = useRouter()
|
|
9
9
|
const nonce = router.options.ssr?.nonce
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const activeMatches = Solid.createMemo(
|
|
11
|
+
() => router.stores.activeMatchesSnapshot.state,
|
|
12
|
+
)
|
|
13
|
+
const assetScripts = Solid.createMemo(() => {
|
|
14
|
+
const assetScripts: Array<RouterManagedTag> = []
|
|
15
|
+
const manifest = router.ssr?.manifest
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
if (!manifest) {
|
|
18
|
+
return []
|
|
19
|
+
}
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
21
|
+
activeMatches()
|
|
22
|
+
.map((match) => router.looseRoutesById[match.routeId]!)
|
|
23
|
+
.forEach((route) =>
|
|
24
|
+
manifest.routes[route.id]?.assets
|
|
25
|
+
?.filter((d) => d.tag === 'script')
|
|
26
|
+
.forEach((asset) => {
|
|
27
|
+
assetScripts.push({
|
|
28
|
+
tag: 'script',
|
|
29
|
+
attrs: { ...asset.attrs, nonce },
|
|
30
|
+
children: asset.children,
|
|
31
|
+
} as any)
|
|
32
|
+
}),
|
|
33
|
+
)
|
|
32
34
|
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
+
return assetScripts
|
|
35
36
|
})
|
|
36
37
|
|
|
37
|
-
const scripts =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}),
|
|
53
|
-
})
|
|
38
|
+
const scripts = Solid.createMemo(() =>
|
|
39
|
+
(
|
|
40
|
+
activeMatches()
|
|
41
|
+
.map((match) => match.scripts!)
|
|
42
|
+
.flat(1)
|
|
43
|
+
.filter(Boolean) as Array<RouterManagedTag>
|
|
44
|
+
).map(({ children, ...script }) => ({
|
|
45
|
+
tag: 'script',
|
|
46
|
+
attrs: {
|
|
47
|
+
...script,
|
|
48
|
+
nonce,
|
|
49
|
+
},
|
|
50
|
+
children,
|
|
51
|
+
})),
|
|
52
|
+
)
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
const serverBufferedScript: RouterManagedTag | undefined = router.serverSsr
|
|
55
|
+
? router.serverSsr.takeBufferedScripts()
|
|
56
|
+
: undefined
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
58
|
+
const allScripts = Solid.createMemo(() => {
|
|
59
|
+
const result = [...scripts(), ...assetScripts()] as Array<RouterManagedTag>
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
] as Array<RouterManagedTag>
|
|
61
|
+
if (serverBufferedScript) {
|
|
62
|
+
result.unshift(serverBufferedScript)
|
|
63
|
+
}
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
65
|
+
return result
|
|
66
|
+
})
|
|
69
67
|
|
|
70
68
|
return (
|
|
71
69
|
<NoHydration>
|
|
72
|
-
{allScripts
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
<Solid.For each={allScripts()}>
|
|
71
|
+
{(asset) => {
|
|
72
|
+
const a = Solid.untrack(asset)
|
|
73
|
+
return <Asset {...a} />
|
|
74
|
+
}}
|
|
75
|
+
</Solid.For>
|
|
75
76
|
</NoHydration>
|
|
76
77
|
)
|
|
77
78
|
}
|
package/src/Transitioner.tsx
CHANGED
|
@@ -1,44 +1,62 @@
|
|
|
1
1
|
import * as Solid from 'solid-js'
|
|
2
|
-
import {
|
|
3
|
-
getLocationChangeInfo,
|
|
4
|
-
handleHashScroll,
|
|
5
|
-
trimPathRight,
|
|
6
|
-
} from '@tanstack/router-core'
|
|
2
|
+
import { getLocationChangeInfo, trimPathRight } from '@tanstack/router-core'
|
|
7
3
|
import { useRouter } from './useRouter'
|
|
8
|
-
import {
|
|
9
|
-
|
|
4
|
+
import type { ParsedLocation } from '@tanstack/router-core'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Inline version of handleHashScroll that accepts a pre-captured location
|
|
8
|
+
* to avoid reading router.stores.location.state inside an effect callback
|
|
9
|
+
* (which would trigger a Solid v2 reactive warning).
|
|
10
|
+
*/
|
|
11
|
+
function handleHashScrollWithLocation(_router: any, location: ParsedLocation) {
|
|
12
|
+
if (typeof document !== 'undefined' && (document as any).querySelector) {
|
|
13
|
+
const hashScrollIntoViewOptions =
|
|
14
|
+
location.state.__hashScrollIntoViewOptions ?? true
|
|
15
|
+
|
|
16
|
+
if (hashScrollIntoViewOptions && location.hash !== '') {
|
|
17
|
+
const el = document.getElementById(location.hash)
|
|
18
|
+
if (el) {
|
|
19
|
+
el.scrollIntoView(hashScrollIntoViewOptions)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
10
24
|
|
|
11
25
|
export function Transitioner() {
|
|
12
26
|
const router = useRouter()
|
|
13
27
|
let mountLoadForRouter = { router, mounted: false }
|
|
14
|
-
const isLoading =
|
|
15
|
-
select: ({ isLoading }) => isLoading,
|
|
16
|
-
})
|
|
28
|
+
const isLoading = Solid.createMemo(() => router.stores.isLoading.state)
|
|
17
29
|
|
|
18
30
|
const [isSolidTransitioning] = [() => false]
|
|
19
31
|
|
|
20
32
|
// Track pending state changes
|
|
21
|
-
const hasPendingMatches =
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const previousIsLoading = usePrevious(isLoading)
|
|
33
|
+
const hasPendingMatches = Solid.createMemo(
|
|
34
|
+
() => router.stores.hasPendingMatches.state,
|
|
35
|
+
)
|
|
26
36
|
|
|
27
|
-
const isAnyPending = (
|
|
28
|
-
isLoading() || isSolidTransitioning() || hasPendingMatches()
|
|
29
|
-
|
|
37
|
+
const isAnyPending = Solid.createMemo(
|
|
38
|
+
() => isLoading() || isSolidTransitioning() || hasPendingMatches(),
|
|
39
|
+
)
|
|
30
40
|
|
|
31
|
-
const isPagePending = (
|
|
32
|
-
|
|
41
|
+
const isPagePending = Solid.createMemo(
|
|
42
|
+
() => isLoading() || hasPendingMatches(),
|
|
43
|
+
)
|
|
33
44
|
|
|
34
45
|
router.startTransition = (fn: () => void | Promise<void>) => {
|
|
35
46
|
Solid.runWithOwner(null, fn)
|
|
47
|
+
try {
|
|
48
|
+
Solid.flush()
|
|
49
|
+
} catch {
|
|
50
|
+
// flush() throws inside reactive contexts — Solid auto-flushes there
|
|
51
|
+
}
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
// Subscribe to location changes
|
|
39
55
|
// and try to load the new location
|
|
40
56
|
Solid.onSettled(() => {
|
|
41
|
-
const unsub = router.history.subscribe(
|
|
57
|
+
const unsub = router.history.subscribe(() => {
|
|
58
|
+
queueMicrotask(() => router.load())
|
|
59
|
+
})
|
|
42
60
|
|
|
43
61
|
// Refresh latestLocation from the current browser URL before comparing.
|
|
44
62
|
// The URL may have been changed synchronously (e.g. via replaceState) after
|
|
@@ -71,16 +89,21 @@ export function Transitioner() {
|
|
|
71
89
|
})
|
|
72
90
|
|
|
73
91
|
// Try to load the initial location
|
|
74
|
-
Solid
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
mountLoadForRouter
|
|
92
|
+
// In Solid v2, signal updates inside onSettled cannot be flushed
|
|
93
|
+
// synchronously (flush() throws). router.load() sets signals via batch(),
|
|
94
|
+
// and the code that runs immediately after needs those values committed.
|
|
95
|
+
// By deferring to queueMicrotask, the load runs outside the reactive
|
|
96
|
+
// scheduling frame so flush() works correctly.
|
|
97
|
+
Solid.onSettled(() => {
|
|
98
|
+
if (
|
|
99
|
+
// if we are hydrating from SSR, loading is triggered in ssr-client
|
|
100
|
+
(typeof window !== 'undefined' && router.ssr) ||
|
|
101
|
+
(mountLoadForRouter.router === router && mountLoadForRouter.mounted)
|
|
102
|
+
) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
105
|
+
mountLoadForRouter = { router, mounted: true }
|
|
106
|
+
queueMicrotask(() => {
|
|
84
107
|
const tryLoad = async () => {
|
|
85
108
|
try {
|
|
86
109
|
await router.load()
|
|
@@ -91,50 +114,70 @@ export function Transitioner() {
|
|
|
91
114
|
tryLoad()
|
|
92
115
|
})
|
|
93
116
|
})
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
117
|
+
Solid.createRenderEffect(
|
|
118
|
+
() =>
|
|
119
|
+
[
|
|
120
|
+
isLoading(),
|
|
121
|
+
isPagePending(),
|
|
122
|
+
isAnyPending(),
|
|
123
|
+
router.stores.location.state,
|
|
124
|
+
router.stores.resolvedLocation.state,
|
|
125
|
+
] as const,
|
|
126
|
+
(
|
|
127
|
+
[
|
|
128
|
+
currentIsLoading,
|
|
129
|
+
currentIsPagePending,
|
|
130
|
+
currentIsAnyPending,
|
|
131
|
+
loc,
|
|
132
|
+
resolvedLoc,
|
|
133
|
+
],
|
|
134
|
+
prev,
|
|
135
|
+
) => {
|
|
136
|
+
// Guard: if location state isn't available yet, skip all event emissions
|
|
137
|
+
if (!loc) return
|
|
138
|
+
|
|
139
|
+
const previousIsLoading = prev?.[0]
|
|
140
|
+
const previousIsPagePending = prev?.[1]
|
|
141
|
+
const previousIsAnyPending = prev?.[2]
|
|
142
|
+
|
|
143
|
+
// onLoad: when the router finishes loading
|
|
144
|
+
if (previousIsLoading && !currentIsLoading) {
|
|
99
145
|
router.emit({
|
|
100
146
|
type: 'onLoad',
|
|
101
|
-
...getLocationChangeInfo(
|
|
147
|
+
...getLocationChangeInfo(loc, resolvedLoc),
|
|
102
148
|
})
|
|
103
149
|
}
|
|
104
|
-
},
|
|
105
|
-
)
|
|
106
150
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
([isPagePending, previousIsPagePending]) => {
|
|
110
|
-
// emit onBeforeRouteMount
|
|
111
|
-
if (previousIsPagePending.previous && !isPagePending) {
|
|
151
|
+
// onBeforeRouteMount: must fire before onResolved
|
|
152
|
+
if (previousIsPagePending && !currentIsPagePending) {
|
|
112
153
|
router.emit({
|
|
113
154
|
type: 'onBeforeRouteMount',
|
|
114
|
-
...getLocationChangeInfo(
|
|
155
|
+
...getLocationChangeInfo(loc, resolvedLoc),
|
|
115
156
|
})
|
|
116
157
|
}
|
|
117
|
-
},
|
|
118
|
-
)
|
|
119
158
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (previousIsAnyPending.previous && !isAnyPending) {
|
|
124
|
-
const changeInfo = getLocationChangeInfo(router.state)
|
|
159
|
+
// onResolved: fires after onBeforeRouteMount
|
|
160
|
+
if (previousIsAnyPending && !currentIsAnyPending) {
|
|
161
|
+
const changeInfo = getLocationChangeInfo(loc, resolvedLoc)
|
|
125
162
|
router.emit({
|
|
126
163
|
type: 'onResolved',
|
|
127
164
|
...changeInfo,
|
|
128
165
|
})
|
|
129
166
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
167
|
+
Solid.runWithOwner(null, () => {
|
|
168
|
+
router.batch(() => {
|
|
169
|
+
router.stores.status.setState(() => 'idle')
|
|
170
|
+
// Use `loc` from the source tuple to avoid reading
|
|
171
|
+
// router.stores.location.state inside the effect callback
|
|
172
|
+
router.stores.resolvedLocation.setState(() => loc)
|
|
173
|
+
})
|
|
174
|
+
})
|
|
135
175
|
|
|
136
176
|
if (changeInfo.hrefChanged) {
|
|
137
|
-
|
|
177
|
+
// Pass the already-captured location to avoid a reactive read
|
|
178
|
+
// inside the effect callback (handleHashScroll would otherwise
|
|
179
|
+
// read router.stores.location.state which triggers a warning)
|
|
180
|
+
handleHashScrollWithLocation(router, loc)
|
|
138
181
|
}
|
|
139
182
|
}
|
|
140
183
|
},
|