@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/useBlocker.tsx
CHANGED
|
@@ -180,86 +180,103 @@ export function useBlocker(
|
|
|
180
180
|
reset: undefined,
|
|
181
181
|
})
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
183
|
+
let disposeBlock: (() => void) | undefined
|
|
184
|
+
|
|
185
|
+
Solid.createEffect(
|
|
186
|
+
() => props.disabled,
|
|
187
|
+
(disabled) => {
|
|
188
|
+
// Dispose previous blocker registration when re-running
|
|
189
|
+
disposeBlock?.()
|
|
190
|
+
disposeBlock = undefined
|
|
191
|
+
|
|
192
|
+
if (disabled) {
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {
|
|
197
|
+
function getLocation(
|
|
198
|
+
location: HistoryLocation,
|
|
199
|
+
): AnyShouldBlockFnLocation {
|
|
200
|
+
const parsedLocation = router.parseLocation(location)
|
|
201
|
+
const matchedRoutes = router.getMatchedRoutes(parsedLocation.pathname)
|
|
202
|
+
if (matchedRoutes.foundRoute === undefined) {
|
|
203
|
+
return {
|
|
204
|
+
routeId: '__notFound__',
|
|
205
|
+
fullPath: parsedLocation.pathname,
|
|
206
|
+
pathname: parsedLocation.pathname,
|
|
207
|
+
params: matchedRoutes.routeParams,
|
|
208
|
+
search: parsedLocation.search,
|
|
209
|
+
}
|
|
210
|
+
}
|
|
191
211
|
return {
|
|
192
|
-
routeId:
|
|
193
|
-
fullPath:
|
|
212
|
+
routeId: matchedRoutes.foundRoute.id,
|
|
213
|
+
fullPath: matchedRoutes.foundRoute.fullPath,
|
|
194
214
|
pathname: parsedLocation.pathname,
|
|
195
215
|
params: matchedRoutes.routeParams,
|
|
196
216
|
search: parsedLocation.search,
|
|
197
217
|
}
|
|
198
218
|
}
|
|
199
|
-
return {
|
|
200
|
-
routeId: matchedRoutes.foundRoute.id,
|
|
201
|
-
fullPath: matchedRoutes.foundRoute.fullPath,
|
|
202
|
-
pathname: parsedLocation.pathname,
|
|
203
|
-
params: matchedRoutes.routeParams,
|
|
204
|
-
search: parsedLocation.search,
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const current = getLocation(blockerFnArgs.currentLocation)
|
|
209
|
-
const next = getLocation(blockerFnArgs.nextLocation)
|
|
210
219
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
next.routeId !== '__notFound__'
|
|
214
|
-
) {
|
|
215
|
-
return false
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const shouldBlock = await props.shouldBlockFn({
|
|
219
|
-
action: blockerFnArgs.action,
|
|
220
|
-
current,
|
|
221
|
-
next,
|
|
222
|
-
})
|
|
223
|
-
if (!props.withResolver) {
|
|
224
|
-
return shouldBlock
|
|
225
|
-
}
|
|
220
|
+
const current = getLocation(blockerFnArgs.currentLocation)
|
|
221
|
+
const next = getLocation(blockerFnArgs.nextLocation)
|
|
226
222
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
223
|
+
if (
|
|
224
|
+
current.routeId === '__notFound__' &&
|
|
225
|
+
next.routeId !== '__notFound__'
|
|
226
|
+
) {
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
230
229
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
status: 'blocked',
|
|
230
|
+
const shouldBlock = await props.shouldBlockFn({
|
|
231
|
+
action: blockerFnArgs.action,
|
|
234
232
|
current,
|
|
235
233
|
next,
|
|
236
|
-
action: blockerFnArgs.action,
|
|
237
|
-
proceed: () => resolve(false),
|
|
238
|
-
reset: () => resolve(true),
|
|
239
234
|
})
|
|
240
|
-
|
|
235
|
+
if (!props.withResolver) {
|
|
236
|
+
return shouldBlock
|
|
237
|
+
}
|
|
241
238
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
current: undefined,
|
|
246
|
-
next: undefined,
|
|
247
|
-
action: undefined,
|
|
248
|
-
proceed: undefined,
|
|
249
|
-
reset: undefined,
|
|
250
|
-
})
|
|
239
|
+
if (!shouldBlock) {
|
|
240
|
+
return false
|
|
241
|
+
}
|
|
251
242
|
|
|
252
|
-
|
|
253
|
-
|
|
243
|
+
const promise = new Promise<boolean>((resolve) => {
|
|
244
|
+
setResolver({
|
|
245
|
+
status: 'blocked',
|
|
246
|
+
current,
|
|
247
|
+
next,
|
|
248
|
+
action: blockerFnArgs.action,
|
|
249
|
+
proceed: () => resolve(false),
|
|
250
|
+
reset: () => resolve(true),
|
|
251
|
+
})
|
|
252
|
+
})
|
|
254
253
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
254
|
+
const canNavigateAsync = await promise
|
|
255
|
+
setResolver({
|
|
256
|
+
status: 'idle',
|
|
257
|
+
current: undefined,
|
|
258
|
+
next: undefined,
|
|
259
|
+
action: undefined,
|
|
260
|
+
proceed: undefined,
|
|
261
|
+
reset: undefined,
|
|
260
262
|
})
|
|
261
263
|
|
|
262
|
-
|
|
264
|
+
return canNavigateAsync
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
disposeBlock = router.history.block({
|
|
268
|
+
blockerFn: blockerFnComposed,
|
|
269
|
+
enableBeforeUnload: props.enableBeforeUnload,
|
|
270
|
+
})
|
|
271
|
+
},
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
// Clean up on unmount
|
|
275
|
+
Solid.onSettled(() => {
|
|
276
|
+
return () => {
|
|
277
|
+
disposeBlock?.()
|
|
278
|
+
disposeBlock = undefined
|
|
279
|
+
}
|
|
263
280
|
})
|
|
264
281
|
|
|
265
282
|
return resolver
|
package/src/useCanGoBack.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Solid from 'solid-js'
|
|
2
|
+
import { useRouter } from './useRouter'
|
|
2
3
|
|
|
3
4
|
export function useCanGoBack() {
|
|
4
|
-
|
|
5
|
+
const router = useRouter()
|
|
6
|
+
return Solid.createMemo(
|
|
7
|
+
() => router.stores.location.state.state.__TSR_index !== 0,
|
|
8
|
+
)
|
|
5
9
|
}
|
package/src/useLoaderDeps.tsx
CHANGED
|
@@ -37,11 +37,10 @@ export function useLoaderDeps<
|
|
|
37
37
|
>(
|
|
38
38
|
opts: UseLoaderDepsOptions<TRouter, TFrom, TSelected>,
|
|
39
39
|
): Accessor<UseLoaderDepsResult<TRouter, TFrom, TSelected>> {
|
|
40
|
-
const { select, ...rest } = opts
|
|
41
40
|
return useMatch({
|
|
42
|
-
...
|
|
41
|
+
...opts,
|
|
43
42
|
select: (s) => {
|
|
44
|
-
return select ? select(s.loaderDeps) : s.loaderDeps
|
|
43
|
+
return opts.select ? opts.select(s.loaderDeps) : s.loaderDeps
|
|
45
44
|
},
|
|
46
45
|
}) as Accessor<UseLoaderDepsResult<TRouter, TFrom, TSelected>>
|
|
47
46
|
}
|
package/src/useLocation.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as Solid from 'solid-js'
|
|
2
|
+
import { replaceEqualDeep } from '@tanstack/router-core'
|
|
3
|
+
import { useRouter } from './useRouter'
|
|
2
4
|
import type {
|
|
3
5
|
AnyRouter,
|
|
4
6
|
RegisteredRouter,
|
|
@@ -23,8 +25,19 @@ export function useLocation<
|
|
|
23
25
|
>(
|
|
24
26
|
opts?: UseLocationBaseOptions<TRouter, TSelected>,
|
|
25
27
|
): Accessor<UseLocationResult<TRouter, TSelected>> {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
const router = useRouter<TRouter>()
|
|
29
|
+
|
|
30
|
+
if (!opts?.select) {
|
|
31
|
+
return (() => router.stores.location.state) as Accessor<
|
|
32
|
+
UseLocationResult<TRouter, TSelected>
|
|
33
|
+
>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const select = opts.select
|
|
37
|
+
|
|
38
|
+
return Solid.createMemo((prev: TSelected | undefined) => {
|
|
39
|
+
const res = select(router.stores.location.state)
|
|
40
|
+
if (prev === undefined) return res
|
|
41
|
+
return replaceEqualDeep(prev, res)
|
|
42
|
+
}) as Accessor<UseLocationResult<TRouter, TSelected>>
|
|
30
43
|
}
|
package/src/useMatch.tsx
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as Solid from 'solid-js'
|
|
2
2
|
import invariant from 'tiny-invariant'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { replaceEqualDeep } from '@tanstack/router-core'
|
|
4
|
+
import { nearestMatchContext } from './matchContext'
|
|
5
|
+
import { useRouter } from './useRouter'
|
|
5
6
|
import type {
|
|
6
7
|
AnyRouter,
|
|
7
8
|
MakeRouteMatch,
|
|
@@ -69,47 +70,45 @@ export function useMatch<
|
|
|
69
70
|
): Solid.Accessor<
|
|
70
71
|
ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
|
|
71
72
|
> {
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
const router = useRouter<TRouter>()
|
|
74
|
+
const nearestMatch = opts.from
|
|
75
|
+
? undefined
|
|
76
|
+
: Solid.useContext(nearestMatchContext)
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
78
|
+
const match = () => {
|
|
79
|
+
if (opts.from) {
|
|
80
|
+
const ids = router.stores.matchesId.state
|
|
81
|
+
for (const id of ids) {
|
|
82
|
+
const matchStore = router.stores.activeMatchStoresById.get(id)
|
|
83
|
+
if (matchStore?.routeId === opts.from) {
|
|
84
|
+
return matchStore.state
|
|
85
|
+
}
|
|
86
|
+
}
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const pendingMatch = state.pendingMatches?.find((d: any) =>
|
|
89
|
-
opts.from ? opts.from === d.routeId : d.id === nearestMatchId(),
|
|
90
|
-
)
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
!pendingMatch && !state.isTransitioning && (opts.shouldThrow ?? true)
|
|
91
|
+
return nearestMatch?.match()
|
|
92
|
+
}
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
return Solid.createMemo((prev: TSelected | undefined) => {
|
|
95
|
+
const selectedMatch = match()
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
} as any)
|
|
97
|
+
if (selectedMatch === undefined) {
|
|
98
|
+
const hasPendingMatch = opts.from
|
|
99
|
+
? Boolean(router.stores.pendingRouteIds.state[opts.from!])
|
|
100
|
+
: (nearestMatch?.hasPending() ?? false)
|
|
101
|
+
const isTransitioning = router.stores.isTransitioning.state
|
|
105
102
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
invariant(
|
|
104
|
+
!(!hasPendingMatch && !isTransitioning && (opts.shouldThrow ?? true)),
|
|
105
|
+
`Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
|
|
106
|
+
)
|
|
107
|
+
return undefined
|
|
108
|
+
}
|
|
112
109
|
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
const res = opts.select ? opts.select(selectedMatch as any) : selectedMatch
|
|
111
|
+
if (prev === undefined) return res as TSelected
|
|
112
|
+
return replaceEqualDeep(prev, res) as TSelected
|
|
113
|
+
}) as any
|
|
115
114
|
}
|
package/src/useParams.tsx
CHANGED
|
@@ -62,11 +62,10 @@ export function useParams<
|
|
|
62
62
|
> {
|
|
63
63
|
return useMatch({
|
|
64
64
|
from: opts.from!,
|
|
65
|
-
shouldThrow: opts.shouldThrow,
|
|
66
65
|
strict: opts.strict,
|
|
67
|
-
|
|
66
|
+
shouldThrow: opts.shouldThrow,
|
|
67
|
+
select: (match: any) => {
|
|
68
68
|
const params = opts.strict === false ? match.params : match._strictParams
|
|
69
|
-
|
|
70
69
|
return opts.select ? opts.select(params) : params
|
|
71
70
|
},
|
|
72
71
|
}) as Accessor<any>
|
package/src/useRouterState.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { createMemo, createSignal, onCleanup } from 'solid-js'
|
|
2
1
|
import { isServer } from '@tanstack/router-core/isServer'
|
|
2
|
+
import * as Solid from 'solid-js'
|
|
3
|
+
import { replaceEqualDeep } from '@tanstack/router-core'
|
|
3
4
|
import { useRouter } from './useRouter'
|
|
4
5
|
import type {
|
|
5
6
|
AnyRouter,
|
|
@@ -8,41 +9,6 @@ import type {
|
|
|
8
9
|
} from '@tanstack/router-core'
|
|
9
10
|
import type { Accessor } from 'solid-js'
|
|
10
11
|
|
|
11
|
-
function deepEqual(a: any, b: any): boolean {
|
|
12
|
-
if (Object.is(a, b)) return true
|
|
13
|
-
|
|
14
|
-
if (isPromiseLike(a) || isPromiseLike(b)) return false
|
|
15
|
-
|
|
16
|
-
if (
|
|
17
|
-
typeof a !== 'object' ||
|
|
18
|
-
a === null ||
|
|
19
|
-
typeof b !== 'object' ||
|
|
20
|
-
b === null
|
|
21
|
-
) {
|
|
22
|
-
return false
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const keysA = Object.keys(a)
|
|
26
|
-
const keysB = Object.keys(b)
|
|
27
|
-
|
|
28
|
-
if (keysA.length !== keysB.length) return false
|
|
29
|
-
|
|
30
|
-
for (const key of keysA) {
|
|
31
|
-
if (!Object.prototype.hasOwnProperty.call(b, key)) return false
|
|
32
|
-
if (!deepEqual(a[key], b[key])) return false
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return true
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
|
|
39
|
-
return (
|
|
40
|
-
!!value &&
|
|
41
|
-
(typeof value === 'object' || typeof value === 'function') &&
|
|
42
|
-
typeof (value as PromiseLike<unknown>).then === 'function'
|
|
43
|
-
)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
12
|
export type UseRouterStateOptions<TRouter extends AnyRouter, TSelected> = {
|
|
47
13
|
router?: TRouter
|
|
48
14
|
select?: (state: RouterState<TRouter['routeTree']>) => TSelected
|
|
@@ -69,40 +35,28 @@ export function useRouterState<
|
|
|
69
35
|
// implementation does not provide subscribe() semantics.
|
|
70
36
|
const _isServer = isServer ?? router.isServer
|
|
71
37
|
if (_isServer) {
|
|
72
|
-
const state = router.state as RouterState<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
38
|
+
const state = router.stores.__store.state as RouterState<
|
|
39
|
+
TRouter['routeTree']
|
|
40
|
+
>
|
|
41
|
+
const selected = (
|
|
42
|
+
opts?.select ? opts.select(state) : state
|
|
43
|
+
) as UseRouterStateResult<TRouter, TSelected>
|
|
44
|
+
return (() => selected) as Accessor<
|
|
45
|
+
UseRouterStateResult<TRouter, TSelected>
|
|
46
|
+
>
|
|
77
47
|
}
|
|
78
48
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
49
|
+
if (!opts?.select) {
|
|
50
|
+
return (() => router.stores.__store.state) as Accessor<
|
|
51
|
+
UseRouterStateResult<TRouter, TSelected>
|
|
52
|
+
>
|
|
83
53
|
}
|
|
84
54
|
|
|
85
|
-
|
|
86
|
-
// We store the full state so that the selector (which may read reactive
|
|
87
|
-
// props like props.matchId) re-runs inside a Solid tracking scope (the
|
|
88
|
-
// createMemo below) rather than inside the store subscriber callback
|
|
89
|
-
// where reactive reads would be untracked.
|
|
90
|
-
const [storeState, setStoreState] = createSignal(router.__store.get())
|
|
91
|
-
|
|
92
|
-
const unsub = router.__store.subscribe((s) => {
|
|
93
|
-
setStoreState(s)
|
|
94
|
-
}).unsubscribe
|
|
95
|
-
|
|
96
|
-
onCleanup(() => {
|
|
97
|
-
unsub()
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
// Run the selector inside a memo so that:
|
|
101
|
-
// 1. Reactive values read by the selector (e.g. props.matchId) are tracked
|
|
102
|
-
// 2. The result is memoized and only updates when the selected value changes
|
|
103
|
-
const selected = createMemo(() => selector(storeState()), undefined, {
|
|
104
|
-
equals: (a: any, b: any) => deepEqual(a, b),
|
|
105
|
-
})
|
|
55
|
+
const select = opts.select
|
|
106
56
|
|
|
107
|
-
return
|
|
57
|
+
return Solid.createMemo((prev: TSelected | undefined) => {
|
|
58
|
+
const res = select(router.stores.__store.state)
|
|
59
|
+
if (prev === undefined) return res
|
|
60
|
+
return replaceEqualDeep(prev, res)
|
|
61
|
+
}) as Accessor<UseRouterStateResult<TRouter, TSelected>>
|
|
108
62
|
}
|
package/src/useSearch.tsx
CHANGED
|
@@ -65,7 +65,8 @@ export function useSearch<
|
|
|
65
65
|
strict: opts.strict,
|
|
66
66
|
shouldThrow: opts.shouldThrow,
|
|
67
67
|
select: (match: any) => {
|
|
68
|
-
|
|
68
|
+
const search = match.search
|
|
69
|
+
return opts.select ? opts.select(search) : search
|
|
69
70
|
},
|
|
70
71
|
}) as any
|
|
71
72
|
}
|
package/src/utils.ts
CHANGED
|
@@ -1,27 +1,5 @@
|
|
|
1
1
|
import * as Solid from 'solid-js'
|
|
2
2
|
|
|
3
|
-
export const useLayoutEffect =
|
|
4
|
-
typeof window !== 'undefined' ? Solid.createEffect : Solid.createEffect
|
|
5
|
-
|
|
6
|
-
export const usePrevious = (fn: () => boolean) => {
|
|
7
|
-
return Solid.createMemo(
|
|
8
|
-
(
|
|
9
|
-
prev: { current: boolean | null; previous: boolean | null } = {
|
|
10
|
-
current: null,
|
|
11
|
-
previous: null,
|
|
12
|
-
},
|
|
13
|
-
) => {
|
|
14
|
-
const current = fn()
|
|
15
|
-
|
|
16
|
-
if (prev.current !== current) {
|
|
17
|
-
return { previous: prev.current, current }
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return prev
|
|
21
|
-
},
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
3
|
/**
|
|
26
4
|
* React hook to wrap `IntersectionObserver`.
|
|
27
5
|
*
|
|
@@ -68,9 +46,9 @@ export function useIntersectionObserver<T extends Element>(
|
|
|
68
46
|
|
|
69
47
|
observerRef.observe(r)
|
|
70
48
|
|
|
71
|
-
|
|
49
|
+
return () => {
|
|
72
50
|
observerRef?.disconnect()
|
|
73
|
-
}
|
|
51
|
+
}
|
|
74
52
|
})
|
|
75
53
|
|
|
76
54
|
return () => observerRef
|