@tanstack/solid-router 1.167.5 → 1.168.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/dist/cjs/Match.cjs +244 -223
  2. package/dist/cjs/Match.cjs.map +1 -1
  3. package/dist/cjs/Match.d.cts +1 -3
  4. package/dist/cjs/Matches.cjs +32 -31
  5. package/dist/cjs/Matches.cjs.map +1 -1
  6. package/dist/cjs/Scripts.cjs +10 -8
  7. package/dist/cjs/Scripts.cjs.map +1 -1
  8. package/dist/cjs/Scripts.d.cts +2 -1
  9. package/dist/cjs/Transitioner.cjs +26 -26
  10. package/dist/cjs/Transitioner.cjs.map +1 -1
  11. package/dist/cjs/headContentUtils.cjs +15 -15
  12. package/dist/cjs/headContentUtils.cjs.map +1 -1
  13. package/dist/cjs/index.cjs +1 -1
  14. package/dist/cjs/index.dev.cjs +1 -1
  15. package/dist/cjs/link.cjs +119 -84
  16. package/dist/cjs/link.cjs.map +1 -1
  17. package/dist/cjs/matchContext.cjs +7 -5
  18. package/dist/cjs/matchContext.cjs.map +1 -1
  19. package/dist/cjs/matchContext.d.cts +8 -2
  20. package/dist/cjs/not-found.cjs +8 -4
  21. package/dist/cjs/not-found.cjs.map +1 -1
  22. package/dist/cjs/not-found.d.cts +1 -1
  23. package/dist/cjs/router.cjs +2 -1
  24. package/dist/cjs/router.cjs.map +1 -1
  25. package/dist/cjs/routerStores.cjs +67 -0
  26. package/dist/cjs/routerStores.cjs.map +1 -0
  27. package/dist/cjs/routerStores.d.cts +10 -0
  28. package/dist/cjs/ssr/RouterClient.cjs +1 -1
  29. package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
  30. package/dist/cjs/ssr/renderRouterToStream.cjs +1 -1
  31. package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
  32. package/dist/cjs/ssr/renderRouterToString.cjs +2 -2
  33. package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
  34. package/dist/cjs/ssr/renderRouterToString.d.cts +1 -1
  35. package/dist/cjs/useCanGoBack.cjs +6 -2
  36. package/dist/cjs/useCanGoBack.cjs.map +1 -1
  37. package/dist/cjs/useCanGoBack.d.cts +2 -1
  38. package/dist/cjs/useLoaderDeps.cjs +2 -3
  39. package/dist/cjs/useLoaderDeps.cjs.map +1 -1
  40. package/dist/cjs/useLocation.cjs +13 -2
  41. package/dist/cjs/useLocation.cjs.map +1 -1
  42. package/dist/cjs/useMatch.cjs +17 -15
  43. package/dist/cjs/useMatch.cjs.map +1 -1
  44. package/dist/cjs/useParams.cjs +1 -1
  45. package/dist/cjs/useParams.cjs.map +1 -1
  46. package/dist/cjs/useRouterState.cjs +12 -19
  47. package/dist/cjs/useRouterState.cjs.map +1 -1
  48. package/dist/cjs/useSearch.cjs +2 -1
  49. package/dist/cjs/useSearch.cjs.map +1 -1
  50. package/dist/cjs/utils.cjs +0 -14
  51. package/dist/cjs/utils.cjs.map +1 -1
  52. package/dist/cjs/utils.d.cts +0 -4
  53. package/dist/esm/Match.d.ts +1 -3
  54. package/dist/esm/Match.js +245 -224
  55. package/dist/esm/Match.js.map +1 -1
  56. package/dist/esm/Matches.js +34 -33
  57. package/dist/esm/Matches.js.map +1 -1
  58. package/dist/esm/Scripts.d.ts +2 -1
  59. package/dist/esm/Scripts.js +8 -7
  60. package/dist/esm/Scripts.js.map +1 -1
  61. package/dist/esm/Transitioner.js +26 -26
  62. package/dist/esm/Transitioner.js.map +1 -1
  63. package/dist/esm/headContentUtils.js +15 -15
  64. package/dist/esm/headContentUtils.js.map +1 -1
  65. package/dist/esm/index.dev.js +1 -1
  66. package/dist/esm/index.js +1 -1
  67. package/dist/esm/link.js +120 -85
  68. package/dist/esm/link.js.map +1 -1
  69. package/dist/esm/matchContext.d.ts +8 -2
  70. package/dist/esm/matchContext.js +7 -4
  71. package/dist/esm/matchContext.js.map +1 -1
  72. package/dist/esm/not-found.d.ts +1 -1
  73. package/dist/esm/not-found.js +6 -3
  74. package/dist/esm/not-found.js.map +1 -1
  75. package/dist/esm/router.js +2 -1
  76. package/dist/esm/router.js.map +1 -1
  77. package/dist/esm/routerStores.d.ts +10 -0
  78. package/dist/esm/routerStores.js +65 -0
  79. package/dist/esm/routerStores.js.map +1 -0
  80. package/dist/esm/ssr/RouterClient.js +1 -1
  81. package/dist/esm/ssr/RouterClient.js.map +1 -1
  82. package/dist/esm/ssr/renderRouterToStream.js +1 -1
  83. package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
  84. package/dist/esm/ssr/renderRouterToString.d.ts +1 -1
  85. package/dist/esm/ssr/renderRouterToString.js +2 -2
  86. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  87. package/dist/esm/useCanGoBack.d.ts +2 -1
  88. package/dist/esm/useCanGoBack.js +4 -2
  89. package/dist/esm/useCanGoBack.js.map +1 -1
  90. package/dist/esm/useLoaderDeps.js +2 -3
  91. package/dist/esm/useLoaderDeps.js.map +1 -1
  92. package/dist/esm/useLocation.js +11 -2
  93. package/dist/esm/useLocation.js.map +1 -1
  94. package/dist/esm/useMatch.js +18 -16
  95. package/dist/esm/useMatch.js.map +1 -1
  96. package/dist/esm/useParams.js +1 -1
  97. package/dist/esm/useParams.js.map +1 -1
  98. package/dist/esm/useRouterState.js +10 -18
  99. package/dist/esm/useRouterState.js.map +1 -1
  100. package/dist/esm/useSearch.js +2 -1
  101. package/dist/esm/useSearch.js.map +1 -1
  102. package/dist/esm/utils.d.ts +0 -4
  103. package/dist/esm/utils.js +1 -14
  104. package/dist/esm/utils.js.map +1 -1
  105. package/dist/source/Match.d.ts +1 -3
  106. package/dist/source/Match.jsx +246 -237
  107. package/dist/source/Match.jsx.map +1 -1
  108. package/dist/source/Matches.jsx +42 -44
  109. package/dist/source/Matches.jsx.map +1 -1
  110. package/dist/source/Scripts.d.ts +2 -1
  111. package/dist/source/Scripts.jsx +31 -36
  112. package/dist/source/Scripts.jsx.map +1 -1
  113. package/dist/source/Transitioner.jsx +26 -31
  114. package/dist/source/Transitioner.jsx.map +1 -1
  115. package/dist/source/headContentUtils.jsx +64 -72
  116. package/dist/source/headContentUtils.jsx.map +1 -1
  117. package/dist/source/link.jsx +136 -107
  118. package/dist/source/link.jsx.map +1 -1
  119. package/dist/source/matchContext.d.ts +8 -2
  120. package/dist/source/matchContext.jsx +7 -3
  121. package/dist/source/matchContext.jsx.map +1 -1
  122. package/dist/source/not-found.d.ts +1 -1
  123. package/dist/source/not-found.jsx +6 -5
  124. package/dist/source/not-found.jsx.map +1 -1
  125. package/dist/source/router.js +2 -1
  126. package/dist/source/router.js.map +1 -1
  127. package/dist/source/routerStores.d.ts +10 -0
  128. package/dist/source/routerStores.js +71 -0
  129. package/dist/source/routerStores.js.map +1 -0
  130. package/dist/source/ssr/RouterClient.jsx +1 -1
  131. package/dist/source/ssr/RouterClient.jsx.map +1 -1
  132. package/dist/source/ssr/renderRouterToStream.jsx +1 -1
  133. package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
  134. package/dist/source/ssr/renderRouterToString.d.ts +1 -1
  135. package/dist/source/ssr/renderRouterToString.jsx +2 -2
  136. package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
  137. package/dist/source/useCanGoBack.d.ts +2 -1
  138. package/dist/source/useCanGoBack.js +4 -2
  139. package/dist/source/useCanGoBack.js.map +1 -1
  140. package/dist/source/useLoaderDeps.jsx +2 -3
  141. package/dist/source/useLoaderDeps.jsx.map +1 -1
  142. package/dist/source/useLocation.jsx +13 -3
  143. package/dist/source/useLocation.jsx.map +1 -1
  144. package/dist/source/useMatch.jsx +30 -27
  145. package/dist/source/useMatch.jsx.map +1 -1
  146. package/dist/source/useParams.jsx +1 -1
  147. package/dist/source/useParams.jsx.map +1 -1
  148. package/dist/source/useRouterState.jsx +12 -33
  149. package/dist/source/useRouterState.jsx.map +1 -1
  150. package/dist/source/useSearch.jsx +2 -1
  151. package/dist/source/useSearch.jsx.map +1 -1
  152. package/dist/source/utils.d.ts +0 -4
  153. package/dist/source/utils.js +0 -13
  154. package/dist/source/utils.js.map +1 -1
  155. package/package.json +2 -3
  156. package/skills/solid-router/SKILL.md +2 -0
  157. package/src/Match.tsx +351 -304
  158. package/src/Matches.tsx +49 -52
  159. package/src/Scripts.tsx +40 -41
  160. package/src/Transitioner.tsx +67 -66
  161. package/src/headContentUtils.tsx +89 -91
  162. package/src/link.tsx +179 -141
  163. package/src/matchContext.tsx +16 -7
  164. package/src/not-found.tsx +6 -6
  165. package/src/router.ts +2 -1
  166. package/src/routerStores.ts +107 -0
  167. package/src/ssr/RouterClient.tsx +1 -1
  168. package/src/ssr/renderRouterToStream.tsx +1 -1
  169. package/src/ssr/renderRouterToString.tsx +2 -2
  170. package/src/useCanGoBack.ts +6 -2
  171. package/src/useLoaderDeps.tsx +2 -3
  172. package/src/useLocation.tsx +18 -5
  173. package/src/useMatch.tsx +36 -43
  174. package/src/useParams.tsx +2 -3
  175. package/src/useRouterState.tsx +17 -41
  176. package/src/useSearch.tsx +2 -1
  177. package/src/utils.ts +0 -20
@@ -1,4 +1,6 @@
1
- import { useRouterState } from './useRouterState'
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
- return useRouterState({
27
- select: (state: any) =>
28
- opts?.select ? opts.select(state.location) : state.location,
29
- } as any) as Accessor<UseLocationResult<TRouter, TSelected>>
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 { useRouterState } from './useRouterState'
4
- import { dummyMatchContext, matchContext } from './matchContext'
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,52 +70,44 @@ export function useMatch<
69
70
  ): Solid.Accessor<
70
71
  ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
71
72
  > {
72
- const nearestMatchId = Solid.useContext(
73
- opts.from ? dummyMatchContext : matchContext,
74
- )
73
+ const router = useRouter<TRouter>()
74
+ const nearestMatch = opts.from
75
+ ? undefined
76
+ : Solid.useContext(nearestMatchContext)
75
77
 
76
- // Create a signal to track error state separately from the match
77
- const matchState: Solid.Accessor<{
78
- match: any
79
- shouldThrowError: boolean
80
- }> = useRouterState({
81
- select: (state: any) => {
82
- const match = state.matches.find((d: any) =>
83
- opts.from ? opts.from === d.routeId : d.id === nearestMatchId(),
84
- )
85
-
86
- if (match === undefined) {
87
- // During navigation transitions, check if the match exists in pendingMatches
88
- const pendingMatch = state.pendingMatches?.find((d: any) =>
89
- opts.from ? opts.from === d.routeId : d.id === nearestMatchId(),
90
- )
91
-
92
- // Determine if we should throw an error
93
- const shouldThrowError =
94
- !pendingMatch && !state.isTransitioning && (opts.shouldThrow ?? true)
95
-
96
- return { match: undefined, shouldThrowError }
97
- }
78
+ const match = () => {
79
+ if (opts.from) {
80
+ return router.stores.getMatchStoreByRouteId(opts.from).state
81
+ }
98
82
 
99
- return {
100
- match: opts.select ? opts.select(match) : match,
101
- shouldThrowError: false,
102
- }
103
- },
104
- } as any)
83
+ return nearestMatch?.match()
84
+ }
105
85
 
106
- // Use createEffect to throw errors outside the reactive selector context
107
- // This allows error boundaries to properly catch the errors
108
86
  Solid.createEffect(() => {
109
- const state = matchState()
110
- if (state.shouldThrowError) {
111
- invariant(
112
- false,
113
- `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
114
- )
87
+ if (match() !== undefined) {
88
+ return
115
89
  }
90
+
91
+ const hasPendingMatch = opts.from
92
+ ? Boolean(router.stores.pendingRouteIds.state[opts.from!])
93
+ : (nearestMatch?.hasPending() ?? false)
94
+
95
+ invariant(
96
+ !(
97
+ !hasPendingMatch &&
98
+ !router.stores.isTransitioning.state &&
99
+ (opts.shouldThrow ?? true)
100
+ ),
101
+ `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
102
+ )
116
103
  })
117
104
 
118
- // Return an accessor that extracts just the match value
119
- return Solid.createMemo(() => matchState().match) as any
105
+ return Solid.createMemo((prev: TSelected | undefined) => {
106
+ const selectedMatch = match()
107
+
108
+ if (selectedMatch === undefined) return undefined
109
+ const res = opts.select ? opts.select(selectedMatch as any) : selectedMatch
110
+ if (prev === undefined) return res as TSelected
111
+ return replaceEqualDeep(prev, res) as TSelected
112
+ }) as any
120
113
  }
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
- select: (match) => {
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>
@@ -1,5 +1,6 @@
1
- import { useStore } from '@tanstack/solid-store'
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,32 +9,6 @@ import type {
8
9
  } from '@tanstack/router-core'
9
10
  import type { Accessor } from 'solid-js'
10
11
 
11
- // Deep equality check to match behavior of solid-store 0.7.0's reconcile()
12
- function deepEqual(a: any, b: any): boolean {
13
- if (Object.is(a, b)) return true
14
-
15
- if (
16
- typeof a !== 'object' ||
17
- a === null ||
18
- typeof b !== 'object' ||
19
- b === null
20
- ) {
21
- return false
22
- }
23
-
24
- const keysA = Object.keys(a)
25
- const keysB = Object.keys(b)
26
-
27
- if (keysA.length !== keysB.length) return false
28
-
29
- for (const key of keysA) {
30
- if (!Object.prototype.hasOwnProperty.call(b, key)) return false
31
- if (!deepEqual(a[key], b[key])) return false
32
- }
33
-
34
- return true
35
- }
36
-
37
12
  export type UseRouterStateOptions<TRouter extends AnyRouter, TSelected> = {
38
13
  router?: TRouter
39
14
  select?: (state: RouterState<TRouter['routeTree']>) => TSelected
@@ -60,7 +35,9 @@ export function useRouterState<
60
35
  // implementation does not provide subscribe() semantics.
61
36
  const _isServer = isServer ?? router.isServer
62
37
  if (_isServer) {
63
- const state = router.state as RouterState<TRouter['routeTree']>
38
+ const state = router.stores.__store.state as RouterState<
39
+ TRouter['routeTree']
40
+ >
64
41
  const selected = (
65
42
  opts?.select ? opts.select(state) : state
66
43
  ) as UseRouterStateResult<TRouter, TSelected>
@@ -69,18 +46,17 @@ export function useRouterState<
69
46
  >
70
47
  }
71
48
 
72
- return useStore(
73
- router.__store,
74
- (state) => {
75
- if (opts?.select) return opts.select(state)
49
+ if (!opts?.select) {
50
+ return (() => router.stores.__store.state) as Accessor<
51
+ UseRouterStateResult<TRouter, TSelected>
52
+ >
53
+ }
54
+
55
+ const select = opts.select
76
56
 
77
- return state
78
- },
79
- {
80
- // Use deep equality to match behavior of solid-store 0.7.0 which used
81
- // reconcile(). This ensures updates work correctly when selectors
82
- // return new object references but with the same values.
83
- equal: deepEqual,
84
- },
85
- ) as Accessor<UseRouterStateResult<TRouter, TSelected>>
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>>
86
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
- return opts.select ? opts.select(match.search) : match.search
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,25 +1,5 @@
1
1
  import * as Solid from 'solid-js'
2
2
 
3
- export const usePrevious = (fn: () => boolean) => {
4
- return Solid.createMemo(
5
- (
6
- prev: { current: boolean | null; previous: boolean | null } = {
7
- current: null,
8
- previous: null,
9
- },
10
- ) => {
11
- const current = fn()
12
-
13
- if (prev.current !== current) {
14
- prev.previous = prev.current
15
- prev.current = current
16
- }
17
-
18
- return prev
19
- },
20
- )
21
- }
22
-
23
3
  /**
24
4
  * React hook to wrap `IntersectionObserver`.
25
5
  *