@tanstack/solid-router 1.166.6 → 2.0.0-alpha.1

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 (182) hide show
  1. package/dist/cjs/Asset.cjs +111 -68
  2. package/dist/cjs/Asset.cjs.map +1 -1
  3. package/dist/cjs/CatchBoundary.cjs +15 -15
  4. package/dist/cjs/CatchBoundary.cjs.map +1 -1
  5. package/dist/cjs/ClientOnly.cjs +2 -2
  6. package/dist/cjs/ClientOnly.cjs.map +1 -1
  7. package/dist/cjs/HeadContent.cjs +16 -8
  8. package/dist/cjs/HeadContent.cjs.map +1 -1
  9. package/dist/cjs/HeadContent.dev.cjs +18 -10
  10. package/dist/cjs/HeadContent.dev.cjs.map +1 -1
  11. package/dist/cjs/Match.cjs +125 -81
  12. package/dist/cjs/Match.cjs.map +1 -1
  13. package/dist/cjs/Matches.cjs +23 -16
  14. package/dist/cjs/Matches.cjs.map +1 -1
  15. package/dist/cjs/RouterProvider.cjs +3 -2
  16. package/dist/cjs/RouterProvider.cjs.map +1 -1
  17. package/dist/cjs/SafeFragment.cjs +1 -1
  18. package/dist/cjs/ScriptOnce.cjs +4 -2
  19. package/dist/cjs/ScriptOnce.cjs.map +1 -1
  20. package/dist/cjs/Scripts.cjs +6 -2
  21. package/dist/cjs/Scripts.cjs.map +1 -1
  22. package/dist/cjs/Transitioner.cjs +11 -16
  23. package/dist/cjs/Transitioner.cjs.map +1 -1
  24. package/dist/cjs/awaited.cjs +20 -16
  25. package/dist/cjs/awaited.cjs.map +1 -1
  26. package/dist/cjs/lazyRouteComponent.cjs +3 -3
  27. package/dist/cjs/lazyRouteComponent.cjs.map +1 -1
  28. package/dist/cjs/link.cjs +40 -22
  29. package/dist/cjs/link.cjs.map +1 -1
  30. package/dist/cjs/not-found.cjs +1 -1
  31. package/dist/cjs/renderRouteNotFound.cjs +1 -1
  32. package/dist/cjs/route.cjs +1 -1
  33. package/dist/cjs/scroll-restoration.cjs +1 -1
  34. package/dist/cjs/ssr/RouterClient.cjs +4 -23
  35. package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
  36. package/dist/cjs/ssr/RouterServer.cjs +4 -47
  37. package/dist/cjs/ssr/RouterServer.cjs.map +1 -1
  38. package/dist/cjs/ssr/RouterServer.d.cts +0 -1
  39. package/dist/cjs/ssr/defaultRenderHandler.cjs +1 -1
  40. package/dist/cjs/ssr/defaultStreamHandler.cjs +1 -1
  41. package/dist/cjs/ssr/renderRouterToStream.cjs +2 -3
  42. package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
  43. package/dist/cjs/ssr/renderRouterToString.cjs +2 -2
  44. package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
  45. package/dist/cjs/ssr/renderRouterToString.d.cts +1 -1
  46. package/dist/cjs/useBlocker.cjs +9 -5
  47. package/dist/cjs/useBlocker.cjs.map +1 -1
  48. package/dist/cjs/useMatch.cjs +3 -6
  49. package/dist/cjs/useMatch.cjs.map +1 -1
  50. package/dist/cjs/useNavigate.cjs +1 -1
  51. package/dist/cjs/useNavigate.cjs.map +1 -1
  52. package/dist/cjs/useRouterState.cjs +15 -9
  53. package/dist/cjs/useRouterState.cjs.map +1 -1
  54. package/dist/cjs/utils.cjs +2 -4
  55. package/dist/cjs/utils.cjs.map +1 -1
  56. package/dist/cjs/utils.d.cts +1 -0
  57. package/dist/esm/Asset.js +111 -68
  58. package/dist/esm/Asset.js.map +1 -1
  59. package/dist/esm/CatchBoundary.js +15 -15
  60. package/dist/esm/CatchBoundary.js.map +1 -1
  61. package/dist/esm/ClientOnly.js +2 -2
  62. package/dist/esm/ClientOnly.js.map +1 -1
  63. package/dist/esm/HeadContent.dev.js +18 -10
  64. package/dist/esm/HeadContent.dev.js.map +1 -1
  65. package/dist/esm/HeadContent.js +16 -8
  66. package/dist/esm/HeadContent.js.map +1 -1
  67. package/dist/esm/Match.js +89 -45
  68. package/dist/esm/Match.js.map +1 -1
  69. package/dist/esm/Matches.js +23 -16
  70. package/dist/esm/Matches.js.map +1 -1
  71. package/dist/esm/RouterProvider.js +3 -2
  72. package/dist/esm/RouterProvider.js.map +1 -1
  73. package/dist/esm/SafeFragment.js +1 -1
  74. package/dist/esm/ScriptOnce.js +4 -2
  75. package/dist/esm/ScriptOnce.js.map +1 -1
  76. package/dist/esm/Scripts.js +6 -2
  77. package/dist/esm/Scripts.js.map +1 -1
  78. package/dist/esm/Transitioner.js +11 -16
  79. package/dist/esm/Transitioner.js.map +1 -1
  80. package/dist/esm/awaited.js +18 -14
  81. package/dist/esm/awaited.js.map +1 -1
  82. package/dist/esm/lazyRouteComponent.js +3 -3
  83. package/dist/esm/lazyRouteComponent.js.map +1 -1
  84. package/dist/esm/link.js +39 -21
  85. package/dist/esm/link.js.map +1 -1
  86. package/dist/esm/not-found.js +1 -1
  87. package/dist/esm/renderRouteNotFound.js +1 -1
  88. package/dist/esm/route.js +1 -1
  89. package/dist/esm/scroll-restoration.js +1 -1
  90. package/dist/esm/ssr/RouterClient.js +4 -23
  91. package/dist/esm/ssr/RouterClient.js.map +1 -1
  92. package/dist/esm/ssr/RouterServer.d.ts +0 -1
  93. package/dist/esm/ssr/RouterServer.js +5 -48
  94. package/dist/esm/ssr/RouterServer.js.map +1 -1
  95. package/dist/esm/ssr/defaultRenderHandler.js +1 -1
  96. package/dist/esm/ssr/defaultStreamHandler.js +1 -1
  97. package/dist/esm/ssr/renderRouterToStream.js +2 -4
  98. package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
  99. package/dist/esm/ssr/renderRouterToString.d.ts +1 -1
  100. package/dist/esm/ssr/renderRouterToString.js +2 -2
  101. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  102. package/dist/esm/useBlocker.js +9 -5
  103. package/dist/esm/useBlocker.js.map +1 -1
  104. package/dist/esm/useMatch.js +3 -6
  105. package/dist/esm/useMatch.js.map +1 -1
  106. package/dist/esm/useNavigate.js +1 -1
  107. package/dist/esm/useNavigate.js.map +1 -1
  108. package/dist/esm/useRouterState.js +15 -9
  109. package/dist/esm/useRouterState.js.map +1 -1
  110. package/dist/esm/utils.d.ts +1 -0
  111. package/dist/esm/utils.js +2 -4
  112. package/dist/esm/utils.js.map +1 -1
  113. package/dist/source/Asset.jsx +58 -35
  114. package/dist/source/Asset.jsx.map +1 -1
  115. package/dist/source/CatchBoundary.jsx +9 -5
  116. package/dist/source/CatchBoundary.jsx.map +1 -1
  117. package/dist/source/ClientOnly.jsx +1 -1
  118. package/dist/source/ClientOnly.jsx.map +1 -1
  119. package/dist/source/HeadContent.dev.jsx +8 -6
  120. package/dist/source/HeadContent.dev.jsx.map +1 -1
  121. package/dist/source/HeadContent.jsx +6 -4
  122. package/dist/source/HeadContent.jsx.map +1 -1
  123. package/dist/source/Match.jsx +76 -35
  124. package/dist/source/Match.jsx.map +1 -1
  125. package/dist/source/Matches.jsx +25 -17
  126. package/dist/source/Matches.jsx.map +1 -1
  127. package/dist/source/RouterProvider.jsx +2 -3
  128. package/dist/source/RouterProvider.jsx.map +1 -1
  129. package/dist/source/Scripts.jsx +4 -3
  130. package/dist/source/Scripts.jsx.map +1 -1
  131. package/dist/source/Transitioner.jsx +15 -16
  132. package/dist/source/Transitioner.jsx.map +1 -1
  133. package/dist/source/awaited.jsx +7 -8
  134. package/dist/source/awaited.jsx.map +1 -1
  135. package/dist/source/lazyRouteComponent.jsx +3 -3
  136. package/dist/source/lazyRouteComponent.jsx.map +1 -1
  137. package/dist/source/link.jsx +53 -48
  138. package/dist/source/link.jsx.map +1 -1
  139. package/dist/source/ssr/RouterClient.jsx +1 -13
  140. package/dist/source/ssr/RouterClient.jsx.map +1 -1
  141. package/dist/source/ssr/RouterServer.d.ts +0 -1
  142. package/dist/source/ssr/RouterServer.jsx +1 -34
  143. package/dist/source/ssr/RouterServer.jsx.map +1 -1
  144. package/dist/source/ssr/renderRouterToStream.jsx +2 -6
  145. package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
  146. package/dist/source/ssr/renderRouterToString.d.ts +1 -1
  147. package/dist/source/ssr/renderRouterToString.jsx +2 -2
  148. package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
  149. package/dist/source/useBlocker.jsx +8 -4
  150. package/dist/source/useBlocker.jsx.map +1 -1
  151. package/dist/source/useMatch.jsx +3 -8
  152. package/dist/source/useMatch.jsx.map +1 -1
  153. package/dist/source/useNavigate.jsx +1 -1
  154. package/dist/source/useNavigate.jsx.map +1 -1
  155. package/dist/source/useRouterState.jsx +23 -10
  156. package/dist/source/useRouterState.jsx.map +1 -1
  157. package/dist/source/utils.d.ts +1 -0
  158. package/dist/source/utils.js +3 -4
  159. package/dist/source/utils.js.map +1 -1
  160. package/package.json +8 -7
  161. package/src/Asset.tsx +123 -95
  162. package/src/CatchBoundary.tsx +9 -7
  163. package/src/ClientOnly.tsx +8 -3
  164. package/src/HeadContent.dev.tsx +16 -11
  165. package/src/HeadContent.tsx +6 -4
  166. package/src/Match.tsx +112 -44
  167. package/src/Matches.tsx +39 -30
  168. package/src/RouterProvider.tsx +7 -4
  169. package/src/Scripts.tsx +4 -3
  170. package/src/Transitioner.tsx +51 -58
  171. package/src/awaited.tsx +11 -12
  172. package/src/lazyRouteComponent.tsx +3 -3
  173. package/src/link.tsx +68 -60
  174. package/src/ssr/RouterClient.tsx +1 -22
  175. package/src/ssr/RouterServer.tsx +1 -53
  176. package/src/ssr/renderRouterToStream.tsx +5 -15
  177. package/src/ssr/renderRouterToString.tsx +2 -2
  178. package/src/useBlocker.tsx +8 -4
  179. package/src/useMatch.tsx +6 -11
  180. package/src/useNavigate.tsx +1 -1
  181. package/src/useRouterState.tsx +34 -22
  182. package/src/utils.ts +5 -4
@@ -1,6 +1,6 @@
1
- import { Dynamic } from 'solid-js/web'
2
- import { createResource } from 'solid-js'
3
1
  import { isModuleNotFoundError } from '@tanstack/router-core'
2
+ import { Dynamic } from '@solidjs/web'
3
+ import { createMemo } from 'solid-js'
4
4
  import type { AsyncRouteComponent } from './route'
5
5
 
6
6
  export function lazyRouteComponent<
@@ -74,7 +74,7 @@ export function lazyRouteComponent<
74
74
  }
75
75
 
76
76
  if (!comp) {
77
- const [compResource] = createResource(load, {
77
+ const compResource = createMemo(load, {
78
78
  initialValue: comp,
79
79
  ssrLoadFrom: 'initial',
80
80
  })
package/src/link.tsx CHANGED
@@ -1,7 +1,5 @@
1
1
  import * as Solid from 'solid-js'
2
2
 
3
- import { mergeRefs } from '@solid-primitives/refs'
4
-
5
3
  import {
6
4
  deepEqual,
7
5
  exactPathTest,
@@ -12,7 +10,7 @@ import {
12
10
  } from '@tanstack/router-core'
13
11
 
14
12
  import { isServer } from '@tanstack/router-core/isServer'
15
- import { Dynamic } from 'solid-js/web'
13
+ import { Dynamic } from '@solidjs/web'
16
14
  import { useRouterState } from './useRouterState'
17
15
  import { useRouter } from './useRouter'
18
16
 
@@ -31,6 +29,31 @@ import type {
31
29
  ValidateLinkOptionsArray,
32
30
  } from './typePrimitives'
33
31
 
32
+ function mergeRefs<T>(
33
+ ...refs: Array<((el: T) => void) | undefined>
34
+ ): (el: T) => void {
35
+ return (el: T) => {
36
+ for (const ref of refs) {
37
+ if (typeof ref === 'function') {
38
+ ref(el)
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ function splitProps<T extends Record<string, any>, TKey extends keyof T>(
45
+ props: T,
46
+ keys: ReadonlyArray<TKey>,
47
+ ): [Pick<T, TKey>, Omit<T, TKey>] {
48
+ const _local = {} as Pick<T, TKey>
49
+ const _rest = {} as Omit<T, TKey>
50
+
51
+ // A safe way to polyfill splitProps if native getter copy is too complex
52
+ // is just to return [props, Solid.omit(props, keys)] but it modifies typing.
53
+ // Actually, Solid.omit exists!
54
+ // Note: Solid.omit uses rest params (...keys), so we must spread the array.
55
+ return [props as any, Solid.omit(props, ...(keys as any)) as any]
56
+ }
34
57
  const timeoutMap = new WeakMap<EventTarget, ReturnType<typeof setTimeout>>()
35
58
 
36
59
  export function useLinkProps<
@@ -49,8 +72,8 @@ export function useLinkProps<
49
72
 
50
73
  let hasRenderFetched = false
51
74
 
52
- const [local, rest] = Solid.splitProps(
53
- Solid.mergeProps(
75
+ const [local, rest] = splitProps(
76
+ Solid.merge(
54
77
  {
55
78
  activeProps: () => ({ class: 'active' }),
56
79
  inactiveProps: () => ({}),
@@ -85,35 +108,7 @@ export function useLinkProps<
85
108
  ],
86
109
  )
87
110
 
88
- // const {
89
- // // custom props
90
- // activeProps = () => ({ class: 'active' }),
91
- // inactiveProps = () => ({}),
92
- // activeOptions,
93
- // to,
94
- // preload: userPreload,
95
- // preloadDelay: userPreloadDelay,
96
- // hashScrollIntoView,
97
- // replace,
98
- // startTransition,
99
- // resetScroll,
100
- // viewTransition,
101
- // // element props
102
- // children,
103
- // target,
104
- // disabled,
105
- // style,
106
- // class,
107
- // onClick,
108
- // onFocus,
109
- // onMouseEnter,
110
- // onMouseLeave,
111
- // onTouchStart,
112
- // ignoreBlocker,
113
- // ...rest
114
- // } = options
115
-
116
- const [_, propsSafeToSpread] = Solid.splitProps(rest, [
111
+ const [_, propsSafeToSpread] = splitProps(rest, [
117
112
  'params',
118
113
  'search',
119
114
  'hash',
@@ -121,7 +116,7 @@ export function useLinkProps<
121
116
  'mask',
122
117
  'reloadDocument',
123
118
  'unsafeRelative',
124
- ])
119
+ ] as any)
125
120
 
126
121
  const currentLocation = useRouterState({
127
122
  select: (s) => s.location,
@@ -141,10 +136,11 @@ export function useLinkProps<
141
136
  const from = options.from
142
137
 
143
138
  const _options = () => {
144
- return {
139
+ const result = {
145
140
  ...options,
146
141
  from,
147
142
  }
143
+ return result
148
144
  }
149
145
 
150
146
  const next = Solid.createMemo(() => {
@@ -274,33 +270,39 @@ export function useLinkProps<
274
270
  }
275
271
  }
276
272
 
277
- const [ref, setRef] = Solid.createSignal<Element | null>(null)
273
+ const [ref, setRefSignal] = Solid.createSignal<Element | null>(null)
274
+
275
+ const setRef = (el: Element | null) => {
276
+ Solid.runWithOwner(null, () => {
277
+ setRefSignal(el)
278
+ })
279
+ }
278
280
 
279
281
  useIntersectionObserver(
280
282
  ref,
281
283
  preloadViewportIoCallback,
282
284
  { rootMargin: '100px' },
283
- { disabled: !!local.disabled || !(preload() === 'viewport') },
285
+ { disabled: !!local.disabled || !(Solid.untrack(preload) === 'viewport') },
284
286
  )
285
287
 
286
- Solid.createEffect(() => {
288
+ Solid.createEffect(preload, (preloadValue) => {
287
289
  if (hasRenderFetched) {
288
290
  return
289
291
  }
290
- if (!local.disabled && preload() === 'render') {
292
+ if (!local.disabled && preloadValue === 'render') {
291
293
  doPreload()
292
294
  hasRenderFetched = true
293
295
  }
294
296
  })
295
297
 
296
- if (externalLink()) {
297
- return Solid.mergeProps(
298
+ if (Solid.untrack(externalLink)) {
299
+ return Solid.merge(
298
300
  propsSafeToSpread,
299
301
  {
300
- ref: mergeRefs(setRef, _options().ref),
302
+ // ref: mergeRefs(setRef, _options().ref),
301
303
  href: externalLink(),
302
304
  },
303
- Solid.splitProps(local, [
305
+ splitProps(local, [
304
306
  'target',
305
307
  'disabled',
306
308
  'style',
@@ -443,14 +445,14 @@ export function useLinkProps<
443
445
  ...resolvedInactiveProps().style,
444
446
  })
445
447
 
446
- return Solid.mergeProps(
448
+ return Solid.merge(
447
449
  propsSafeToSpread,
448
450
  resolvedActiveProps,
449
451
  resolvedInactiveProps,
450
452
  () => {
451
453
  return {
452
454
  href: hrefOption()?.href,
453
- ref: mergeRefs(setRef, _options().ref),
455
+ ref: mergeRefs(setRef, (_options() as any).ref),
454
456
  onClick: composeEventHandlers([local.onClick, handleClick]),
455
457
  onBlur: composeEventHandlers([local.onBlur, handleLeave]),
456
458
  onFocus: composeEventHandlers([local.onFocus, enqueueIntentPreload]),
@@ -480,7 +482,7 @@ export function useLinkProps<
480
482
  })(),
481
483
  ...(local.disabled && {
482
484
  role: 'link',
483
- 'aria-disabled': true,
485
+ 'aria-disabled': 'true',
484
486
  }),
485
487
  ...(isActive() && { 'data-status': 'active', 'aria-current': 'page' }),
486
488
  ...(isTransitioning() && { 'data-transitioning': 'transitioning' }),
@@ -610,20 +612,26 @@ export function createLink<const TComp>(
610
612
  }
611
613
 
612
614
  export const Link: LinkComponent<'a'> = (props) => {
613
- const [local, rest] = Solid.splitProps(
614
- props as typeof props & { _asChild: any },
615
- ['_asChild', 'children'],
616
- )
615
+ const [local, rest] = splitProps(props as typeof props & { _asChild: any }, [
616
+ '_asChild',
617
+ 'children',
618
+ ])
617
619
 
618
- const [_, linkProps] = Solid.splitProps(
619
- useLinkProps(rest as unknown as any),
620
- ['type'],
620
+ const [_, linkProps] = splitProps(useLinkProps(rest as unknown as any), [
621
+ 'type',
622
+ ])
623
+
624
+ // Resolve children once using Solid.children to avoid
625
+ // re-accessing the children getter (which in Solid 2.0 would
626
+ // re-invoke createComponent each time for JSX children).
627
+ const resolvedChildren = Solid.children(
628
+ () => local.children as Solid.JSX.Element,
621
629
  )
622
630
 
623
- const children = Solid.createMemo(() => {
624
- const ch = local.children
631
+ const children = () => {
632
+ const ch = resolvedChildren()
625
633
  if (typeof ch === 'function') {
626
- return ch({
634
+ return (ch as Function)({
627
635
  get isActive() {
628
636
  return (linkProps as any)['data-status'] === 'active'
629
637
  },
@@ -633,11 +641,11 @@ export const Link: LinkComponent<'a'> = (props) => {
633
641
  })
634
642
  }
635
643
 
636
- return ch satisfies Solid.JSX.Element
637
- })
644
+ return ch
645
+ }
638
646
 
639
647
  if (local._asChild === 'svg') {
640
- const [_, svgLinkProps] = Solid.splitProps(linkProps, ['class'])
648
+ const [_, svgLinkProps] = splitProps(linkProps as any, ['class'])
641
649
  return (
642
650
  <svg>
643
651
  <a {...svgLinkProps}>{children()}</a>
@@ -1,14 +1,10 @@
1
1
  import { hydrate } from '@tanstack/router-core/ssr/client'
2
2
  import { Await } from '../awaited'
3
- import { HeadContent } from '../HeadContent'
4
3
  import { RouterProvider } from '../RouterProvider'
5
4
  import type { AnyRouter } from '@tanstack/router-core'
6
- import type { JSXElement } from 'solid-js'
7
5
 
8
6
  let hydrationPromise: Promise<void | Array<Array<void>>> | undefined
9
7
 
10
- const Dummy = (props: { children?: JSXElement }) => <>{props.children}</>
11
-
12
8
  export function RouterClient(props: { router: AnyRouter }) {
13
9
  if (!hydrationPromise) {
14
10
  if (!props.router.state.matches.length) {
@@ -20,24 +16,7 @@ export function RouterClient(props: { router: AnyRouter }) {
20
16
  return (
21
17
  <Await
22
18
  promise={hydrationPromise}
23
- children={() => (
24
- <Dummy>
25
- <Dummy>
26
- <RouterProvider
27
- router={props.router}
28
- InnerWrap={(props) => (
29
- <Dummy>
30
- <Dummy>
31
- <HeadContent />
32
- {props.children}
33
- </Dummy>
34
- <Dummy />
35
- </Dummy>
36
- )}
37
- />
38
- </Dummy>
39
- </Dummy>
40
- )}
19
+ children={() => <RouterProvider router={props.router} />}
41
20
  />
42
21
  )
43
22
  }
@@ -1,60 +1,8 @@
1
- import {
2
- Hydration,
3
- HydrationScript,
4
- NoHydration,
5
- ssr,
6
- useAssets,
7
- } from 'solid-js/web'
8
- import { MetaProvider } from '@solidjs/meta'
9
- import { Asset } from '../Asset'
10
- import { useTags } from '../headContentUtils'
11
1
  import { RouterProvider } from '../RouterProvider'
12
- import { Scripts } from '../Scripts'
13
2
  import type { AnyRouter } from '@tanstack/router-core'
14
3
 
15
- export function ServerHeadContent() {
16
- const tags = useTags()
17
- useAssets(() => {
18
- return (
19
- <MetaProvider>
20
- {tags().map((tag) => (
21
- <Asset {...tag} />
22
- ))}
23
- </MetaProvider>
24
- )
25
- })
26
- return null
27
- }
28
-
29
- const docType = ssr('<!DOCTYPE html>')
30
-
31
4
  export function RouterServer<TRouter extends AnyRouter>(props: {
32
5
  router: TRouter
33
6
  }) {
34
- return (
35
- <NoHydration>
36
- {docType as any}
37
- <html>
38
- <head>
39
- <HydrationScript />
40
- </head>
41
- <body>
42
- <Hydration>
43
- <RouterProvider
44
- router={props.router}
45
- InnerWrap={(props) => (
46
- <NoHydration>
47
- <MetaProvider>
48
- <ServerHeadContent />
49
- <Hydration>{props.children}</Hydration>
50
- <Scripts />
51
- </MetaProvider>
52
- </NoHydration>
53
- )}
54
- />
55
- </Hydration>
56
- </body>
57
- </html>
58
- </NoHydration>
59
- )
7
+ return <RouterProvider router={props.router} />
60
8
  }
@@ -1,4 +1,4 @@
1
- import * as Solid from 'solid-js/web'
1
+ import * as Solid from '@solidjs/web'
2
2
  import { isbot } from 'isbot'
3
3
  import { transformReadableStreamWithRouter } from '@tanstack/router-core/ssr/server'
4
4
  import { makeSsrSerovalPlugin } from '@tanstack/router-core'
@@ -19,8 +19,6 @@ export const renderRouterToStream = async ({
19
19
  }) => {
20
20
  const { writable, readable } = new TransformStream()
21
21
 
22
- const docType = Solid.ssr('<!DOCTYPE html>')
23
-
24
22
  const serializationAdapters =
25
23
  (router.options as any)?.serializationAdapters ||
26
24
  (router.options.ssr as any)?.serializationAdapters
@@ -29,18 +27,10 @@ export const renderRouterToStream = async ({
29
27
  return plugin
30
28
  })
31
29
 
32
- const stream = Solid.renderToStream(
33
- () => (
34
- <>
35
- {docType}
36
- {children()}
37
- </>
38
- ),
39
- {
40
- nonce: router.options.ssr?.nonce,
41
- plugins: serovalPlugins,
42
- } as any,
43
- )
30
+ const stream = Solid.renderToStream(() => children, {
31
+ nonce: router.options.ssr?.nonce,
32
+ plugins: serovalPlugins,
33
+ } as any)
44
34
 
45
35
  if (isbot(request.headers.get('User-Agent'))) {
46
36
  await stream
@@ -1,9 +1,9 @@
1
- import * as Solid from 'solid-js/web'
1
+ import * as Solid from '@solidjs/web'
2
2
  import { makeSsrSerovalPlugin } from '@tanstack/router-core'
3
3
  import type { AnyRouter } from '@tanstack/router-core'
4
4
  import type { JSXElement } from 'solid-js'
5
5
 
6
- export const renderRouterToString = async ({
6
+ export const renderRouterToString = ({
7
7
  router,
8
8
  responseHeaders,
9
9
  children,
@@ -160,7 +160,7 @@ export function useBlocker(
160
160
  opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,
161
161
  condition?: boolean | any,
162
162
  ): Solid.Accessor<BlockerResolver> | void {
163
- const props = Solid.mergeProps(
163
+ const props = Solid.merge(
164
164
  {
165
165
  enableBeforeUnload: true,
166
166
  disabled: false,
@@ -180,7 +180,7 @@ export function useBlocker(
180
180
  reset: undefined,
181
181
  })
182
182
 
183
- Solid.createEffect(() => {
183
+ Solid.createTrackedEffect(() => {
184
184
  const blockerFnComposed = async (blockerFnArgs: BlockerFnArgs) => {
185
185
  function getLocation(
186
186
  location: HistoryLocation,
@@ -303,8 +303,12 @@ export function Block<
303
303
  export function Block(opts: LegacyPromptProps): SolidNode
304
304
 
305
305
  export function Block(opts: PromptProps | LegacyPromptProps): SolidNode {
306
- const [propsWithChildren, rest] = Solid.splitProps(opts, ['children'])
307
- const args = _resolvePromptBlockerArgs(rest)
306
+ const propsWithChildren = {
307
+ get children() {
308
+ return opts.children
309
+ },
310
+ }
311
+ const args = _resolvePromptBlockerArgs(opts)
308
312
 
309
313
  const resolver = useBlocker(args)
310
314
  const children = Solid.createMemo(() => {
package/src/useMatch.tsx CHANGED
@@ -103,17 +103,12 @@ export function useMatch<
103
103
  },
104
104
  } as any)
105
105
 
106
- // Use createEffect to throw errors outside the reactive selector context
107
- // This allows error boundaries to properly catch the errors
108
- 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
- )
115
- }
116
- })
106
+ if (Solid.untrack(matchState).shouldThrowError) {
107
+ invariant(
108
+ false,
109
+ `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
110
+ )
111
+ }
117
112
 
118
113
  // Return an accessor that extracts just the match value
119
114
  return Solid.createMemo(() => matchState().match) as any
@@ -33,7 +33,7 @@ export function Navigate<
33
33
  >(props: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): null {
34
34
  const { navigate } = useRouter()
35
35
 
36
- Solid.onMount(() => {
36
+ Solid.onSettled(() => {
37
37
  navigate({
38
38
  ...props,
39
39
  })
@@ -1,4 +1,4 @@
1
- import { useStore } from '@tanstack/solid-store'
1
+ import { createMemo, createSignal, onCleanup } from 'solid-js'
2
2
  import { isServer } from '@tanstack/router-core/isServer'
3
3
  import { useRouter } from './useRouter'
4
4
  import type {
@@ -8,7 +8,6 @@ import type {
8
8
  } from '@tanstack/router-core'
9
9
  import type { Accessor } from 'solid-js'
10
10
 
11
- // Deep equality check to match behavior of solid-store 0.7.0's reconcile()
12
11
  function deepEqual(a: any, b: any): boolean {
13
12
  if (Object.is(a, b)) return true
14
13
 
@@ -61,26 +60,39 @@ export function useRouterState<
61
60
  const _isServer = isServer ?? router.isServer
62
61
  if (_isServer) {
63
62
  const state = router.state as RouterState<TRouter['routeTree']>
64
- const selected = (
65
- opts?.select ? opts.select(state) : state
66
- ) as UseRouterStateResult<TRouter, TSelected>
67
- return (() => selected) as Accessor<
68
- UseRouterStateResult<TRouter, TSelected>
69
- >
63
+ const selected = createMemo(() =>
64
+ opts?.select ? opts.select(state) : state,
65
+ ) as Accessor<UseRouterStateResult<TRouter, TSelected>>
66
+ return selected
70
67
  }
71
68
 
72
- return useStore(
73
- router.__store,
74
- (state) => {
75
- if (opts?.select) return opts.select(state)
76
-
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>>
69
+ const selector = (state: any) => {
70
+ if (opts?.select) return opts.select(state)
71
+
72
+ return state
73
+ }
74
+
75
+ // Track the latest store state in a signal that updates via subscription.
76
+ // We store the full state so that the selector (which may read reactive
77
+ // props like props.matchId) re-runs inside a Solid tracking scope (the
78
+ // createMemo below) rather than inside the store subscriber callback
79
+ // where reactive reads would be untracked.
80
+ const [storeState, setStoreState] = createSignal(router.__store.get())
81
+
82
+ const unsub = router.__store.subscribe((s) => {
83
+ setStoreState(s)
84
+ }).unsubscribe
85
+
86
+ onCleanup(() => {
87
+ unsub()
88
+ })
89
+
90
+ // Run the selector inside a memo so that:
91
+ // 1. Reactive values read by the selector (e.g. props.matchId) are tracked
92
+ // 2. The result is memoized and only updates when the selected value changes
93
+ const selected = createMemo(() => selector(storeState()), undefined, {
94
+ equals: (a: any, b: any) => deepEqual(a, b),
95
+ })
96
+
97
+ return selected as Accessor<UseRouterStateResult<TRouter, TSelected>>
86
98
  }
package/src/utils.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  import * as Solid from 'solid-js'
2
2
 
3
+ export const useLayoutEffect =
4
+ typeof window !== 'undefined' ? Solid.createEffect : Solid.createEffect
5
+
3
6
  export const usePrevious = (fn: () => boolean) => {
4
7
  return Solid.createMemo(
5
8
  (
@@ -11,8 +14,7 @@ export const usePrevious = (fn: () => boolean) => {
11
14
  const current = fn()
12
15
 
13
16
  if (prev.current !== current) {
14
- prev.previous = prev.current
15
- prev.current = current
17
+ return { previous: prev.current, current }
16
18
  }
17
19
 
18
20
  return prev
@@ -55,8 +57,7 @@ export function useIntersectionObserver<T extends Element>(
55
57
  typeof IntersectionObserver === 'function'
56
58
  let observerRef: IntersectionObserver | null = null
57
59
 
58
- Solid.createEffect(() => {
59
- const r = ref()
60
+ Solid.createEffect(ref, (r) => {
60
61
  if (!r || !isIntersectionObserverAvailable || options.disabled) {
61
62
  return
62
63
  }