@tanstack/router-core 0.0.1-beta.184 → 0.0.1-beta.186

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.184",
4
+ "version": "0.0.1-beta.186",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
package/src/fileRoute.ts CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  AnyRoute,
4
4
  ResolveFullPath,
5
5
  ResolveFullSearchSchema,
6
- MergeParamsFromParent,
6
+ MergeFromFromParent,
7
7
  RouteContext,
8
8
  AnyContext,
9
9
  RouteOptions,
@@ -94,14 +94,14 @@ export class FileRoute<
94
94
  TParams extends RouteConstraints['TParams'] = ParsePathParams<TPath> extends never
95
95
  ? AnyPathParams
96
96
  : Record<ParsePathParams<TPath>, RouteConstraints['TPath']>,
97
- TAllParams extends RouteConstraints['TAllParams'] = MergeParamsFromParent<
97
+ TAllParams extends RouteConstraints['TAllParams'] = MergeFromFromParent<
98
98
  TParentRoute['types']['allParams'],
99
99
  TParams
100
100
  >,
101
101
  TParentContext extends RouteConstraints['TParentContext'] = TParentRoute['types']['routeContext'],
102
102
  TAllParentContext extends RouteConstraints['TId'] = TParentRoute['types']['context'],
103
103
  TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
104
- TContext extends RouteConstraints['TAllContext'] = MergeParamsFromParent<
104
+ TContext extends RouteConstraints['TAllContext'] = MergeFromFromParent<
105
105
  TParentRoute['types']['context'],
106
106
  TRouteContext
107
107
  >,
package/src/history.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // making assumptions about the way TanStack Router works
4
4
 
5
5
  export interface RouterHistory {
6
- location: RouterLocation
6
+ location: HistoryLocation
7
7
  subscribe: (cb: () => void) => () => void
8
8
  push: (path: string, state?: any) => void
9
9
  replace: (path: string, state?: any) => void
@@ -14,6 +14,10 @@ export interface RouterHistory {
14
14
  block: (blockerFn: BlockerFn) => () => void
15
15
  }
16
16
 
17
+ export interface HistoryLocation extends ParsedPath {
18
+ state: LocationState
19
+ }
20
+
17
21
  export interface ParsedPath {
18
22
  href: string
19
23
  pathname: string
@@ -21,8 +25,10 @@ export interface ParsedPath {
21
25
  hash: string
22
26
  }
23
27
 
24
- export interface RouterLocation extends ParsedPath {
25
- state: any
28
+ export interface LocationState {
29
+ key: string
30
+ __tempLocation?: HistoryLocation
31
+ __tempKey?: string
26
32
  }
27
33
 
28
34
  type BlockerFn = (retry: () => void, cancel: () => void) => void
@@ -44,7 +50,7 @@ const stopBlocking = () => {
44
50
  }
45
51
 
46
52
  function createHistory(opts: {
47
- getLocation: () => RouterLocation
53
+ getLocation: () => HistoryLocation
48
54
  subscriber: false | ((onUpdate: () => void) => () => void)
49
55
  pushState: (path: string, state: any) => void
50
56
  replaceState: (path: string, state: any) => void
@@ -108,11 +114,13 @@ function createHistory(opts: {
108
114
  }
109
115
  },
110
116
  push: (path: string, state: any) => {
117
+ assignKey(state)
111
118
  queueTask(() => {
112
119
  opts.pushState(path, state)
113
120
  })
114
121
  },
115
122
  replace: (path: string, state: any) => {
123
+ assignKey(state)
116
124
  queueTask(() => {
117
125
  opts.replaceState(path, state)
118
126
  })
@@ -153,6 +161,16 @@ function createHistory(opts: {
153
161
  }
154
162
  }
155
163
 
164
+ function assignKey(state: LocationState) {
165
+ state.key = createRandomKey()
166
+ // if (state.__actualLocation) {
167
+ // state.__actualLocation.state = {
168
+ // ...state.__actualLocation.state,
169
+ // key,
170
+ // }
171
+ // }
172
+ }
173
+
156
174
  export function createBrowserHistory(opts?: {
157
175
  getHref?: () => string
158
176
  createHref?: (path: string) => string
@@ -161,8 +179,10 @@ export function createBrowserHistory(opts?: {
161
179
  opts?.getHref ??
162
180
  (() =>
163
181
  `${window.location.pathname}${window.location.search}${window.location.hash}`)
182
+
164
183
  const createHref = opts?.createHref ?? ((path) => path)
165
- const getLocation = () => parseLocation(getHref(), history.state)
184
+
185
+ const getLocation = () => parseLocation(getHref(), window.history.state)
166
186
 
167
187
  return createHistory({
168
188
  getLocation,
@@ -191,18 +211,10 @@ export function createBrowserHistory(opts?: {
191
211
  }
192
212
  },
193
213
  pushState: (path, state) => {
194
- window.history.pushState(
195
- { ...state, key: createRandomKey() },
196
- '',
197
- createHref(path),
198
- )
214
+ window.history.pushState(state, '', createHref(path))
199
215
  },
200
216
  replaceState: (path, state) => {
201
- window.history.replaceState(
202
- { ...state, key: createRandomKey() },
203
- '',
204
- createHref(path),
205
- )
217
+ window.history.replaceState(state, '', createHref(path))
206
218
  },
207
219
  back: () => window.history.back(),
208
220
  forward: () => window.history.forward(),
@@ -228,7 +240,9 @@ export function createMemoryHistory(
228
240
  ): RouterHistory {
229
241
  const entries = opts.initialEntries
230
242
  let index = opts.initialIndex ?? entries.length - 1
231
- let currentState = {}
243
+ let currentState = {
244
+ key: createRandomKey(),
245
+ } as LocationState
232
246
 
233
247
  const getLocation = () => parseLocation(entries[index]!, currentState)
234
248
 
@@ -236,18 +250,12 @@ export function createMemoryHistory(
236
250
  getLocation,
237
251
  subscriber: false,
238
252
  pushState: (path, state) => {
239
- currentState = {
240
- ...state,
241
- key: createRandomKey(),
242
- }
253
+ currentState = state
243
254
  entries.push(path)
244
255
  index++
245
256
  },
246
257
  replaceState: (path, state) => {
247
- currentState = {
248
- ...state,
249
- key: createRandomKey(),
250
- }
258
+ currentState = state
251
259
  entries[index] = path
252
260
  },
253
261
  back: () => {
@@ -261,7 +269,7 @@ export function createMemoryHistory(
261
269
  })
262
270
  }
263
271
 
264
- function parseLocation(href: string, state: any): RouterLocation {
272
+ function parseLocation(href: string, state: LocationState): HistoryLocation {
265
273
  let hashIndex = href.indexOf('#')
266
274
  let searchIndex = href.indexOf('?')
267
275
 
@@ -282,7 +290,7 @@ function parseLocation(href: string, state: any): RouterLocation {
282
290
  searchIndex > -1
283
291
  ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)
284
292
  : '',
285
- state,
293
+ state: state || {},
286
294
  }
287
295
  }
288
296
 
package/src/link.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Trim } from './fileRoute'
2
+ import { LocationState } from './history'
2
3
  import { AnyRoute } from './route'
3
4
  import {
4
5
  AllParams,
@@ -7,8 +8,16 @@ import {
7
8
  RouteIds,
8
9
  RoutePaths,
9
10
  } from './routeInfo'
10
- import { ParsedLocation, LocationState } from './router'
11
- import { NoInfer, PickRequired, UnionToIntersection, Updater } from './utils'
11
+ import { ParsedLocation } from './router'
12
+ import {
13
+ Expand,
14
+ NoInfer,
15
+ NonNullableUpdater,
16
+ PickAsRequired,
17
+ PickRequired,
18
+ UnionToIntersection,
19
+ Updater,
20
+ } from './utils'
12
21
 
13
22
  export type LinkInfo =
14
23
  | {
@@ -121,7 +130,9 @@ export type NavigateOptions<
121
130
  TRouteTree extends AnyRoute = AnyRoute,
122
131
  TFrom extends RoutePaths<TRouteTree> = '/',
123
132
  TTo extends string = '',
124
- > = ToOptions<TRouteTree, TFrom, TTo> & {
133
+ TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
134
+ TMaskTo extends string = '',
135
+ > = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
125
136
  // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.
126
137
  replace?: boolean
127
138
  resetScroll?: boolean
@@ -131,81 +142,83 @@ export type ToOptions<
131
142
  TRouteTree extends AnyRoute = AnyRoute,
132
143
  TFrom extends RoutePaths<TRouteTree> = '/',
133
144
  TTo extends string = '',
134
- TResolvedTo = ResolveRelativePath<TFrom, NoInfer<TTo>>,
145
+ TMaskFrom extends RoutePaths<TRouteTree> = '/',
146
+ TMaskTo extends string = '',
147
+ > = ToSubOptions<TRouteTree, TFrom, TTo> & {
148
+ mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>
149
+ }
150
+
151
+ export type ToMaskOptions<
152
+ TRouteTree extends AnyRoute = AnyRoute,
153
+ TMaskFrom extends RoutePaths<TRouteTree> = '/',
154
+ TMaskTo extends string = '',
155
+ > = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {
156
+ unmaskOnReload?: boolean
157
+ }
158
+
159
+ export type ToSubOptions<
160
+ TRouteTree extends AnyRoute = AnyRoute,
161
+ TFrom extends RoutePaths<TRouteTree> = '/',
162
+ TTo extends string = '',
163
+ TResolved = ResolveRelativePath<TFrom, NoInfer<TTo>>,
135
164
  > = {
136
165
  to?: ToPathOption<TRouteTree, TFrom, TTo>
137
166
  // The new has string or a function to update it
138
- hash?: Updater<string>
167
+ hash?: true | Updater<string>
139
168
  // State to pass to the history stack
140
- state?: LocationState
169
+ state?: true | NonNullableUpdater<LocationState>
141
170
  // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required
142
171
  from?: TFrom
143
172
  // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path
144
173
  // fromCurrent?: boolean
145
- } & CheckPath<TRouteTree, NoInfer<TResolvedTo>, {}> &
146
- SearchParamOptions<TRouteTree, TFrom, TResolvedTo> &
147
- PathParamOptions<TRouteTree, TFrom, TResolvedTo>
174
+ } & CheckPath<TRouteTree, NoInfer<TResolved>, {}> &
175
+ SearchParamOptions<TRouteTree, TFrom, TResolved> &
176
+ PathParamOptions<TRouteTree, TFrom, TResolved>
148
177
 
149
178
  export type SearchParamOptions<
150
179
  TRouteTree extends AnyRoute,
151
180
  TFrom,
152
181
  TTo,
153
- TFromSchema = UnionToIntersection<
154
- FullSearchSchema<TRouteTree> & RouteByPath<TRouteTree, TFrom> extends never
155
- ? {}
156
- : RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']
157
- >,
158
- // Find the schema for the new path, and make optional any keys
159
- // that are already defined in the current schema
160
- TToSchema = Partial<
161
- RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']
162
- > &
163
- Omit<
164
- RouteByPath<TRouteTree, TTo>['types']['fullSearchSchema'],
165
- keyof PickRequired<
166
- RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']
167
- >
168
- >,
169
- TFromFullSchema = UnionToIntersection<
170
- FullSearchSchema<TRouteTree> & TFromSchema
182
+ TFromSearchEnsured = Expand<
183
+ UnionToIntersection<
184
+ PickRequired<RouteByPath<TRouteTree, TFrom>['types']['fullSearchSchema']>
185
+ >
171
186
  >,
172
- TToFullSchema = UnionToIntersection<FullSearchSchema<TRouteTree> & TToSchema>,
173
- > = keyof PickRequired<TToSchema> extends never
187
+ TFromSearchOptional = Omit<AllParams<TRouteTree>, keyof TFromSearchEnsured>,
188
+ TFromSearch = Expand<TFromSearchEnsured & TFromSearchOptional>,
189
+ TToSearch = Expand<RouteByPath<TRouteTree, TTo>['types']['fullSearchSchema']>,
190
+ > = keyof PickRequired<TToSearch> extends never
174
191
  ? {
175
- search?: true | SearchReducer<TFromFullSchema, TToFullSchema>
192
+ search?: true | SearchReducer<TFromSearch, TToSearch>
176
193
  }
177
194
  : {
178
- search: SearchReducer<TFromFullSchema, TToFullSchema>
195
+ search: TFromSearchEnsured extends PickRequired<TToSearch>
196
+ ? true | SearchReducer<TFromSearch, TToSearch>
197
+ : SearchReducer<TFromSearch, TToSearch>
179
198
  }
180
199
 
181
- type SearchReducer<TFrom, TTo> =
182
- | { [TKey in keyof TTo]: TTo[TKey] }
183
- | ((current: TFrom) => TTo)
200
+ type SearchReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
184
201
 
185
202
  export type PathParamOptions<
186
203
  TRouteTree extends AnyRoute,
187
204
  TFrom,
188
205
  TTo,
189
- TFromSchema = UnionToIntersection<
190
- RouteByPath<TRouteTree, TFrom> extends never
191
- ? {}
192
- : RouteByPath<TRouteTree, TFrom>['types']['allParams']
206
+ TFromParamsEnsured = Expand<
207
+ UnionToIntersection<
208
+ PickRequired<RouteByPath<TRouteTree, TFrom>['types']['allParams']>
209
+ >
193
210
  >,
194
- // Find the schema for the new path, and make optional any keys
195
- // that are already defined in the current schema
196
- TToSchema = Partial<RouteByPath<TRouteTree, TFrom>['types']['allParams']> &
197
- Omit<
198
- RouteByPath<TRouteTree, TTo>['types']['allParams'],
199
- keyof PickRequired<RouteByPath<TRouteTree, TFrom>['types']['allParams']>
200
- >,
201
- TFromFullParams = UnionToIntersection<AllParams<TRouteTree> & TFromSchema>,
202
- TToFullParams = UnionToIntersection<AllParams<TRouteTree> & TToSchema>,
203
- > = keyof PickRequired<TToSchema> extends never
211
+ TFromParamsOptional = Omit<AllParams<TRouteTree>, keyof TFromParamsEnsured>,
212
+ TFromParams = Expand<TFromParamsOptional & TFromParamsEnsured>,
213
+ TToParams = Expand<RouteByPath<TRouteTree, TTo>['types']['allParams']>,
214
+ > = keyof PickRequired<TToParams> extends never
204
215
  ? {
205
- params?: ParamsReducer<TFromFullParams, TToFullParams>
216
+ params?: true | ParamsReducer<TFromParams, TToParams>
206
217
  }
207
218
  : {
208
- params: ParamsReducer<TFromFullParams, TToFullParams>
219
+ params: TFromParamsEnsured extends PickRequired<TToParams>
220
+ ? true | ParamsReducer<TFromParams, TToParams>
221
+ : ParamsReducer<TFromParams, TToParams>
209
222
  }
210
223
 
211
224
  type ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)
@@ -244,7 +257,9 @@ export type LinkOptions<
244
257
  TRouteTree extends AnyRoute = AnyRoute,
245
258
  TFrom extends RoutePaths<TRouteTree> = '/',
246
259
  TTo extends string = '',
247
- > = NavigateOptions<TRouteTree, TFrom, TTo> & {
260
+ TMaskFrom extends RoutePaths<TRouteTree> = TFrom,
261
+ TMaskTo extends string = '',
262
+ > = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
248
263
  // The standard anchor tag target attribute
249
264
  target?: HTMLAnchorElement['target']
250
265
  // Defaults to `{ exact: false, includeHash: false }`
package/src/route.ts CHANGED
@@ -1,14 +1,25 @@
1
- import { ParsePathParams } from './link'
1
+ import invariant from 'tiny-invariant'
2
+ import { RouteById, RoutePaths } from './routeInfo'
3
+ import { joinPaths, trimPath } from './path'
2
4
  import {
3
5
  AnyRouter,
4
- Router,
5
6
  RouteMatch,
6
- RegisteredRouter,
7
7
  AnyRouteMatch,
8
+ RegisteredRouter,
8
9
  } from './router'
9
- import { IsAny, NoInfer, PickRequired, UnionToIntersection } from './utils'
10
- import invariant from 'tiny-invariant'
11
- import { joinPaths, trimPath } from './path'
10
+ import {
11
+ Expand,
12
+ IsAny,
13
+ NoInfer,
14
+ PickRequired,
15
+ UnionToIntersection,
16
+ } from './utils'
17
+ import {
18
+ ParsePathParams,
19
+ ResolveRelativePath,
20
+ ToMaskOptions,
21
+ ToSubOptions,
22
+ } from './link'
12
23
 
13
24
  export const rootRouteId = '__root__' as const
14
25
  export type RootRouteId = typeof rootRouteId
@@ -393,6 +404,9 @@ export type UpdatableRouteOptions<
393
404
  onEnter?: (match: AnyRouteMatch) => void
394
405
  onTransition?: (match: AnyRouteMatch) => void
395
406
  onLeave?: (match: AnyRouteMatch) => void
407
+ // Set this to true or false to specifically set whether or not this route should be preloaded. If unset, will
408
+ // default to router.options.reloadOnWindowFocus
409
+ reloadOnWindowFocus?: boolean
396
410
  }
397
411
 
398
412
  export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
@@ -525,7 +539,7 @@ export interface AnyRoute
525
539
  any
526
540
  > {}
527
541
 
528
- export type MergeParamsFromParent<T, U> = IsAny<T, U, T & U>
542
+ export type MergeFromFromParent<T, U> = IsAny<T, U, T & U>
529
543
 
530
544
  export type UseLoaderResult<T> = T
531
545
  // T extends Record<PropertyKey, infer U>
@@ -545,6 +559,15 @@ export type StreamedPromise<T> = {
545
559
  resolve: (value: T) => void
546
560
  }
547
561
 
562
+ export type ResolveAllParams<
563
+ TParentRoute extends AnyRoute,
564
+ TParams extends AnyPathParams,
565
+ > = Record<never, string> extends TParentRoute['types']['allParams']
566
+ ? TParams
567
+ : Expand<
568
+ UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}
569
+ >
570
+
548
571
  export type RouteConstraints = {
549
572
  TParentRoute: AnyRoute
550
573
  TPath: string
@@ -583,18 +606,17 @@ export class Route<
583
606
  TParentRoute,
584
607
  TSearchSchema
585
608
  >,
586
- TParams extends RouteConstraints['TParams'] = Record<
587
- ParsePathParams<TPath>,
588
- string
609
+ TParams extends RouteConstraints['TParams'] = Expand<
610
+ Record<ParsePathParams<TPath>, string>
589
611
  >,
590
- TAllParams extends RouteConstraints['TAllParams'] = MergeParamsFromParent<
591
- TParentRoute['types']['allParams'],
612
+ TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<
613
+ TParentRoute,
592
614
  TParams
593
615
  >,
594
616
  TParentContext extends RouteConstraints['TParentContext'] = TParentRoute['types']['routeContext'],
595
617
  TAllParentContext extends RouteConstraints['TAllParentContext'] = TParentRoute['types']['context'],
596
618
  TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
597
- TAllContext extends RouteConstraints['TAllContext'] = MergeParamsFromParent<
619
+ TAllContext extends RouteConstraints['TAllContext'] = MergeFromFromParent<
598
620
  TParentRoute['types']['context'],
599
621
  TRouteContext
600
622
  >,
@@ -816,7 +838,7 @@ export class RouterContext<TRouterContext extends {}> {
816
838
  TRouterContext,
817
839
  TRouterContext,
818
840
  TRouteContext,
819
- MergeParamsFromParent<TRouterContext, TRouteContext>
841
+ MergeFromFromParent<TRouterContext, TRouteContext>
820
842
  >,
821
843
  | 'path'
822
844
  | 'id'
@@ -849,7 +871,7 @@ export class RootRoute<
849
871
  TRouterContext,
850
872
  TRouterContext,
851
873
  TRouteContext,
852
- MergeParamsFromParent<TRouterContext, TRouteContext>,
874
+ MergeFromFromParent<TRouterContext, TRouteContext>,
853
875
  TRouterContext,
854
876
  any,
855
877
  any
@@ -869,7 +891,7 @@ export class RootRoute<
869
891
  TRouterContext,
870
892
  TRouterContext,
871
893
  TRouteContext,
872
- MergeParamsFromParent<TRouterContext, TRouteContext>
894
+ MergeFromFromParent<TRouterContext, TRouteContext>
873
895
  >,
874
896
  | 'path'
875
897
  | 'id'
@@ -919,3 +941,26 @@ export type TrimPathRight<T extends string> = T extends '/'
919
941
  : T extends `${infer U}/`
920
942
  ? TrimPathRight<U>
921
943
  : T
944
+
945
+ export type RouteMask<TRouteTree extends AnyRoute> = {
946
+ routeTree: TRouteTree
947
+ from: RoutePaths<TRouteTree>
948
+ to?: any
949
+ params?: any
950
+ search?: any
951
+ hash?: any
952
+ state?: any
953
+ unmaskOnReload?: boolean
954
+ }
955
+
956
+ export function createRouteMask<
957
+ TRouteTree extends AnyRoute,
958
+ TFrom extends RoutePaths<TRouteTree>,
959
+ TTo extends string,
960
+ >(
961
+ opts: {
962
+ routeTree: TRouteTree
963
+ } & ToSubOptions<TRouteTree, TFrom, TTo>,
964
+ ): RouteMask<TRouteTree> {
965
+ return opts as any
966
+ }
package/src/routeInfo.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AnyRoute, Route } from './route'
2
- import { MergeUnion } from './utils'
2
+ import { UnionToIntersection } from './utils'
3
3
 
4
4
  export type ParseRoute<TRouteTree extends AnyRoute> =
5
5
  | TRouteTree
@@ -60,10 +60,10 @@ export type RoutePaths<TRouteTree extends AnyRoute> =
60
60
  | ParseRoute<TRouteTree>['fullPath']
61
61
  | '/'
62
62
 
63
- export type FullSearchSchema<TRouteTree extends AnyRoute> = MergeUnion<
63
+ export type FullSearchSchema<TRouteTree extends AnyRoute> = UnionToIntersection<
64
64
  ParseRoute<TRouteTree>['types']['fullSearchSchema']
65
65
  > & {}
66
66
 
67
- export type AllParams<TRouteTree extends AnyRoute> = MergeUnion<
67
+ export type AllParams<TRouteTree extends AnyRoute> = UnionToIntersection<
68
68
  ParseRoute<TRouteTree>['types']['allParams']
69
69
  >