@tanstack/vue-router 0.0.1 → 1.140.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 (268) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -45
  3. package/dist/esm/Asset.d.ts +2 -0
  4. package/dist/esm/Asset.js +33 -0
  5. package/dist/esm/Asset.js.map +1 -0
  6. package/dist/esm/CatchBoundary.d.ts +19 -0
  7. package/dist/esm/CatchBoundary.js +135 -0
  8. package/dist/esm/CatchBoundary.js.map +1 -0
  9. package/dist/esm/ClientOnly.d.ts +67 -0
  10. package/dist/esm/HeadContent.d.ts +10 -0
  11. package/dist/esm/HeadContent.js +116 -0
  12. package/dist/esm/HeadContent.js.map +1 -0
  13. package/dist/esm/Match.d.ts +25 -0
  14. package/dist/esm/Match.js +262 -0
  15. package/dist/esm/Match.js.map +1 -0
  16. package/dist/esm/Matches.d.ts +39 -0
  17. package/dist/esm/Matches.js +186 -0
  18. package/dist/esm/Matches.js.map +1 -0
  19. package/dist/esm/RouterProvider.d.ts +33 -0
  20. package/dist/esm/RouterProvider.js +65 -0
  21. package/dist/esm/RouterProvider.js.map +1 -0
  22. package/dist/esm/SafeFragment.d.ts +4 -0
  23. package/dist/esm/ScriptOnce.d.ts +5 -0
  24. package/dist/esm/ScriptOnce.js +21 -0
  25. package/dist/esm/ScriptOnce.js.map +1 -0
  26. package/dist/esm/Scripts.d.ts +1 -0
  27. package/dist/esm/Scripts.js +46 -0
  28. package/dist/esm/Scripts.js.map +1 -0
  29. package/dist/esm/ScrollRestoration.d.ts +14 -0
  30. package/dist/esm/ScrollRestoration.js +36 -0
  31. package/dist/esm/ScrollRestoration.js.map +1 -0
  32. package/dist/esm/Transitioner.d.ts +2 -0
  33. package/dist/esm/Transitioner.js +154 -0
  34. package/dist/esm/Transitioner.js.map +1 -0
  35. package/dist/esm/awaited.d.ts +12 -0
  36. package/dist/esm/awaited.js +40 -0
  37. package/dist/esm/awaited.js.map +1 -0
  38. package/dist/esm/fileRoute.d.ts +54 -0
  39. package/dist/esm/fileRoute.js +103 -0
  40. package/dist/esm/fileRoute.js.map +1 -0
  41. package/dist/esm/history.d.ts +8 -0
  42. package/dist/esm/index.d.ts +51 -0
  43. package/dist/esm/index.js +138 -0
  44. package/dist/esm/index.js.map +1 -0
  45. package/dist/esm/lazyRouteComponent.d.ts +8 -0
  46. package/dist/esm/lazyRouteComponent.js +106 -0
  47. package/dist/esm/lazyRouteComponent.js.map +1 -0
  48. package/dist/esm/link.d.ts +61 -0
  49. package/dist/esm/link.js +376 -0
  50. package/dist/esm/link.js.map +1 -0
  51. package/dist/esm/matchContext.d.ts +20 -0
  52. package/dist/esm/matchContext.js +16 -0
  53. package/dist/esm/matchContext.js.map +1 -0
  54. package/dist/esm/not-found.d.ts +12 -0
  55. package/dist/esm/not-found.js +45 -0
  56. package/dist/esm/not-found.js.map +1 -0
  57. package/dist/esm/renderRouteNotFound.d.ts +11 -0
  58. package/dist/esm/renderRouteNotFound.js +19 -0
  59. package/dist/esm/renderRouteNotFound.js.map +1 -0
  60. package/dist/esm/route.d.ts +96 -0
  61. package/dist/esm/route.js +176 -0
  62. package/dist/esm/route.js.map +1 -0
  63. package/dist/esm/router.d.ts +69 -0
  64. package/dist/esm/router.js +14 -0
  65. package/dist/esm/router.js.map +1 -0
  66. package/dist/esm/routerContext.d.ts +21 -0
  67. package/dist/esm/routerContext.js +21 -0
  68. package/dist/esm/routerContext.js.map +1 -0
  69. package/dist/esm/scroll-restoration.d.ts +1 -0
  70. package/dist/esm/scroll-restoration.js +21 -0
  71. package/dist/esm/scroll-restoration.js.map +1 -0
  72. package/dist/esm/typePrimitives.d.ts +10 -0
  73. package/dist/esm/useBlocker.d.ts +66 -0
  74. package/dist/esm/useBlocker.js +295 -0
  75. package/dist/esm/useBlocker.js.map +1 -0
  76. package/dist/esm/useCanGoBack.d.ts +1 -0
  77. package/dist/esm/useCanGoBack.js +8 -0
  78. package/dist/esm/useCanGoBack.js.map +1 -0
  79. package/dist/esm/useLoaderData.d.ts +8 -0
  80. package/dist/esm/useLoaderData.js +14 -0
  81. package/dist/esm/useLoaderData.js.map +1 -0
  82. package/dist/esm/useLoaderDeps.d.ts +7 -0
  83. package/dist/esm/useLoaderDeps.js +17 -0
  84. package/dist/esm/useLoaderDeps.js.map +1 -0
  85. package/dist/esm/useLocation.d.ts +7 -0
  86. package/dist/esm/useLocation.js +10 -0
  87. package/dist/esm/useLocation.js.map +1 -0
  88. package/dist/esm/useMatch.d.ts +10 -0
  89. package/dist/esm/useMatch.js +39 -0
  90. package/dist/esm/useMatch.js.map +1 -0
  91. package/dist/esm/useNavigate.d.ts +5 -0
  92. package/dist/esm/useNavigate.js +29 -0
  93. package/dist/esm/useNavigate.js.map +1 -0
  94. package/dist/esm/useParams.d.ts +9 -0
  95. package/dist/esm/useParams.js +15 -0
  96. package/dist/esm/useParams.js.map +1 -0
  97. package/dist/esm/useRouteContext.d.ts +4 -0
  98. package/dist/esm/useRouteContext.js +11 -0
  99. package/dist/esm/useRouteContext.js.map +1 -0
  100. package/dist/esm/useRouter.d.ts +4 -0
  101. package/dist/esm/useRouter.js +12 -0
  102. package/dist/esm/useRouter.js.map +1 -0
  103. package/dist/esm/useRouterState.d.ts +8 -0
  104. package/dist/esm/useRouterState.js +20 -0
  105. package/dist/esm/useRouterState.js.map +1 -0
  106. package/dist/esm/useSearch.d.ts +9 -0
  107. package/dist/esm/useSearch.js +15 -0
  108. package/dist/esm/useSearch.js.map +1 -0
  109. package/dist/esm/utils.d.ts +40 -0
  110. package/dist/esm/utils.js +44 -0
  111. package/dist/esm/utils.js.map +1 -0
  112. package/dist/source/Asset.d.ts +2 -0
  113. package/dist/source/Asset.jsx +22 -0
  114. package/dist/source/Asset.jsx.map +1 -0
  115. package/dist/source/CatchBoundary.d.ts +19 -0
  116. package/dist/source/CatchBoundary.jsx +134 -0
  117. package/dist/source/CatchBoundary.jsx.map +1 -0
  118. package/dist/source/ClientOnly.d.ts +67 -0
  119. package/dist/source/ClientOnly.jsx +63 -0
  120. package/dist/source/ClientOnly.jsx.map +1 -0
  121. package/dist/source/HeadContent.d.ts +10 -0
  122. package/dist/source/HeadContent.jsx +133 -0
  123. package/dist/source/HeadContent.jsx.map +1 -0
  124. package/dist/source/Match.d.ts +25 -0
  125. package/dist/source/Match.jsx +316 -0
  126. package/dist/source/Match.jsx.map +1 -0
  127. package/dist/source/Matches.d.ts +39 -0
  128. package/dist/source/Matches.jsx +191 -0
  129. package/dist/source/Matches.jsx.map +1 -0
  130. package/dist/source/RouterProvider.d.ts +33 -0
  131. package/dist/source/RouterProvider.jsx +63 -0
  132. package/dist/source/RouterProvider.jsx.map +1 -0
  133. package/dist/source/SafeFragment.d.ts +4 -0
  134. package/dist/source/SafeFragment.jsx +10 -0
  135. package/dist/source/SafeFragment.jsx.map +1 -0
  136. package/dist/source/ScriptOnce.d.ts +5 -0
  137. package/dist/source/ScriptOnce.jsx +17 -0
  138. package/dist/source/ScriptOnce.jsx.map +1 -0
  139. package/dist/source/Scripts.d.ts +1 -0
  140. package/dist/source/Scripts.jsx +49 -0
  141. package/dist/source/Scripts.jsx.map +1 -0
  142. package/dist/source/ScrollRestoration.d.ts +14 -0
  143. package/dist/source/ScrollRestoration.jsx +37 -0
  144. package/dist/source/ScrollRestoration.jsx.map +1 -0
  145. package/dist/source/Transitioner.d.ts +2 -0
  146. package/dist/source/Transitioner.jsx +181 -0
  147. package/dist/source/Transitioner.jsx.map +1 -0
  148. package/dist/source/awaited.d.ts +12 -0
  149. package/dist/source/awaited.jsx +38 -0
  150. package/dist/source/awaited.jsx.map +1 -0
  151. package/dist/source/fileRoute.d.ts +54 -0
  152. package/dist/source/fileRoute.js +98 -0
  153. package/dist/source/fileRoute.js.map +1 -0
  154. package/dist/source/history.d.ts +8 -0
  155. package/dist/source/history.js +2 -0
  156. package/dist/source/history.js.map +1 -0
  157. package/dist/source/index.d.ts +51 -0
  158. package/dist/source/index.jsx +40 -0
  159. package/dist/source/index.jsx.map +1 -0
  160. package/dist/source/lazyRouteComponent.d.ts +8 -0
  161. package/dist/source/lazyRouteComponent.jsx +135 -0
  162. package/dist/source/lazyRouteComponent.jsx.map +1 -0
  163. package/dist/source/link.d.ts +61 -0
  164. package/dist/source/link.jsx +495 -0
  165. package/dist/source/link.jsx.map +1 -0
  166. package/dist/source/matchContext.d.ts +20 -0
  167. package/dist/source/matchContext.jsx +32 -0
  168. package/dist/source/matchContext.jsx.map +1 -0
  169. package/dist/source/not-found.d.ts +12 -0
  170. package/dist/source/not-found.jsx +48 -0
  171. package/dist/source/not-found.jsx.map +1 -0
  172. package/dist/source/renderRouteNotFound.d.ts +11 -0
  173. package/dist/source/renderRouteNotFound.jsx +24 -0
  174. package/dist/source/renderRouteNotFound.jsx.map +1 -0
  175. package/dist/source/route.d.ts +97 -0
  176. package/dist/source/route.js +167 -0
  177. package/dist/source/route.js.map +1 -0
  178. package/dist/source/router.d.ts +70 -0
  179. package/dist/source/router.js +10 -0
  180. package/dist/source/router.js.map +1 -0
  181. package/dist/source/routerContext.d.ts +21 -0
  182. package/dist/source/routerContext.jsx +37 -0
  183. package/dist/source/routerContext.jsx.map +1 -0
  184. package/dist/source/scroll-restoration.d.ts +1 -0
  185. package/dist/source/scroll-restoration.jsx +16 -0
  186. package/dist/source/scroll-restoration.jsx.map +1 -0
  187. package/dist/source/typePrimitives.d.ts +10 -0
  188. package/dist/source/typePrimitives.js +2 -0
  189. package/dist/source/typePrimitives.js.map +1 -0
  190. package/dist/source/useBlocker.d.ts +66 -0
  191. package/dist/source/useBlocker.jsx +308 -0
  192. package/dist/source/useBlocker.jsx.map +1 -0
  193. package/dist/source/useCanGoBack.d.ts +1 -0
  194. package/dist/source/useCanGoBack.js +5 -0
  195. package/dist/source/useCanGoBack.js.map +1 -0
  196. package/dist/source/useLoaderData.d.ts +8 -0
  197. package/dist/source/useLoaderData.jsx +11 -0
  198. package/dist/source/useLoaderData.jsx.map +1 -0
  199. package/dist/source/useLoaderDeps.d.ts +7 -0
  200. package/dist/source/useLoaderDeps.jsx +11 -0
  201. package/dist/source/useLoaderDeps.jsx.map +1 -0
  202. package/dist/source/useLocation.d.ts +7 -0
  203. package/dist/source/useLocation.jsx +7 -0
  204. package/dist/source/useLocation.jsx.map +1 -0
  205. package/dist/source/useMatch.d.ts +10 -0
  206. package/dist/source/useMatch.jsx +46 -0
  207. package/dist/source/useMatch.jsx.map +1 -0
  208. package/dist/source/useNavigate.d.ts +5 -0
  209. package/dist/source/useNavigate.jsx +18 -0
  210. package/dist/source/useNavigate.jsx.map +1 -0
  211. package/dist/source/useParams.d.ts +9 -0
  212. package/dist/source/useParams.jsx +12 -0
  213. package/dist/source/useParams.jsx.map +1 -0
  214. package/dist/source/useRouteContext.d.ts +4 -0
  215. package/dist/source/useRouteContext.js +8 -0
  216. package/dist/source/useRouteContext.js.map +1 -0
  217. package/dist/source/useRouter.d.ts +4 -0
  218. package/dist/source/useRouter.jsx +9 -0
  219. package/dist/source/useRouter.jsx.map +1 -0
  220. package/dist/source/useRouterState.d.ts +8 -0
  221. package/dist/source/useRouterState.jsx +19 -0
  222. package/dist/source/useRouterState.jsx.map +1 -0
  223. package/dist/source/useSearch.d.ts +9 -0
  224. package/dist/source/useSearch.jsx +12 -0
  225. package/dist/source/useSearch.jsx.map +1 -0
  226. package/dist/source/utils.d.ts +40 -0
  227. package/dist/source/utils.js +78 -0
  228. package/dist/source/utils.js.map +1 -0
  229. package/package.json +77 -7
  230. package/src/Asset.tsx +23 -0
  231. package/src/CatchBoundary.tsx +186 -0
  232. package/src/ClientOnly.tsx +75 -0
  233. package/src/HeadContent.tsx +159 -0
  234. package/src/Match.tsx +415 -0
  235. package/src/Matches.tsx +349 -0
  236. package/src/RouterProvider.tsx +117 -0
  237. package/src/SafeFragment.tsx +10 -0
  238. package/src/ScriptOnce.tsx +30 -0
  239. package/src/Scripts.tsx +65 -0
  240. package/src/ScrollRestoration.tsx +69 -0
  241. package/src/Transitioner.tsx +213 -0
  242. package/src/awaited.tsx +54 -0
  243. package/src/fileRoute.ts +271 -0
  244. package/src/history.ts +9 -0
  245. package/src/index.tsx +346 -0
  246. package/src/lazyRouteComponent.tsx +173 -0
  247. package/src/link.tsx +765 -0
  248. package/src/matchContext.tsx +41 -0
  249. package/src/not-found.tsx +55 -0
  250. package/src/renderRouteNotFound.tsx +35 -0
  251. package/src/route.ts +658 -0
  252. package/src/router.ts +103 -0
  253. package/src/routerContext.tsx +53 -0
  254. package/src/scroll-restoration.tsx +29 -0
  255. package/src/typePrimitives.ts +74 -0
  256. package/src/useBlocker.tsx +501 -0
  257. package/src/useCanGoBack.ts +5 -0
  258. package/src/useLoaderData.tsx +50 -0
  259. package/src/useLoaderDeps.tsx +46 -0
  260. package/src/useLocation.tsx +30 -0
  261. package/src/useMatch.tsx +127 -0
  262. package/src/useNavigate.tsx +40 -0
  263. package/src/useParams.tsx +71 -0
  264. package/src/useRouteContext.ts +31 -0
  265. package/src/useRouter.tsx +15 -0
  266. package/src/useRouterState.tsx +43 -0
  267. package/src/useSearch.tsx +71 -0
  268. package/src/utils.ts +111 -0
@@ -0,0 +1,213 @@
1
+ import * as Vue from 'vue'
2
+ import {
3
+ getLocationChangeInfo,
4
+ handleHashScroll,
5
+ trimPathRight,
6
+ } from '@tanstack/router-core'
7
+ import { useRouter } from './useRouter'
8
+ import { useRouterState } from './useRouterState'
9
+ import { usePrevious } from './utils'
10
+
11
+ export const Transitioner = Vue.defineComponent({
12
+ name: 'Transitioner',
13
+ setup() {
14
+ const router = useRouter()
15
+ let mountLoadForRouter = { router, mounted: false }
16
+
17
+ if (router.isServer) {
18
+ return () => null
19
+ }
20
+
21
+ const isLoading = useRouterState({
22
+ select: ({ isLoading }) => isLoading,
23
+ })
24
+
25
+ // Track if we're in a transition - using a ref to track async transitions
26
+ const isTransitioning = Vue.ref(false)
27
+
28
+ // Track pending state changes
29
+ const hasPendingMatches = useRouterState({
30
+ select: (s) => s.matches.some((d) => d.status === 'pending'),
31
+ })
32
+
33
+ const previousIsLoading = usePrevious(() => isLoading.value)
34
+
35
+ const isAnyPending = Vue.computed(
36
+ () => isLoading.value || isTransitioning.value || hasPendingMatches.value,
37
+ )
38
+ const previousIsAnyPending = usePrevious(() => isAnyPending.value)
39
+
40
+ const isPagePending = Vue.computed(
41
+ () => isLoading.value || hasPendingMatches.value,
42
+ )
43
+ const previousIsPagePending = usePrevious(() => isPagePending.value)
44
+
45
+ // Implement startTransition similar to React/Solid
46
+ // Vue doesn't have a native useTransition like React 18, so we simulate it
47
+ // We also update the router state's isTransitioning flag so useMatch can check it
48
+ router.startTransition = (fn: () => void | Promise<void>) => {
49
+ isTransitioning.value = true
50
+ // Also update the router state so useMatch knows we're transitioning
51
+ try {
52
+ router.__store.setState((s) => ({ ...s, isTransitioning: true }))
53
+ } catch {
54
+ // Ignore errors if component is unmounted
55
+ }
56
+
57
+ // Helper to end the transition
58
+ const endTransition = () => {
59
+ // Use nextTick to ensure Vue has processed all reactive updates
60
+ Vue.nextTick(() => {
61
+ try {
62
+ isTransitioning.value = false
63
+ router.__store.setState((s) => ({ ...s, isTransitioning: false }))
64
+ } catch {
65
+ // Ignore errors if component is unmounted
66
+ }
67
+ })
68
+ }
69
+
70
+ // Execute the function synchronously
71
+ // The function internally may call startViewTransition which schedules async work
72
+ // via document.startViewTransition, but we don't need to wait for it here
73
+ // because Vue's reactivity will trigger re-renders when state changes
74
+ fn()
75
+
76
+ // End the transition on next tick to allow Vue to process reactive updates
77
+ endTransition()
78
+ }
79
+
80
+ // For Vue, we need to completely override startViewTransition because Vue's
81
+ // async rendering doesn't work well with the View Transitions API's requirement
82
+ // for synchronous DOM updates. The browser expects the DOM to be updated
83
+ // when the callback promise resolves, but Vue updates asynchronously.
84
+ //
85
+ // Our approach: Skip the actual view transition animation but still update state.
86
+ // This ensures navigation works correctly even without the visual transition.
87
+ // In the future, we could explore using viewTransition.captured like vue-view-transitions does.
88
+ router.startViewTransition = (fn: () => Promise<void>) => {
89
+ // Just run the callback directly without wrapping in document.startViewTransition
90
+ // This ensures the state updates happen and Vue can render them normally
91
+ fn()
92
+ }
93
+
94
+ // Subscribe to location changes
95
+ // and try to load the new location
96
+ let unsubscribe: (() => void) | undefined
97
+
98
+ Vue.onMounted(() => {
99
+ unsubscribe = router.history.subscribe(router.load)
100
+
101
+ const nextLocation = router.buildLocation({
102
+ to: router.latestLocation.pathname,
103
+ search: true,
104
+ params: true,
105
+ hash: true,
106
+ state: true,
107
+ _includeValidateSearch: true,
108
+ })
109
+
110
+ if (
111
+ trimPathRight(router.latestLocation.href) !==
112
+ trimPathRight(nextLocation.href)
113
+ ) {
114
+ router.commitLocation({ ...nextLocation, replace: true })
115
+ }
116
+ })
117
+
118
+ // Track if component is mounted to prevent updates after unmount
119
+ const isMounted = Vue.ref(false)
120
+
121
+ Vue.onMounted(() => {
122
+ isMounted.value = true
123
+ })
124
+
125
+ Vue.onUnmounted(() => {
126
+ isMounted.value = false
127
+ if (unsubscribe) {
128
+ unsubscribe()
129
+ }
130
+ })
131
+
132
+ // Try to load the initial location
133
+ Vue.onMounted(() => {
134
+ if (
135
+ (typeof window !== 'undefined' && router.ssr) ||
136
+ (mountLoadForRouter.router === router && mountLoadForRouter.mounted)
137
+ ) {
138
+ return
139
+ }
140
+ mountLoadForRouter = { router, mounted: true }
141
+ const tryLoad = async () => {
142
+ try {
143
+ await router.load()
144
+ } catch (err) {
145
+ console.error(err)
146
+ }
147
+ }
148
+ tryLoad()
149
+ })
150
+
151
+ // Setup watchers for emitting events
152
+ // All watchers check isMounted to prevent updates after unmount
153
+ Vue.watch(
154
+ () => isLoading.value,
155
+ (newValue) => {
156
+ if (!isMounted.value) return
157
+ try {
158
+ if (previousIsLoading.value.previous && !newValue) {
159
+ router.emit({
160
+ type: 'onLoad',
161
+ ...getLocationChangeInfo(router.state),
162
+ })
163
+ }
164
+ } catch {
165
+ // Ignore errors if component is unmounted
166
+ }
167
+ },
168
+ )
169
+
170
+ Vue.watch(isPagePending, (newValue) => {
171
+ if (!isMounted.value) return
172
+ try {
173
+ // emit onBeforeRouteMount
174
+ if (previousIsPagePending.value.previous && !newValue) {
175
+ router.emit({
176
+ type: 'onBeforeRouteMount',
177
+ ...getLocationChangeInfo(router.state),
178
+ })
179
+ }
180
+ } catch {
181
+ // Ignore errors if component is unmounted
182
+ }
183
+ })
184
+
185
+ Vue.watch(isAnyPending, (newValue) => {
186
+ if (!isMounted.value) return
187
+ try {
188
+ // The router was pending and now it's not
189
+ if (previousIsAnyPending.value.previous && !newValue) {
190
+ const changeInfo = getLocationChangeInfo(router.state)
191
+ router.emit({
192
+ type: 'onResolved',
193
+ ...changeInfo,
194
+ })
195
+
196
+ router.__store.setState((s) => ({
197
+ ...s,
198
+ status: 'idle',
199
+ resolvedLocation: s.location,
200
+ }))
201
+
202
+ if (changeInfo.hrefChanged) {
203
+ handleHashScroll(router)
204
+ }
205
+ }
206
+ } catch {
207
+ // Ignore errors if component is unmounted
208
+ }
209
+ })
210
+
211
+ return () => null
212
+ },
213
+ })
@@ -0,0 +1,54 @@
1
+ import * as Vue from 'vue'
2
+
3
+ import { TSR_DEFERRED_PROMISE, defer } from '@tanstack/router-core'
4
+ import type { DeferredPromise } from '@tanstack/router-core'
5
+
6
+ export type AwaitOptions<T> = {
7
+ promise: Promise<T>
8
+ }
9
+
10
+ export function useAwaited<T>({
11
+ promise: _promise,
12
+ }: AwaitOptions<T>): [T, DeferredPromise<T>] {
13
+ const promise = defer(_promise)
14
+
15
+ if (promise[TSR_DEFERRED_PROMISE].status === 'pending') {
16
+ throw promise
17
+ }
18
+
19
+ if (promise[TSR_DEFERRED_PROMISE].status === 'error') {
20
+ throw promise[TSR_DEFERRED_PROMISE].error
21
+ }
22
+
23
+ return [promise[TSR_DEFERRED_PROMISE].data, promise]
24
+ }
25
+
26
+ export function Await<T>(
27
+ props: AwaitOptions<T> & {
28
+ fallback?: Vue.VNode
29
+ children: (result: T) => Vue.VNode
30
+ },
31
+ ) {
32
+ const data = Vue.ref<T | null>(null)
33
+ const error = Vue.ref<Error | null>(null)
34
+ const pending = Vue.ref(true)
35
+
36
+ Vue.watchEffect(async () => {
37
+ pending.value = true
38
+ try {
39
+ data.value = await props.promise
40
+ } catch (err) {
41
+ error.value = err as Error
42
+ } finally {
43
+ pending.value = false
44
+ }
45
+ })
46
+
47
+ const inner = Vue.computed(() => {
48
+ if (error.value) throw error.value
49
+ if (pending.value) return props.fallback
50
+ return props.children(data.value as T)
51
+ })
52
+
53
+ return () => inner.value
54
+ }
@@ -0,0 +1,271 @@
1
+ import warning from 'tiny-warning'
2
+ import { createRoute } from './route'
3
+
4
+ import { useMatch } from './useMatch'
5
+ import { useLoaderDeps } from './useLoaderDeps'
6
+ import { useLoaderData } from './useLoaderData'
7
+ import { useSearch } from './useSearch'
8
+ import { useParams } from './useParams'
9
+ import { useNavigate } from './useNavigate'
10
+ import { useRouter } from './useRouter'
11
+ import type { UseParamsRoute } from './useParams'
12
+ import type { UseMatchRoute } from './useMatch'
13
+ import type { UseSearchRoute } from './useSearch'
14
+ import type {
15
+ AnyContext,
16
+ AnyRoute,
17
+ AnyRouter,
18
+ Constrain,
19
+ ConstrainLiteral,
20
+ FileBaseRouteOptions,
21
+ FileRoutesByPath,
22
+ LazyRouteOptions,
23
+ Register,
24
+ RegisteredRouter,
25
+ ResolveParams,
26
+ Route,
27
+ RouteById,
28
+ RouteConstraints,
29
+ RouteIds,
30
+ RouteLoaderFn,
31
+ UpdatableRouteOptions,
32
+ UseNavigateResult,
33
+ } from '@tanstack/router-core'
34
+ import type { UseLoaderDepsRoute } from './useLoaderDeps'
35
+ import type { UseLoaderDataRoute } from './useLoaderData'
36
+ import type { UseRouteContextRoute } from './useRouteContext'
37
+
38
+ export function createFileRoute<
39
+ TFilePath extends keyof FileRoutesByPath,
40
+ TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
41
+ TId extends RouteConstraints['TId'] = FileRoutesByPath[TFilePath]['id'],
42
+ TPath extends RouteConstraints['TPath'] = FileRoutesByPath[TFilePath]['path'],
43
+ TFullPath extends
44
+ RouteConstraints['TFullPath'] = FileRoutesByPath[TFilePath]['fullPath'],
45
+ >(
46
+ path?: TFilePath,
47
+ ): FileRoute<TFilePath, TParentRoute, TId, TPath, TFullPath>['createRoute'] {
48
+ if (typeof path === 'object') {
49
+ return new FileRoute<TFilePath, TParentRoute, TId, TPath, TFullPath>(path, {
50
+ silent: true,
51
+ }).createRoute(path) as any
52
+ }
53
+ return new FileRoute<TFilePath, TParentRoute, TId, TPath, TFullPath>(path, {
54
+ silent: true,
55
+ }).createRoute
56
+ }
57
+
58
+ /**
59
+ @deprecated It's no longer recommended to use the `FileRoute` class directly.
60
+ Instead, use `createFileRoute('/path/to/file')(options)` to create a file route.
61
+ */
62
+ export class FileRoute<
63
+ TFilePath extends keyof FileRoutesByPath,
64
+ TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
65
+ TId extends RouteConstraints['TId'] = FileRoutesByPath[TFilePath]['id'],
66
+ TPath extends RouteConstraints['TPath'] = FileRoutesByPath[TFilePath]['path'],
67
+ TFullPath extends
68
+ RouteConstraints['TFullPath'] = FileRoutesByPath[TFilePath]['fullPath'],
69
+ > {
70
+ silent?: boolean
71
+
72
+ constructor(
73
+ public path?: TFilePath,
74
+ _opts?: { silent: boolean },
75
+ ) {
76
+ this.silent = _opts?.silent
77
+ }
78
+
79
+ createRoute = <
80
+ TRegister = Register,
81
+ TSearchValidator = undefined,
82
+ TParams = ResolveParams<TPath>,
83
+ TRouteContextFn = AnyContext,
84
+ TBeforeLoadFn = AnyContext,
85
+ TLoaderDeps extends Record<string, any> = {},
86
+ TLoaderFn = undefined,
87
+ TChildren = unknown,
88
+ TSSR = unknown,
89
+ TMiddlewares = unknown,
90
+ THandlers = undefined,
91
+ >(
92
+ options?: FileBaseRouteOptions<
93
+ TRegister,
94
+ TParentRoute,
95
+ TId,
96
+ TPath,
97
+ TSearchValidator,
98
+ TParams,
99
+ TLoaderDeps,
100
+ TLoaderFn,
101
+ AnyContext,
102
+ TRouteContextFn,
103
+ TBeforeLoadFn,
104
+ AnyContext,
105
+ TSSR,
106
+ TMiddlewares,
107
+ THandlers
108
+ > &
109
+ UpdatableRouteOptions<
110
+ TParentRoute,
111
+ TId,
112
+ TFullPath,
113
+ TParams,
114
+ TSearchValidator,
115
+ TLoaderFn,
116
+ TLoaderDeps,
117
+ AnyContext,
118
+ TRouteContextFn,
119
+ TBeforeLoadFn
120
+ >,
121
+ ): Route<
122
+ TRegister,
123
+ TParentRoute,
124
+ TPath,
125
+ TFullPath,
126
+ TFilePath,
127
+ TId,
128
+ TSearchValidator,
129
+ TParams,
130
+ AnyContext,
131
+ TRouteContextFn,
132
+ TBeforeLoadFn,
133
+ TLoaderDeps,
134
+ TLoaderFn,
135
+ TChildren,
136
+ unknown,
137
+ TSSR,
138
+ TMiddlewares,
139
+ THandlers
140
+ > => {
141
+ warning(
142
+ this.silent,
143
+ 'FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.',
144
+ )
145
+ const route = createRoute(options as any)
146
+ ;(route as any).isRoot = false
147
+ return route as any
148
+ }
149
+ }
150
+
151
+ /**
152
+ @deprecated It's recommended not to split loaders into separate files.
153
+ Instead, place the loader function in the the main route file, inside the
154
+ `createFileRoute('/path/to/file)(options)` options.
155
+ */
156
+ export function FileRouteLoader<
157
+ TFilePath extends keyof FileRoutesByPath,
158
+ TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute'],
159
+ >(
160
+ _path: TFilePath,
161
+ ): <TLoaderFn>(
162
+ loaderFn: Constrain<
163
+ TLoaderFn,
164
+ RouteLoaderFn<
165
+ Register,
166
+ TRoute['parentRoute'],
167
+ TRoute['types']['id'],
168
+ TRoute['types']['params'],
169
+ TRoute['types']['loaderDeps'],
170
+ TRoute['types']['routerContext'],
171
+ TRoute['types']['routeContextFn'],
172
+ TRoute['types']['beforeLoadFn']
173
+ >
174
+ >,
175
+ ) => TLoaderFn {
176
+ warning(
177
+ false,
178
+ `FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`,
179
+ )
180
+ return (loaderFn) => loaderFn as any
181
+ }
182
+
183
+ declare module '@tanstack/router-core' {
184
+ export interface LazyRoute<in out TRoute extends AnyRoute> {
185
+ useMatch: UseMatchRoute<TRoute['id']>
186
+ useRouteContext: UseRouteContextRoute<TRoute['id']>
187
+ useSearch: UseSearchRoute<TRoute['id']>
188
+ useParams: UseParamsRoute<TRoute['id']>
189
+ useLoaderDeps: UseLoaderDepsRoute<TRoute['id']>
190
+ useLoaderData: UseLoaderDataRoute<TRoute['id']>
191
+ useNavigate: () => UseNavigateResult<TRoute['fullPath']>
192
+ }
193
+ }
194
+
195
+ export class LazyRoute<TRoute extends AnyRoute> {
196
+ options: {
197
+ id: string
198
+ } & LazyRouteOptions
199
+
200
+ constructor(
201
+ opts: {
202
+ id: string
203
+ } & LazyRouteOptions,
204
+ ) {
205
+ this.options = opts
206
+ }
207
+
208
+ useMatch: UseMatchRoute<TRoute['id']> = (opts) => {
209
+ return useMatch({
210
+ select: opts?.select,
211
+ from: this.options.id,
212
+ } as any) as any
213
+ }
214
+
215
+ useRouteContext: UseRouteContextRoute<TRoute['id']> = (opts) => {
216
+ return useMatch({
217
+ from: this.options.id,
218
+ select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),
219
+ }) as any
220
+ }
221
+
222
+ useSearch: UseSearchRoute<TRoute['id']> = (opts) => {
223
+ return useSearch({
224
+ select: opts?.select,
225
+ from: this.options.id,
226
+ } as any) as any
227
+ }
228
+
229
+ useParams: UseParamsRoute<TRoute['id']> = (opts) => {
230
+ return useParams({
231
+ select: opts?.select,
232
+ from: this.options.id,
233
+ } as any) as any
234
+ }
235
+
236
+ useLoaderDeps: UseLoaderDepsRoute<TRoute['id']> = (opts) => {
237
+ return useLoaderDeps({ ...opts, from: this.options.id } as any)
238
+ }
239
+
240
+ useLoaderData: UseLoaderDataRoute<TRoute['id']> = (opts) => {
241
+ return useLoaderData({ ...opts, from: this.options.id } as any)
242
+ }
243
+
244
+ useNavigate = (): UseNavigateResult<TRoute['fullPath']> => {
245
+ const router = useRouter()
246
+ return useNavigate({ from: router.routesById[this.options.id].fullPath })
247
+ }
248
+ }
249
+
250
+ export function createLazyRoute<
251
+ TRouter extends AnyRouter = RegisteredRouter,
252
+ TId extends string = string,
253
+ TRoute extends AnyRoute = RouteById<TRouter['routeTree'], TId>,
254
+ >(id: ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>) {
255
+ return (opts: LazyRouteOptions) => {
256
+ return new LazyRoute<TRoute>({
257
+ id: id,
258
+ ...opts,
259
+ })
260
+ }
261
+ }
262
+ export function createLazyFileRoute<
263
+ TFilePath extends keyof FileRoutesByPath,
264
+ TRoute extends FileRoutesByPath[TFilePath]['preLoaderRoute'],
265
+ >(id: TFilePath): (opts: LazyRouteOptions) => LazyRoute<TRoute> {
266
+ if (typeof id === 'object') {
267
+ return new LazyRoute<TRoute>(id) as any
268
+ }
269
+
270
+ return (opts: LazyRouteOptions) => new LazyRoute<TRoute>({ id, ...opts })
271
+ }
package/src/history.ts ADDED
@@ -0,0 +1,9 @@
1
+ import type { HistoryLocation } from '@tanstack/history'
2
+
3
+ declare module '@tanstack/history' {
4
+ interface HistoryState {
5
+ __tempLocation?: HistoryLocation
6
+ __tempKey?: string
7
+ __hashScrollIntoViewOptions?: boolean | ScrollIntoViewOptions
8
+ }
9
+ }