@tanstack/react-router 0.0.1-beta.83 → 1.0.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 (225) hide show
  1. package/LICENSE +1 -1
  2. package/build/cjs/CatchBoundary.js +128 -0
  3. package/build/cjs/CatchBoundary.js.map +1 -0
  4. package/build/cjs/Matches.js +233 -0
  5. package/build/cjs/Matches.js.map +1 -0
  6. package/build/cjs/RouterProvider.js +170 -0
  7. package/build/cjs/RouterProvider.js.map +1 -0
  8. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +2 -4
  9. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  10. package/build/cjs/_virtual/with-selector.development.js +16 -0
  11. package/build/cjs/_virtual/with-selector.development.js.map +1 -0
  12. package/build/cjs/_virtual/with-selector.js +16 -0
  13. package/build/cjs/_virtual/with-selector.js.map +1 -0
  14. package/build/cjs/_virtual/with-selector.production.min.js +16 -0
  15. package/build/cjs/_virtual/with-selector.production.min.js.map +1 -0
  16. package/build/cjs/awaited.js +43 -0
  17. package/build/cjs/awaited.js.map +1 -0
  18. package/build/cjs/build/esm/index.js +79 -0
  19. package/build/cjs/build/esm/index.js.map +1 -0
  20. package/build/cjs/defer.js +37 -0
  21. package/build/cjs/defer.js.map +1 -0
  22. package/build/cjs/fileRoute.js +27 -0
  23. package/build/cjs/fileRoute.js.map +1 -0
  24. package/build/cjs/index.js +113 -451
  25. package/build/cjs/index.js.map +1 -1
  26. package/build/cjs/lazyRouteComponent.js +54 -0
  27. package/build/cjs/lazyRouteComponent.js.map +1 -0
  28. package/build/cjs/link.js +223 -0
  29. package/build/cjs/link.js.map +1 -0
  30. package/build/cjs/node_modules/.pnpm/@tanstack_react-store@0.2.1_react-dom@18.2.0_react@18.2.0/node_modules/@tanstack/react-store/build/modern/index.js +47 -0
  31. package/build/cjs/node_modules/.pnpm/@tanstack_react-store@0.2.1_react-dom@18.2.0_react@18.2.0/node_modules/@tanstack/react-store/build/modern/index.js.map +1 -0
  32. package/build/cjs/node_modules/.pnpm/@tanstack_store@0.1.3/node_modules/@tanstack/store/build/modern/index.js +70 -0
  33. package/build/cjs/node_modules/.pnpm/@tanstack_store@0.1.3/node_modules/@tanstack/store/build/modern/index.js.map +1 -0
  34. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js +188 -0
  35. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -0
  36. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js +39 -0
  37. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.min.js.map +1 -0
  38. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/shim/with-selector.js +26 -0
  39. package/build/cjs/node_modules/.pnpm/use-sync-external-store@1.2.0_react@18.2.0/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -0
  40. package/build/cjs/packages/react-router/src/CatchBoundary.js +123 -0
  41. package/build/cjs/packages/react-router/src/CatchBoundary.js.map +1 -0
  42. package/build/cjs/packages/react-router/src/Matches.js +235 -0
  43. package/build/cjs/packages/react-router/src/Matches.js.map +1 -0
  44. package/build/cjs/packages/react-router/src/RouterProvider.js +144 -0
  45. package/build/cjs/packages/react-router/src/RouterProvider.js.map +1 -0
  46. package/build/cjs/packages/react-router/src/awaited.js +43 -0
  47. package/build/cjs/packages/react-router/src/awaited.js.map +1 -0
  48. package/build/cjs/packages/react-router/src/defer.js +37 -0
  49. package/build/cjs/packages/react-router/src/defer.js.map +1 -0
  50. package/build/cjs/packages/react-router/src/fileRoute.js +27 -0
  51. package/build/cjs/packages/react-router/src/fileRoute.js.map +1 -0
  52. package/build/cjs/packages/react-router/src/index.js +61 -0
  53. package/build/cjs/packages/react-router/src/index.js.map +1 -0
  54. package/build/cjs/packages/react-router/src/lazyRouteComponent.js +54 -0
  55. package/build/cjs/packages/react-router/src/lazyRouteComponent.js.map +1 -0
  56. package/build/cjs/packages/react-router/src/link.js +148 -0
  57. package/build/cjs/packages/react-router/src/link.js.map +1 -0
  58. package/build/cjs/packages/react-router/src/path.js +209 -0
  59. package/build/cjs/packages/react-router/src/path.js.map +1 -0
  60. package/build/cjs/packages/react-router/src/qss.js +63 -0
  61. package/build/cjs/packages/react-router/src/qss.js.map +1 -0
  62. package/build/cjs/packages/react-router/src/react.js +634 -0
  63. package/build/cjs/packages/react-router/src/react.js.map +1 -0
  64. package/build/cjs/packages/react-router/src/redirects.js +25 -0
  65. package/build/cjs/packages/react-router/src/redirects.js.map +1 -0
  66. package/build/cjs/packages/react-router/src/route.js +134 -0
  67. package/build/cjs/packages/react-router/src/route.js.map +1 -0
  68. package/build/cjs/packages/react-router/src/router.js +1111 -0
  69. package/build/cjs/packages/react-router/src/router.js.map +1 -0
  70. package/build/cjs/packages/react-router/src/scroll-restoration.js +53 -0
  71. package/build/cjs/packages/react-router/src/scroll-restoration.js.map +1 -0
  72. package/build/cjs/packages/react-router/src/searchParams.js +81 -0
  73. package/build/cjs/packages/react-router/src/searchParams.js.map +1 -0
  74. package/build/cjs/packages/react-router/src/useBlocker.js +61 -0
  75. package/build/cjs/packages/react-router/src/useBlocker.js.map +1 -0
  76. package/build/cjs/packages/react-router/src/useNavigate.js +75 -0
  77. package/build/cjs/packages/react-router/src/useNavigate.js.map +1 -0
  78. package/build/cjs/packages/react-router/src/useParams.js +26 -0
  79. package/build/cjs/packages/react-router/src/useParams.js.map +1 -0
  80. package/build/cjs/packages/react-router/src/useSearch.js +25 -0
  81. package/build/cjs/packages/react-router/src/useSearch.js.map +1 -0
  82. package/build/cjs/packages/react-router/src/utils.js +239 -0
  83. package/build/cjs/packages/react-router/src/utils.js.map +1 -0
  84. package/build/cjs/path.js +214 -0
  85. package/build/cjs/path.js.map +1 -0
  86. package/build/cjs/qss.js +63 -0
  87. package/build/cjs/qss.js.map +1 -0
  88. package/build/cjs/react/CatchBoundary.js +123 -0
  89. package/build/cjs/react/CatchBoundary.js.map +1 -0
  90. package/build/cjs/react/awaited.js +43 -0
  91. package/build/cjs/react/awaited.js.map +1 -0
  92. package/build/cjs/react/defer.js +37 -0
  93. package/build/cjs/react/defer.js.map +1 -0
  94. package/build/cjs/react.js +650 -0
  95. package/build/cjs/react.js.map +1 -0
  96. package/build/cjs/redirects.js +28 -0
  97. package/build/cjs/redirects.js.map +1 -0
  98. package/build/cjs/route.js +191 -0
  99. package/build/cjs/route.js.map +1 -0
  100. package/build/cjs/router.js +1085 -0
  101. package/build/cjs/router.js.map +1 -0
  102. package/build/cjs/routerConfig.js +209 -0
  103. package/build/cjs/routerConfig.js.map +1 -0
  104. package/build/cjs/scroll-restoration.js +202 -0
  105. package/build/cjs/scroll-restoration.js.map +1 -0
  106. package/build/cjs/searchParams.js +81 -0
  107. package/build/cjs/searchParams.js.map +1 -0
  108. package/build/cjs/src/CatchBoundary.js +126 -0
  109. package/build/cjs/src/CatchBoundary.js.map +1 -0
  110. package/build/cjs/src/Matches.js +235 -0
  111. package/build/cjs/src/Matches.js.map +1 -0
  112. package/build/cjs/src/RouterProvider.js +1051 -0
  113. package/build/cjs/src/RouterProvider.js.map +1 -0
  114. package/build/cjs/src/awaited.js +45 -0
  115. package/build/cjs/src/awaited.js.map +1 -0
  116. package/build/cjs/src/defer.js +39 -0
  117. package/build/cjs/src/defer.js.map +1 -0
  118. package/build/cjs/src/fileRoute.js +29 -0
  119. package/build/cjs/src/fileRoute.js.map +1 -0
  120. package/build/cjs/src/index.js +134 -0
  121. package/build/cjs/src/index.js.map +1 -0
  122. package/build/cjs/src/lazyRouteComponent.js +57 -0
  123. package/build/cjs/src/lazyRouteComponent.js.map +1 -0
  124. package/build/cjs/src/link.js +151 -0
  125. package/build/cjs/src/link.js.map +1 -0
  126. package/build/cjs/src/path.js +211 -0
  127. package/build/cjs/src/path.js.map +1 -0
  128. package/build/cjs/src/qss.js +65 -0
  129. package/build/cjs/src/qss.js.map +1 -0
  130. package/build/cjs/src/redirects.js +27 -0
  131. package/build/cjs/src/redirects.js.map +1 -0
  132. package/build/cjs/src/route.js +139 -0
  133. package/build/cjs/src/route.js.map +1 -0
  134. package/build/cjs/src/router.js +203 -0
  135. package/build/cjs/src/router.js.map +1 -0
  136. package/build/cjs/src/scroll-restoration.js +186 -0
  137. package/build/cjs/src/scroll-restoration.js.map +1 -0
  138. package/build/cjs/src/searchParams.js +83 -0
  139. package/build/cjs/src/searchParams.js.map +1 -0
  140. package/build/cjs/src/useBlocker.js +64 -0
  141. package/build/cjs/src/useBlocker.js.map +1 -0
  142. package/build/cjs/src/useNavigate.js +78 -0
  143. package/build/cjs/src/useNavigate.js.map +1 -0
  144. package/build/cjs/src/useParams.js +28 -0
  145. package/build/cjs/src/useParams.js.map +1 -0
  146. package/build/cjs/src/useSearch.js +27 -0
  147. package/build/cjs/src/useSearch.js.map +1 -0
  148. package/build/cjs/src/utils.js +230 -0
  149. package/build/cjs/src/utils.js.map +1 -0
  150. package/build/cjs/useBlocker.js +55 -0
  151. package/build/cjs/useBlocker.js.map +1 -0
  152. package/build/cjs/useNavigate.js +86 -0
  153. package/build/cjs/useNavigate.js.map +1 -0
  154. package/build/cjs/useParams.js +26 -0
  155. package/build/cjs/useParams.js.map +1 -0
  156. package/build/cjs/useSearch.js +25 -0
  157. package/build/cjs/useSearch.js.map +1 -0
  158. package/build/cjs/useStore.js +99 -0
  159. package/build/cjs/useStore.js.map +1 -0
  160. package/build/cjs/utils.js +241 -0
  161. package/build/cjs/utils.js.map +1 -0
  162. package/build/esm/index.js +2581 -337
  163. package/build/esm/index.js.map +1 -1
  164. package/build/stats-html.html +3494 -2700
  165. package/build/stats-react.json +1134 -87
  166. package/build/types/CatchBoundary.d.ts +36 -0
  167. package/build/types/Matches.d.ts +64 -0
  168. package/build/types/RouteMatch.d.ts +23 -0
  169. package/build/types/RouterProvider.d.ts +35 -0
  170. package/build/types/awaited.d.ts +9 -0
  171. package/build/types/defer.d.ts +19 -0
  172. package/build/types/fileRoute.d.ts +38 -0
  173. package/build/types/history.d.ts +7 -0
  174. package/build/types/index.d.ts +911 -88
  175. package/build/types/injectHtml.d.ts +0 -0
  176. package/build/types/lazyRouteComponent.d.ts +2 -0
  177. package/build/types/link.d.ts +93 -0
  178. package/build/types/location.d.ts +12 -0
  179. package/build/types/path.d.ts +17 -0
  180. package/build/types/qss.d.ts +2 -0
  181. package/build/types/react/CatchBoundary.d.ts +33 -0
  182. package/build/types/react/awaited.d.ts +9 -0
  183. package/build/types/react/defer.d.ts +19 -0
  184. package/build/types/react.d.ts +141 -0
  185. package/build/types/redirects.d.ts +11 -0
  186. package/build/types/route.d.ts +283 -0
  187. package/build/types/routeInfo.d.ts +31 -0
  188. package/build/types/router.d.ts +186 -0
  189. package/build/types/scroll-restoration.d.ts +18 -0
  190. package/build/types/searchParams.d.ts +7 -0
  191. package/build/types/useBlocker.d.ts +9 -0
  192. package/build/types/useNavigate.d.ts +19 -0
  193. package/build/types/useParams.d.ts +7 -0
  194. package/build/types/useSearch.d.ts +7 -0
  195. package/build/types/useStore.d.ts +12 -0
  196. package/build/types/utils.d.ts +69 -0
  197. package/build/umd/index.development.js +2829 -1796
  198. package/build/umd/index.development.js.map +1 -1
  199. package/build/umd/index.production.js +4 -24
  200. package/build/umd/index.production.js.map +1 -1
  201. package/package.json +9 -7
  202. package/src/CatchBoundary.tsx +101 -0
  203. package/src/Matches.tsx +423 -0
  204. package/src/RouterProvider.tsx +252 -0
  205. package/src/awaited.tsx +40 -0
  206. package/src/defer.ts +55 -0
  207. package/src/fileRoute.ts +152 -0
  208. package/src/history.ts +8 -0
  209. package/src/index.tsx +28 -747
  210. package/src/lazyRouteComponent.tsx +33 -0
  211. package/src/link.tsx +603 -0
  212. package/src/location.ts +13 -0
  213. package/src/path.ts +261 -0
  214. package/src/qss.ts +53 -0
  215. package/src/redirects.ts +39 -0
  216. package/src/route.ts +882 -0
  217. package/src/routeInfo.ts +84 -0
  218. package/src/router.ts +1671 -0
  219. package/src/scroll-restoration.tsx +230 -0
  220. package/src/searchParams.ts +79 -0
  221. package/src/useBlocker.tsx +27 -0
  222. package/src/useNavigate.tsx +111 -0
  223. package/src/useParams.tsx +25 -0
  224. package/src/useSearch.tsx +25 -0
  225. package/src/utils.ts +360 -0
@@ -0,0 +1,252 @@
1
+ import * as React from 'react'
2
+ import warning from 'tiny-warning'
3
+ import { useStore } from '@tanstack/react-store'
4
+ import { Matches } from './Matches'
5
+ import { NavigateOptions, ResolveRelativePath, ToOptions } from './link'
6
+ import { ParsedLocation } from './location'
7
+ import { AnyRoute } from './route'
8
+ import { RouteById, RoutePaths } from './routeInfo'
9
+ import {
10
+ BuildNextOptions,
11
+ RegisteredRouter,
12
+ Router,
13
+ RouterOptions,
14
+ RouterState,
15
+ } from './router'
16
+ import { NoInfer, pick, useLayoutEffect } from './utils'
17
+ import { MatchRouteOptions } from './Matches'
18
+ import { RouteMatch } from './Matches'
19
+
20
+ export interface CommitLocationOptions {
21
+ replace?: boolean
22
+ resetScroll?: boolean
23
+ startTransition?: boolean
24
+ }
25
+
26
+ export interface MatchLocation {
27
+ to?: string | number | null
28
+ fuzzy?: boolean
29
+ caseSensitive?: boolean
30
+ from?: string
31
+ }
32
+
33
+ export type NavigateFn<TRouteTree extends AnyRoute> = <
34
+ TFrom extends RoutePaths<TRouteTree> = '/',
35
+ TTo extends string = '',
36
+ TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
37
+ TMaskTo extends string = '',
38
+ >(
39
+ opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
40
+ ) => Promise<void>
41
+
42
+ export type MatchRouteFn<TRouteTree extends AnyRoute> = <
43
+ TFrom extends RoutePaths<TRouteTree> = '/',
44
+ TTo extends string = '',
45
+ TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
46
+ >(
47
+ location: ToOptions<TRouteTree, TFrom, TTo>,
48
+ opts?: MatchRouteOptions,
49
+ ) => false | RouteById<TRouteTree, TResolved>['types']['allParams']
50
+
51
+ export type BuildLocationFn<TRouteTree extends AnyRoute> = (
52
+ opts: ToOptions<TRouteTree>,
53
+ ) => ParsedLocation
54
+
55
+ export type InjectedHtmlEntry = string | (() => Promise<string> | string)
56
+
57
+ export let routerContext = React.createContext<Router<any>>(null!)
58
+
59
+ if (typeof document !== 'undefined') {
60
+ if (window.__TSR_ROUTER_CONTEXT__) {
61
+ routerContext = window.__TSR_ROUTER_CONTEXT__
62
+ } else {
63
+ window.__TSR_ROUTER_CONTEXT__ = routerContext as any
64
+ }
65
+ }
66
+
67
+ export function RouterProvider<
68
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
69
+ TDehydrated extends Record<string, any> = Record<string, any>,
70
+ >({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>) {
71
+ // Allow the router to update options on the router instance
72
+ router.update({
73
+ ...router.options,
74
+ ...rest,
75
+ context: {
76
+ ...router.options.context,
77
+ ...rest?.context,
78
+ },
79
+ } as any)
80
+
81
+ const matches = router.options.InnerWrap ? (
82
+ <router.options.InnerWrap>
83
+ <Matches />
84
+ </router.options.InnerWrap>
85
+ ) : (
86
+ <Matches />
87
+ )
88
+
89
+ const provider = (
90
+ <routerContext.Provider value={router}>
91
+ {matches}
92
+ <Transitioner />
93
+ </routerContext.Provider>
94
+ )
95
+
96
+ if (router.options.Wrap) {
97
+ return <router.options.Wrap>{provider}</router.options.Wrap>
98
+ }
99
+
100
+ return provider
101
+ }
102
+
103
+ function Transitioner() {
104
+ const router = useRouter()
105
+ const routerState = useRouterState({
106
+ select: (s) =>
107
+ pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning']),
108
+ })
109
+
110
+ const [isTransitioning, startReactTransition] = React.useTransition()
111
+
112
+ router.startReactTransition = startReactTransition
113
+
114
+ React.useEffect(() => {
115
+ if (isTransitioning) {
116
+ router.__store.setState((s) => ({
117
+ ...s,
118
+ isTransitioning,
119
+ }))
120
+ }
121
+ }, [isTransitioning])
122
+
123
+ const tryLoad = () => {
124
+ const apply = (cb: () => void) => {
125
+ if (!routerState.isTransitioning) {
126
+ startReactTransition(() => cb())
127
+ } else {
128
+ cb()
129
+ }
130
+ }
131
+
132
+ apply(() => {
133
+ try {
134
+ router.load()
135
+ } catch (err) {
136
+ console.error(err)
137
+ }
138
+ })
139
+ }
140
+
141
+ useLayoutEffect(() => {
142
+ const unsub = router.history.subscribe(() => {
143
+ router.latestLocation = router.parseLocation(router.latestLocation)
144
+ if (routerState.location !== router.latestLocation) {
145
+ tryLoad()
146
+ }
147
+ })
148
+
149
+ const nextLocation = router.buildLocation({
150
+ search: true,
151
+ params: true,
152
+ hash: true,
153
+ state: true,
154
+ })
155
+
156
+ if (routerState.location.href !== nextLocation.href) {
157
+ router.commitLocation({ ...nextLocation, replace: true })
158
+ }
159
+
160
+ return () => {
161
+ unsub()
162
+ }
163
+ }, [router.history])
164
+
165
+ useLayoutEffect(() => {
166
+ if (
167
+ routerState.isTransitioning &&
168
+ !isTransitioning &&
169
+ !routerState.isLoading &&
170
+ routerState.resolvedLocation !== routerState.location
171
+ ) {
172
+ router.emit({
173
+ type: 'onResolved',
174
+ fromLocation: routerState.resolvedLocation,
175
+ toLocation: routerState.location,
176
+ pathChanged:
177
+ routerState.location!.href !== routerState.resolvedLocation?.href,
178
+ })
179
+
180
+ if ((document as any).querySelector) {
181
+ if (routerState.location.hash !== '') {
182
+ const el = document.getElementById(
183
+ routerState.location.hash,
184
+ ) as HTMLElement | null
185
+ if (el) {
186
+ el.scrollIntoView()
187
+ }
188
+ }
189
+ }
190
+
191
+ router.__store.setState((s) => ({
192
+ ...s,
193
+ isTransitioning: false,
194
+ resolvedLocation: s.location,
195
+ }))
196
+ }
197
+ }, [
198
+ routerState.isTransitioning,
199
+ isTransitioning,
200
+ routerState.isLoading,
201
+ routerState.resolvedLocation,
202
+ routerState.location,
203
+ ])
204
+
205
+ useLayoutEffect(() => {
206
+ if (!window.__TSR_DEHYDRATED__) {
207
+ tryLoad()
208
+ }
209
+ }, [])
210
+
211
+ return null
212
+ }
213
+
214
+ export function getRouteMatch<TRouteTree extends AnyRoute>(
215
+ state: RouterState<TRouteTree>,
216
+ id: string,
217
+ ): undefined | RouteMatch<TRouteTree> {
218
+ return [
219
+ ...state.cachedMatches,
220
+ ...(state.pendingMatches ?? []),
221
+ ...state.matches,
222
+ ].find((d) => d.id === id)
223
+ }
224
+
225
+ export function useRouterState<
226
+ TSelected = RouterState<RegisteredRouter['routeTree']>,
227
+ >(opts?: {
228
+ select: (state: RouterState<RegisteredRouter['routeTree']>) => TSelected
229
+ }): TSelected {
230
+ const router = useRouter()
231
+ return useStore(router.__store, opts?.select as any)
232
+ }
233
+
234
+ export type RouterProps<
235
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
236
+ TDehydrated extends Record<string, any> = Record<string, any>,
237
+ > = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {
238
+ router: Router<TRouteTree>
239
+ context?: Partial<RouterOptions<TRouteTree, TDehydrated>['context']>
240
+ }
241
+
242
+ export function useRouter<
243
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
244
+ >(): Router<TRouteTree> {
245
+ const resolvedContext =
246
+ typeof document !== 'undefined'
247
+ ? window.__TSR_ROUTER_CONTEXT__ || routerContext
248
+ : routerContext
249
+ const value = React.useContext(resolvedContext)
250
+ warning(value, 'useRouter must be used inside a <RouterProvider> component!')
251
+ return value as any
252
+ }
@@ -0,0 +1,40 @@
1
+ import { useRouter } from './RouterProvider'
2
+ import { DeferredPromise, isDehydratedDeferred } from './defer'
3
+
4
+ export type AwaitOptions<T> = {
5
+ promise: DeferredPromise<T>
6
+ }
7
+
8
+ export function useAwaited<T>({ promise }: AwaitOptions<T>): [T] {
9
+ const router = useRouter()
10
+
11
+ let state = promise.__deferredState
12
+ const key = `__TSR__DEFERRED__${state.uid}`
13
+
14
+ if (isDehydratedDeferred(promise)) {
15
+ state = router.hydrateData(key)!
16
+ promise = Promise.resolve(state.data) as DeferredPromise<any>
17
+ promise.__deferredState = state
18
+ }
19
+
20
+ if (state.status === 'pending') {
21
+ throw new Promise((r) => setTimeout(r, 1)).then(() => promise)
22
+ }
23
+
24
+ if (state.status === 'error') {
25
+ throw state.error
26
+ }
27
+
28
+ router.dehydrateData(key, state)
29
+
30
+ return [state.data]
31
+ }
32
+
33
+ export function Await<T>(
34
+ props: AwaitOptions<T> & {
35
+ children: (result: T) => JSX.Element
36
+ },
37
+ ) {
38
+ const awaited = useAwaited(props)
39
+ return props.children(...awaited)
40
+ }
package/src/defer.ts ADDED
@@ -0,0 +1,55 @@
1
+ export type DeferredPromiseState<T> = { uid: string } & (
2
+ | {
3
+ status: 'pending'
4
+ data?: T
5
+ error?: unknown
6
+ }
7
+ | {
8
+ status: 'success'
9
+ data: T
10
+ }
11
+ | {
12
+ status: 'error'
13
+ data?: T
14
+ error: unknown
15
+ }
16
+ )
17
+
18
+ export type DeferredPromise<T> = Promise<T> & {
19
+ __deferredState: DeferredPromiseState<T>
20
+ }
21
+
22
+ export function defer<T>(_promise: Promise<T>) {
23
+ const promise = _promise as DeferredPromise<T>
24
+
25
+ if (!promise.__deferredState) {
26
+ promise.__deferredState = {
27
+ uid: Math.random().toString(36).slice(2),
28
+ status: 'pending',
29
+ }
30
+
31
+ const state = promise.__deferredState
32
+
33
+ promise
34
+ .then((data) => {
35
+ state.status = 'success' as any
36
+ state.data = data
37
+ })
38
+ .catch((error) => {
39
+ state.status = 'error' as any
40
+ state.error = error
41
+ })
42
+ }
43
+
44
+ return promise
45
+ }
46
+
47
+ export function isDehydratedDeferred(obj: any): boolean {
48
+ return (
49
+ typeof obj === 'object' &&
50
+ obj !== null &&
51
+ !(obj instanceof Promise) &&
52
+ !obj.then &&
53
+ '__deferredState' in obj
54
+ )
55
+ }
@@ -0,0 +1,152 @@
1
+ import { ParsePathParams } from './link'
2
+ import {
3
+ AnyRoute,
4
+ ResolveFullPath,
5
+ ResolveFullSearchSchema,
6
+ MergeFromFromParent,
7
+ RouteContext,
8
+ AnyContext,
9
+ RouteOptions,
10
+ UpdatableRouteOptions,
11
+ Route,
12
+ AnyPathParams,
13
+ RootRouteId,
14
+ TrimPathLeft,
15
+ RouteConstraints,
16
+ } from './route'
17
+ import { Assign, Expand, IsAny } from './utils'
18
+
19
+ export interface FileRoutesByPath {
20
+ // '/': {
21
+ // parentRoute: typeof rootRoute
22
+ // }
23
+ }
24
+
25
+ type Replace<
26
+ S extends string,
27
+ From extends string,
28
+ To extends string,
29
+ > = S extends `${infer Start}${From}${infer Rest}`
30
+ ? `${Start}${To}${Replace<Rest, From, To>}`
31
+ : S
32
+
33
+ export type TrimLeft<
34
+ T extends string,
35
+ S extends string,
36
+ > = T extends `${S}${infer U}` ? U : T
37
+
38
+ export type TrimRight<
39
+ T extends string,
40
+ S extends string,
41
+ > = T extends `${infer U}${S}` ? U : T
42
+
43
+ export type Trim<T extends string, S extends string> = TrimLeft<
44
+ TrimRight<T, S>,
45
+ S
46
+ >
47
+
48
+ export type RemoveUnderScores<T extends string> = Replace<
49
+ Replace<TrimRight<TrimLeft<T, '/_'>, '_'>, '_/', '/'>,
50
+ '/_',
51
+ '/'
52
+ >
53
+
54
+ export type ResolveFilePath<
55
+ TParentRoute extends AnyRoute,
56
+ TFilePath extends string,
57
+ > = TParentRoute['id'] extends RootRouteId
58
+ ? TrimPathLeft<TFilePath>
59
+ : Replace<
60
+ TrimPathLeft<TFilePath>,
61
+ TrimPathLeft<TParentRoute['types']['customId']>,
62
+ ''
63
+ >
64
+
65
+ export type FileRoutePath<
66
+ TParentRoute extends AnyRoute,
67
+ TFilePath extends string,
68
+ > = ResolveFilePath<TParentRoute, TFilePath> extends `_${infer _}`
69
+ ? string
70
+ : ResolveFilePath<TParentRoute, TFilePath>
71
+
72
+ export class FileRoute<
73
+ TFilePath extends keyof FileRoutesByPath,
74
+ TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
75
+ TId extends RouteConstraints['TId'] = TFilePath,
76
+ TPath extends RouteConstraints['TPath'] = FileRoutePath<
77
+ TParentRoute,
78
+ TFilePath
79
+ >,
80
+ TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<
81
+ TParentRoute,
82
+ RemoveUnderScores<TPath>
83
+ >,
84
+ > {
85
+ constructor(public path: TFilePath) {}
86
+
87
+ createRoute = <
88
+ TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
89
+ TFullSearchSchema extends
90
+ RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
91
+ TParentRoute,
92
+ TSearchSchema
93
+ >,
94
+ TParams extends RouteConstraints['TParams'] = Expand<
95
+ Record<ParsePathParams<TPath>, string>
96
+ >,
97
+ TAllParams extends RouteConstraints['TAllParams'] = MergeFromFromParent<
98
+ TParentRoute['types']['allParams'],
99
+ TParams
100
+ >,
101
+ TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
102
+ TContext extends Expand<
103
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
104
+ > = Expand<
105
+ Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
106
+ >,
107
+ TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
108
+ TLoaderDeps extends Record<string, any> = {},
109
+ TLoaderData extends any = unknown,
110
+ TChildren extends RouteConstraints['TChildren'] = unknown,
111
+ TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
112
+ >(
113
+ options?: Omit<
114
+ RouteOptions<
115
+ TParentRoute,
116
+ string,
117
+ TPath,
118
+ TSearchSchema,
119
+ TFullSearchSchema,
120
+ TParams,
121
+ TAllParams,
122
+ TRouteContext,
123
+ TContext,
124
+ TLoaderDeps,
125
+ TLoaderData
126
+ >,
127
+ 'getParentRoute' | 'path' | 'id'
128
+ > &
129
+ UpdatableRouteOptions<TFullSearchSchema>,
130
+ ): Route<
131
+ TParentRoute,
132
+ TPath,
133
+ TFullPath,
134
+ TFilePath,
135
+ TId,
136
+ TSearchSchema,
137
+ TFullSearchSchema,
138
+ TParams,
139
+ TAllParams,
140
+ TRouteContext,
141
+ TContext,
142
+ TRouterContext,
143
+ TLoaderDeps,
144
+ TLoaderData,
145
+ TChildren,
146
+ TRouteTree
147
+ > => {
148
+ const route = new Route(options as any)
149
+ ;(route as any).isRoot = false
150
+ return route as any
151
+ }
152
+ }
package/src/history.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { HistoryLocation } from '@tanstack/history'
2
+
3
+ declare module '@tanstack/history' {
4
+ interface HistoryState {
5
+ __tempLocation?: HistoryLocation
6
+ __tempKey?: string
7
+ }
8
+ }