@tanstack/router-core 0.0.1-beta.21 → 0.0.1-beta.23

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
3
  "author": "Tanner Linsley",
4
- "version": "0.0.1-beta.21",
4
+ "version": "0.0.1-beta.23",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
package/src/path.ts CHANGED
@@ -155,10 +155,6 @@ export function matchPathname(
155
155
  return
156
156
  }
157
157
 
158
- // if (matchLocation.search && !searchMatched) {
159
- // return
160
- // }
161
-
162
158
  return pathParams ?? {}
163
159
  }
164
160
 
@@ -3,6 +3,7 @@ import { ParsePathParams } from './link'
3
3
  import { joinPaths, trimPath, trimPathRight } from './path'
4
4
  import { RouteInfo } from './routeInfo'
5
5
  import { RouteMatch } from './routeMatch'
6
+ import { RouterContext } from './router'
6
7
  import {
7
8
  DeepAwaited,
8
9
  Expand,
@@ -127,10 +128,13 @@ export type RouteOptions<
127
128
  // An asynchronous function made available to the route for performing asynchronous or mutative actions that
128
129
  // might invalidate the route's data.
129
130
  action?: ActionFn<TActionPayload, TActionResponse>
131
+ // This async function is called before a route is loaded. If an error is thrown, the navigation is cancelled.
132
+ // If you want to redirect instead, throw a call to the `router.navigate()` function
133
+ beforeLoad?: (opts: { context: RouterContext }) => Promise<void> | void
130
134
  // This function is called
131
135
  // when moving from an inactive state to an active one. Likewise, when moving from
132
136
  // an active to an inactive state, the return function (if provided) is called.
133
- onMatch?: (matchContext: {
137
+ onLoaded?: (matchContext: {
134
138
  params: TAllParams
135
139
  search: TFullSearchSchema
136
140
  }) =>
package/src/routeInfo.ts CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  RouteConfig,
11
11
  RouteOptions,
12
12
  } from './routeConfig'
13
- import { IsAny, Values } from './utils'
13
+ import { IsAny, UnionToIntersection, Values } from './utils'
14
14
 
15
15
  export interface AnyAllRouteInfo {
16
16
  routeConfig: AnyRouteConfig
@@ -19,6 +19,7 @@ export interface AnyAllRouteInfo {
19
19
  routeInfoByFullPath: Record<string, AnyRouteInfo>
20
20
  routeIds: any
21
21
  routePaths: any
22
+ fullSearchSchema: Record<string, any>
22
23
  }
23
24
 
24
25
  export interface DefaultAllRouteInfo {
@@ -28,6 +29,7 @@ export interface DefaultAllRouteInfo {
28
29
  routeInfoByFullPath: Record<string, RouteInfo>
29
30
  routeIds: string
30
31
  routePaths: string
32
+ fullSearchSchema: AnySearchSchema
31
33
  }
32
34
 
33
35
  export interface AllRouteInfo<TRouteConfig extends AnyRouteConfig = RouteConfig>
@@ -133,6 +135,7 @@ export interface RoutesInfoInner<
133
135
  routeInfoByFullPath: TRouteInfoByFullPath
134
136
  routeIds: keyof TRouteInfoById
135
137
  routePaths: keyof TRouteInfoByFullPath
138
+ fullSearchSchema: Partial<UnionToIntersection<TRouteInfo['fullSearchSchema']>>
136
139
  }
137
140
 
138
141
  export interface AnyRouteInfo
package/src/router.ts CHANGED
@@ -172,9 +172,12 @@ export interface LoaderState<
172
172
  loaderContext: LoaderContext<TFullSearchSchema, TAllParams>
173
173
  }
174
174
 
175
- export interface RouterState {
175
+ export interface RouterState<
176
+ TSearchObj extends AnySearchSchema = {},
177
+ TState extends LocationState = LocationState,
178
+ > {
176
179
  status: 'idle' | 'loading'
177
- location: Location
180
+ location: Location<TSearchObj, TState>
178
181
  matches: RouteMatch[]
179
182
  lastUpdated: number
180
183
  actions: Record<string, Action>
@@ -244,6 +247,8 @@ interface DehydratedRouteMatch
244
247
  | 'invalidAt'
245
248
  > {}
246
249
 
250
+ export interface RouterContext {}
251
+
247
252
  export interface Router<
248
253
  TRouteConfig extends AnyRouteConfig = RouteConfig,
249
254
  TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
@@ -263,11 +268,12 @@ export interface Router<
263
268
  // Computed in this.update()
264
269
  basepath: string
265
270
  // Internal:
271
+ context: RouterContext
266
272
  listeners: Listener[]
267
- location: Location
273
+ location: Location<TAllRouteInfo['fullSearchSchema']>
268
274
  navigateTimeout?: Timeout
269
275
  nextAction?: 'push' | 'replace'
270
- state: RouterState
276
+ state: RouterState<TAllRouteInfo['fullSearchSchema']>
271
277
  routeTree: Route<TAllRouteInfo, RouteInfo>
272
278
  routesById: RoutesById<TAllRouteInfo>
273
279
  navigationPromise: Promise<void>
@@ -395,6 +401,7 @@ export function createRouter<
395
401
  options: originalOptions,
396
402
  listeners: [],
397
403
  // Resolved after construction
404
+ context: {},
398
405
  basepath: '',
399
406
  routeTree: undefined!,
400
407
  routesById: {} as any,
@@ -577,6 +584,22 @@ export function createRouter<
577
584
  strictParseParams: true,
578
585
  })
579
586
 
587
+ // Check if each match middleware to see if the route can be accessed
588
+ try {
589
+ await Promise.all(
590
+ matches.map((match) =>
591
+ match.options.beforeLoad?.({
592
+ context: router.context,
593
+ }),
594
+ ),
595
+ )
596
+ } catch (err: any) {
597
+ if (err?.then) {
598
+ await new Promise(() => {})
599
+ }
600
+ throw err
601
+ }
602
+
580
603
  if (typeof document !== 'undefined') {
581
604
  router.state = {
582
605
  ...router.state,
@@ -655,7 +678,7 @@ export function createRouter<
655
678
  })
656
679
 
657
680
  entering.forEach((d) => {
658
- d.__.onExit = d.options.onMatch?.({
681
+ d.__.onExit = d.options.onLoaded?.({
659
682
  params: d.params,
660
683
  search: d.search,
661
684
  })
package/src/utils.ts CHANGED
@@ -24,11 +24,11 @@ export type Expand<T> = T extends object
24
24
  : never
25
25
  : T
26
26
 
27
- // type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
28
- // k: infer I,
29
- // ) => any
30
- // ? I
31
- // : never
27
+ export type UnionToIntersection<U> = (
28
+ U extends any ? (k: U) => void : never
29
+ ) extends (k: infer I) => any
30
+ ? I
31
+ : never
32
32
 
33
33
  export type Values<O> = O[ValueKeys<O>]
34
34
  export type ValueKeys<O> = Extract<keyof O, PropertyKey>