@tanstack/react-router 0.0.1-beta.23 → 0.0.1-beta.231

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/build/cjs/CatchBoundary.js +123 -0
  3. package/build/cjs/CatchBoundary.js.map +1 -0
  4. package/build/cjs/Matches.js +235 -0
  5. package/build/cjs/Matches.js.map +1 -0
  6. package/build/cjs/RouterProvider.js +159 -0
  7. package/build/cjs/RouterProvider.js.map +1 -0
  8. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +2 -22
  9. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  10. package/build/cjs/awaited.js +43 -0
  11. package/build/cjs/awaited.js.map +1 -0
  12. package/build/cjs/defer.js +37 -0
  13. package/build/cjs/defer.js.map +1 -0
  14. package/build/cjs/fileRoute.js +27 -0
  15. package/build/cjs/fileRoute.js.map +1 -0
  16. package/build/cjs/index.js +123 -0
  17. package/build/cjs/index.js.map +1 -0
  18. package/build/cjs/lazyRouteComponent.js +54 -0
  19. package/build/cjs/lazyRouteComponent.js.map +1 -0
  20. package/build/cjs/link.js +148 -0
  21. package/build/cjs/link.js.map +1 -0
  22. package/build/cjs/path.js +209 -0
  23. package/build/cjs/path.js.map +1 -0
  24. package/build/cjs/qss.js +63 -0
  25. package/build/cjs/qss.js.map +1 -0
  26. package/build/cjs/redirects.js +25 -0
  27. package/build/cjs/redirects.js.map +1 -0
  28. package/build/cjs/route.js +134 -0
  29. package/build/cjs/route.js.map +1 -0
  30. package/build/cjs/router.js +1101 -0
  31. package/build/cjs/router.js.map +1 -0
  32. package/build/cjs/scroll-restoration.js +202 -0
  33. package/build/cjs/scroll-restoration.js.map +1 -0
  34. package/build/cjs/searchParams.js +81 -0
  35. package/build/cjs/searchParams.js.map +1 -0
  36. package/build/cjs/useBlocker.js +61 -0
  37. package/build/cjs/useBlocker.js.map +1 -0
  38. package/build/cjs/useNavigate.js +75 -0
  39. package/build/cjs/useNavigate.js.map +1 -0
  40. package/build/cjs/useParams.js +26 -0
  41. package/build/cjs/useParams.js.map +1 -0
  42. package/build/cjs/useSearch.js +25 -0
  43. package/build/cjs/useSearch.js.map +1 -0
  44. package/build/cjs/utils.js +239 -0
  45. package/build/cjs/utils.js.map +1 -0
  46. package/build/esm/index.js +2174 -2557
  47. package/build/esm/index.js.map +1 -1
  48. package/build/stats-html.html +3498 -2694
  49. package/build/stats-react.json +927 -42
  50. package/build/types/CatchBoundary.d.ts +33 -0
  51. package/build/types/Matches.d.ts +57 -0
  52. package/build/types/RouterProvider.d.ts +41 -0
  53. package/build/types/awaited.d.ts +9 -0
  54. package/build/types/defer.d.ts +19 -0
  55. package/build/types/fileRoute.d.ts +35 -0
  56. package/build/types/history.d.ts +7 -0
  57. package/build/types/index.d.ts +27 -108
  58. package/build/types/injectHtml.d.ts +0 -0
  59. package/build/types/lazyRouteComponent.d.ts +2 -0
  60. package/build/types/link.d.ts +105 -0
  61. package/build/types/location.d.ts +14 -0
  62. package/build/types/path.d.ts +16 -0
  63. package/build/types/qss.d.ts +2 -0
  64. package/build/types/redirects.d.ts +10 -0
  65. package/build/types/route.d.ts +278 -0
  66. package/build/types/routeInfo.d.ts +22 -0
  67. package/build/types/router.d.ts +167 -0
  68. package/build/types/scroll-restoration.d.ts +18 -0
  69. package/build/types/searchParams.d.ts +7 -0
  70. package/build/types/useBlocker.d.ts +8 -0
  71. package/build/types/useNavigate.d.ts +20 -0
  72. package/build/types/useParams.d.ts +7 -0
  73. package/build/types/useSearch.d.ts +7 -0
  74. package/build/types/utils.d.ts +66 -0
  75. package/build/umd/index.development.js +2470 -2513
  76. package/build/umd/index.development.js.map +1 -1
  77. package/build/umd/index.production.js +4 -4
  78. package/build/umd/index.production.js.map +1 -1
  79. package/package.json +9 -10
  80. package/src/CatchBoundary.tsx +98 -0
  81. package/src/Matches.tsx +389 -0
  82. package/src/RouterProvider.tsx +226 -0
  83. package/src/awaited.tsx +40 -0
  84. package/src/defer.ts +55 -0
  85. package/src/fileRoute.ts +154 -0
  86. package/src/history.ts +8 -0
  87. package/src/index.tsx +28 -709
  88. package/src/injectHtml.ts +28 -0
  89. package/src/lazyRouteComponent.tsx +33 -0
  90. package/src/link.tsx +508 -0
  91. package/src/location.ts +15 -0
  92. package/src/path.ts +256 -0
  93. package/src/qss.ts +53 -0
  94. package/src/redirects.ts +31 -0
  95. package/src/route.ts +861 -0
  96. package/src/routeInfo.ts +68 -0
  97. package/src/router.ts +1664 -0
  98. package/src/scroll-restoration.tsx +230 -0
  99. package/src/searchParams.ts +79 -0
  100. package/src/useBlocker.tsx +34 -0
  101. package/src/useNavigate.tsx +109 -0
  102. package/src/useParams.tsx +25 -0
  103. package/src/useSearch.tsx +25 -0
  104. package/src/utils.ts +350 -0
  105. package/build/cjs/react-router/src/index.js +0 -473
  106. package/build/cjs/react-router/src/index.js.map +0 -1
  107. package/build/cjs/router-core/build/esm/index.js +0 -2527
  108. package/build/cjs/router-core/build/esm/index.js.map +0 -1
@@ -0,0 +1,226 @@
1
+ import * as React from 'react'
2
+ import warning from 'tiny-warning'
3
+ import { Matches } from './Matches'
4
+ import {
5
+ LinkInfo,
6
+ LinkOptions,
7
+ NavigateOptions,
8
+ ResolveRelativePath,
9
+ ToOptions,
10
+ } from './link'
11
+ import { ParsedLocation } from './location'
12
+ import { AnyRoute } from './route'
13
+ import { RouteById, RoutePaths } from './routeInfo'
14
+ import {
15
+ BuildNextOptions,
16
+ RegisteredRouter,
17
+ Router,
18
+ RouterOptions,
19
+ RouterState,
20
+ } from './router'
21
+ import { NoInfer, PickAsRequired } from './utils'
22
+ import { MatchRouteOptions } from './Matches'
23
+ import { RouteMatch } from './Matches'
24
+
25
+ export interface CommitLocationOptions {
26
+ replace?: boolean
27
+ resetScroll?: boolean
28
+ startTransition?: boolean
29
+ }
30
+
31
+ export interface MatchLocation {
32
+ to?: string | number | null
33
+ fuzzy?: boolean
34
+ caseSensitive?: boolean
35
+ from?: string
36
+ }
37
+
38
+ export type BuildLinkFn<TRouteTree extends AnyRoute> = <
39
+ TFrom extends RoutePaths<TRouteTree> = '/',
40
+ TTo extends string = '',
41
+ >(
42
+ dest: LinkOptions<TRouteTree, TFrom, TTo>,
43
+ ) => LinkInfo
44
+
45
+ export type NavigateFn<TRouteTree extends AnyRoute> = <
46
+ TFrom extends RoutePaths<TRouteTree> = '/',
47
+ TTo extends string = '',
48
+ TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
49
+ TMaskTo extends string = '',
50
+ >(
51
+ opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,
52
+ ) => Promise<void>
53
+
54
+ export type MatchRouteFn<TRouteTree extends AnyRoute> = <
55
+ TFrom extends RoutePaths<TRouteTree> = '/',
56
+ TTo extends string = '',
57
+ TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
58
+ >(
59
+ location: ToOptions<TRouteTree, TFrom, TTo>,
60
+ opts?: MatchRouteOptions,
61
+ ) => false | RouteById<TRouteTree, TResolved>['types']['allParams']
62
+
63
+ export type BuildLocationFn<TRouteTree extends AnyRoute> = (
64
+ opts: BuildNextOptions,
65
+ ) => ParsedLocation
66
+
67
+ export type InjectedHtmlEntry = string | (() => Promise<string> | string)
68
+
69
+ export const routerContext = React.createContext<Router<any>>(null!)
70
+
71
+ if (typeof document !== 'undefined') {
72
+ window.__TSR_ROUTER_CONTEXT__ = routerContext as any
73
+ }
74
+
75
+ export class SearchParamError extends Error {}
76
+
77
+ export class PathParamError extends Error {}
78
+
79
+ export function getInitialRouterState(
80
+ location: ParsedLocation,
81
+ ): RouterState<any> {
82
+ return {
83
+ status: 'idle',
84
+ resolvedLocation: location,
85
+ location,
86
+ matches: [],
87
+ pendingMatches: [],
88
+ lastUpdated: Date.now(),
89
+ }
90
+ }
91
+
92
+ export function RouterProvider<
93
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
94
+ TDehydrated extends Record<string, any> = Record<string, any>,
95
+ >({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>) {
96
+ // Allow the router to update options on the router instance
97
+ router.updateOptions({
98
+ ...router.options,
99
+ ...rest,
100
+
101
+ context: {
102
+ ...router.options.context,
103
+ ...rest?.context,
104
+ },
105
+ } as PickAsRequired<
106
+ RouterOptions<TRouteTree, TDehydrated>,
107
+ 'stringifySearch' | 'parseSearch' | 'context'
108
+ >)
109
+
110
+ const [preState, setState] = React.useState(() => router.state)
111
+ const [isTransitioning, startReactTransition] = React.useTransition()
112
+ const isAnyTransitioning =
113
+ isTransitioning || preState.matches.some((d) => d.status === 'pending')
114
+
115
+ const state = React.useMemo<RouterState<TRouteTree>>(
116
+ () => ({
117
+ ...preState,
118
+ status: isAnyTransitioning ? 'pending' : 'idle',
119
+ location: isTransitioning ? router.latestLocation : preState.location,
120
+ pendingMatches: router.pendingMatches,
121
+ }),
122
+ [preState, isTransitioning],
123
+ )
124
+
125
+ router.setState = setState
126
+ router.state = state
127
+ router.startReactTransition = startReactTransition
128
+
129
+ React.useLayoutEffect(() => {
130
+ const unsub = router.history.subscribe(() => {
131
+ router.latestLocation = router.parseLocation(router.latestLocation)
132
+
133
+ if (state.location !== router.latestLocation) {
134
+ startReactTransition(() => {
135
+ try {
136
+ router.load()
137
+ } catch (err) {
138
+ console.error(err)
139
+ }
140
+ })
141
+ }
142
+ })
143
+
144
+ const nextLocation = router.buildLocation({
145
+ search: true,
146
+ params: true,
147
+ hash: true,
148
+ state: true,
149
+ })
150
+
151
+ if (state.location.href !== nextLocation.href) {
152
+ router.commitLocation({ ...nextLocation, replace: true })
153
+ }
154
+
155
+ return () => {
156
+ unsub()
157
+ }
158
+ }, [router.history])
159
+
160
+ React.useLayoutEffect(() => {
161
+ if (!isTransitioning && state.resolvedLocation !== state.location) {
162
+ router.emit({
163
+ type: 'onResolved',
164
+ fromLocation: state.resolvedLocation,
165
+ toLocation: state.location,
166
+ pathChanged: state.location!.href !== state.resolvedLocation?.href,
167
+ })
168
+ router.pendingMatches = []
169
+
170
+ setState((s) => ({
171
+ ...s,
172
+ resolvedLocation: s.location,
173
+ }))
174
+ }
175
+ })
176
+
177
+ React.useLayoutEffect(() => {
178
+ startReactTransition(() => {
179
+ try {
180
+ router.load()
181
+ } catch (err) {
182
+ console.error(err)
183
+ }
184
+ })
185
+ }, [])
186
+
187
+ return (
188
+ <routerContext.Provider value={router}>
189
+ <Matches />
190
+ </routerContext.Provider>
191
+ )
192
+ }
193
+
194
+ export function getRouteMatch<TRouteTree extends AnyRoute>(
195
+ state: RouterState<TRouteTree>,
196
+ id: string,
197
+ ): undefined | RouteMatch<TRouteTree> {
198
+ return [...state.pendingMatches, ...state.matches].find((d) => d.id === id)
199
+ }
200
+
201
+ export function useRouterState<
202
+ TSelected = RouterState<RegisteredRouter['routeTree']>,
203
+ >(opts?: {
204
+ select: (state: RouterState<RegisteredRouter['routeTree']>) => TSelected
205
+ }): TSelected {
206
+ const { state } = useRouter()
207
+ // return useStore(router.__store, opts?.select as any)
208
+ return opts?.select ? opts.select(state) : (state as any)
209
+ }
210
+
211
+ export type RouterProps<
212
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
213
+ TDehydrated extends Record<string, any> = Record<string, any>,
214
+ > = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {
215
+ router: Router<TRouteTree>
216
+ context?: Partial<RouterOptions<TRouteTree, TDehydrated>['context']>
217
+ }
218
+
219
+ export function useRouter<
220
+ TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
221
+ >(): Router<TRouteTree> {
222
+ const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext
223
+ const value = React.useContext(resolvedContext)
224
+ warning(value, 'useRouter must be used inside a <RouterProvider> component!')
225
+ return value as any
226
+ }
@@ -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,154 @@
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
+ TLoaderData extends any = unknown,
109
+ TChildren extends RouteConstraints['TChildren'] = unknown,
110
+ TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
111
+ >(
112
+ options?: Omit<
113
+ RouteOptions<
114
+ TParentRoute,
115
+ string,
116
+ TPath,
117
+ TSearchSchema,
118
+ TFullSearchSchema,
119
+ TParams,
120
+ TAllParams,
121
+ TRouteContext,
122
+ TContext,
123
+ TLoaderData
124
+ >,
125
+ 'getParentRoute' | 'path' | 'id'
126
+ > &
127
+ UpdatableRouteOptions<
128
+ TFullSearchSchema,
129
+ TAllParams,
130
+ TContext,
131
+ TLoaderData
132
+ >,
133
+ ): Route<
134
+ TParentRoute,
135
+ TPath,
136
+ TFullPath,
137
+ TFilePath,
138
+ TId,
139
+ TSearchSchema,
140
+ TFullSearchSchema,
141
+ TParams,
142
+ TAllParams,
143
+ TRouteContext,
144
+ TContext,
145
+ TRouterContext,
146
+ TLoaderData,
147
+ TChildren,
148
+ TRouteTree
149
+ > => {
150
+ const route = new Route(options as any)
151
+ ;(route as any).isRoot = false
152
+ return route as any
153
+ }
154
+ }
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
+ }