@tanstack/router-core 0.0.1-beta.16 → 0.0.1-beta.19
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/build/cjs/packages/router-core/src/routeConfig.js.map +1 -1
- package/build/cjs/packages/router-core/src/routeMatch.js +24 -35
- package/build/cjs/packages/router-core/src/routeMatch.js.map +1 -1
- package/build/cjs/packages/router-core/src/router.js +38 -1
- package/build/cjs/packages/router-core/src/router.js.map +1 -1
- package/build/esm/index.js +62 -36
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +130 -130
- package/build/types/index.d.ts +87 -81
- package/build/umd/index.development.js +62 -36
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/routeConfig.ts +1 -4
- package/src/routeInfo.ts +2 -2
- package/src/routeMatch.ts +24 -31
- package/src/router.ts +57 -7
package/package.json
CHANGED
package/src/routeConfig.ts
CHANGED
|
@@ -70,7 +70,7 @@ export interface LoaderContext<
|
|
|
70
70
|
params: TAllParams
|
|
71
71
|
search: TFullSearchSchema
|
|
72
72
|
signal?: AbortSignal
|
|
73
|
-
parentLoaderPromise?: Promise<TParentRouteLoaderData>
|
|
73
|
+
// parentLoaderPromise?: Promise<TParentRouteLoaderData>
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export type ActionFn<TActionPayload = unknown, TActionResponse = unknown> = (
|
|
@@ -138,9 +138,6 @@ export type RouteOptions<
|
|
|
138
138
|
// An asynchronous function made available to the route for performing asynchronous or mutative actions that
|
|
139
139
|
// might invalidate the route's data.
|
|
140
140
|
action?: ActionFn<TActionPayload, TActionResponse>
|
|
141
|
-
// Set this to true to rethrow errors up the component tree to either the nearest error boundary or
|
|
142
|
-
// route with error component, whichever comes first.
|
|
143
|
-
useErrorBoundary?: boolean
|
|
144
141
|
// This function is called
|
|
145
142
|
// when moving from an inactive state to an active one. Likewise, when moving from
|
|
146
143
|
// an active to an inactive state, the return function (if provided) is called.
|
package/src/routeInfo.ts
CHANGED
|
@@ -116,10 +116,10 @@ export interface RoutesInfoInner<
|
|
|
116
116
|
any,
|
|
117
117
|
any
|
|
118
118
|
> = RouteInfo,
|
|
119
|
-
TRouteInfoById = {
|
|
119
|
+
TRouteInfoById = { '/': TRouteInfo } & {
|
|
120
120
|
[TInfo in TRouteInfo as TInfo['id']]: TInfo
|
|
121
121
|
},
|
|
122
|
-
TRouteInfoByFullPath = {
|
|
122
|
+
TRouteInfoByFullPath = { '/': TRouteInfo } & {
|
|
123
123
|
[TInfo in TRouteInfo as TInfo['fullPath'] extends RootRouteId
|
|
124
124
|
? never
|
|
125
125
|
: string extends TInfo['fullPath']
|
package/src/routeMatch.ts
CHANGED
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
DefaultAllRouteInfo,
|
|
7
7
|
RouteInfo,
|
|
8
8
|
} from './routeInfo'
|
|
9
|
-
import {
|
|
10
|
-
import { replaceEqualDeep,
|
|
9
|
+
import { Router } from './router'
|
|
10
|
+
import { replaceEqualDeep, warning } from './utils'
|
|
11
11
|
|
|
12
12
|
export interface RouteMatch<
|
|
13
13
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
@@ -201,8 +201,14 @@ export function createRouteMatch<
|
|
|
201
201
|
}
|
|
202
202
|
},
|
|
203
203
|
fetch: async (opts) => {
|
|
204
|
-
const
|
|
205
|
-
routeMatch.__.latestId =
|
|
204
|
+
const loadId = '' + Date.now() + Math.random()
|
|
205
|
+
routeMatch.__.latestId = loadId
|
|
206
|
+
const checkLatest = async () => {
|
|
207
|
+
if (loadId !== routeMatch.__.latestId) {
|
|
208
|
+
// warning(true, 'Data loader is out of date!')
|
|
209
|
+
return new Promise(() => {})
|
|
210
|
+
}
|
|
211
|
+
}
|
|
206
212
|
|
|
207
213
|
// If the match was in an error state, set it
|
|
208
214
|
// to a loading state again. Otherwise, keep it
|
|
@@ -240,15 +246,8 @@ export function createRouteMatch<
|
|
|
240
246
|
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
241
247
|
try {
|
|
242
248
|
if (routeMatch.options.loader) {
|
|
243
|
-
const data = await
|
|
244
|
-
|
|
245
|
-
params: routeMatch.params,
|
|
246
|
-
search: routeMatch.routeSearch,
|
|
247
|
-
signal: routeMatch.__.abortController.signal,
|
|
248
|
-
})
|
|
249
|
-
if (id !== routeMatch.__.latestId) {
|
|
250
|
-
return routeMatch.__.loadPromise
|
|
251
|
-
}
|
|
249
|
+
const data = await router.loadMatchData(routeMatch)
|
|
250
|
+
await checkLatest()
|
|
252
251
|
|
|
253
252
|
routeMatch.routeLoaderData = replaceEqualDeep(
|
|
254
253
|
routeMatch.routeLoaderData,
|
|
@@ -268,9 +267,7 @@ export function createRouteMatch<
|
|
|
268
267
|
|
|
269
268
|
return routeMatch.routeLoaderData
|
|
270
269
|
} catch (err) {
|
|
271
|
-
|
|
272
|
-
return routeMatch.__.loadPromise
|
|
273
|
-
}
|
|
270
|
+
await checkLatest()
|
|
274
271
|
|
|
275
272
|
if (process.env.NODE_ENV !== 'production') {
|
|
276
273
|
console.error(err)
|
|
@@ -284,30 +281,26 @@ export function createRouteMatch<
|
|
|
284
281
|
}
|
|
285
282
|
})
|
|
286
283
|
|
|
284
|
+
const after = async () => {
|
|
285
|
+
await checkLatest()
|
|
286
|
+
routeMatch.isFetching = false
|
|
287
|
+
delete routeMatch.__.loadPromise
|
|
288
|
+
routeMatch.__.notify()
|
|
289
|
+
}
|
|
290
|
+
|
|
287
291
|
try {
|
|
288
292
|
await Promise.all([
|
|
289
293
|
routeMatch.__.componentsPromise,
|
|
290
294
|
routeMatch.__.dataPromise.catch(() => {}),
|
|
291
295
|
])
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
} finally {
|
|
296
|
-
if (id !== routeMatch.__.latestId) {
|
|
297
|
-
return routeMatch.__.loadPromise
|
|
298
|
-
}
|
|
299
|
-
routeMatch.isFetching = false
|
|
300
|
-
routeMatch.__.notify()
|
|
296
|
+
after()
|
|
297
|
+
} catch {
|
|
298
|
+
after()
|
|
301
299
|
}
|
|
302
300
|
})
|
|
303
301
|
|
|
304
302
|
await routeMatch.__.loadPromise
|
|
305
|
-
|
|
306
|
-
if (id !== routeMatch.__.latestId) {
|
|
307
|
-
return routeMatch.__.loadPromise
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
delete routeMatch.__.loadPromise
|
|
303
|
+
await checkLatest()
|
|
311
304
|
},
|
|
312
305
|
}
|
|
313
306
|
|
package/src/router.ts
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
History,
|
|
7
7
|
MemoryHistory,
|
|
8
8
|
} from 'history'
|
|
9
|
-
import React from 'react'
|
|
10
9
|
import invariant from 'tiny-invariant'
|
|
11
10
|
import { GetFrameworkGeneric } from './frameworks'
|
|
12
11
|
|
|
@@ -91,7 +90,6 @@ export interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
|
|
|
91
90
|
defaultPreloadMaxAge?: number
|
|
92
91
|
defaultPreloadGcMaxAge?: number
|
|
93
92
|
defaultPreloadDelay?: number
|
|
94
|
-
useErrorBoundary?: boolean
|
|
95
93
|
defaultComponent?: GetFrameworkGeneric<'Component'>
|
|
96
94
|
defaultErrorComponent?: GetFrameworkGeneric<'Component'>
|
|
97
95
|
defaultPendingComponent?: GetFrameworkGeneric<'Component'>
|
|
@@ -100,6 +98,7 @@ export interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
|
|
|
100
98
|
caseSensitive?: boolean
|
|
101
99
|
routeConfig?: TRouteConfig
|
|
102
100
|
basepath?: string
|
|
101
|
+
useServerData?: boolean
|
|
103
102
|
createRouter?: (router: Router<any, any>) => void
|
|
104
103
|
createRoute?: (opts: { route: AnyRoute; router: Router<any, any> }) => void
|
|
105
104
|
loadComponent?: (
|
|
@@ -166,11 +165,11 @@ export interface Loader<
|
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
export interface LoaderState<
|
|
169
|
-
TFullSearchSchema =
|
|
170
|
-
TAllParams =
|
|
168
|
+
TFullSearchSchema extends AnySearchSchema = {},
|
|
169
|
+
TAllParams extends AnyPathParams = {},
|
|
171
170
|
> {
|
|
172
171
|
loadedAt: number
|
|
173
|
-
loaderContext: LoaderContext<TFullSearchSchema, TAllParams>
|
|
172
|
+
loaderContext: LoaderContext<AnyLoaderData, TFullSearchSchema, TAllParams>
|
|
174
173
|
}
|
|
175
174
|
|
|
176
175
|
export interface RouterState {
|
|
@@ -249,6 +248,13 @@ export interface Router<
|
|
|
249
248
|
TRouteConfig extends AnyRouteConfig = RouteConfig,
|
|
250
249
|
TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
|
|
251
250
|
> {
|
|
251
|
+
types: {
|
|
252
|
+
// Super secret internal stuff
|
|
253
|
+
RouteConfig: TRouteConfig
|
|
254
|
+
AllRouteInfo: TAllRouteInfo
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Public API
|
|
252
258
|
history: BrowserHistory | MemoryHistory | HashHistory
|
|
253
259
|
options: PickAsRequired<
|
|
254
260
|
RouterOptions<TRouteConfig>,
|
|
@@ -257,7 +263,6 @@ export interface Router<
|
|
|
257
263
|
// Computed in this.update()
|
|
258
264
|
basepath: string
|
|
259
265
|
// Internal:
|
|
260
|
-
allRouteInfo: TAllRouteInfo
|
|
261
266
|
listeners: Listener[]
|
|
262
267
|
location: Location
|
|
263
268
|
navigateTimeout?: Timeout
|
|
@@ -300,6 +305,9 @@ export interface Router<
|
|
|
300
305
|
| { preload: true; maxAge: number; gcMaxAge: number }
|
|
301
306
|
| { preload?: false; maxAge?: never; gcMaxAge?: never },
|
|
302
307
|
) => Promise<void>
|
|
308
|
+
loadMatchData: (
|
|
309
|
+
routeMatch: RouteMatch<any, any>,
|
|
310
|
+
) => Promise<Record<string, unknown>>
|
|
303
311
|
invalidateRoute: (opts: MatchLocation) => void
|
|
304
312
|
reload: () => Promise<void>
|
|
305
313
|
resolvePath: (from: string, path: string) => string
|
|
@@ -380,6 +388,9 @@ export function createRouter<
|
|
|
380
388
|
}
|
|
381
389
|
|
|
382
390
|
let router: Router<TRouteConfig, TAllRouteInfo> = {
|
|
391
|
+
types: undefined!,
|
|
392
|
+
|
|
393
|
+
// public api
|
|
383
394
|
history,
|
|
384
395
|
options: originalOptions,
|
|
385
396
|
listeners: [],
|
|
@@ -388,7 +399,6 @@ export function createRouter<
|
|
|
388
399
|
routeTree: undefined!,
|
|
389
400
|
routesById: {} as any,
|
|
390
401
|
location: undefined!,
|
|
391
|
-
allRouteInfo: undefined!,
|
|
392
402
|
//
|
|
393
403
|
navigationPromise: Promise.resolve(),
|
|
394
404
|
resolveNavigation: () => {},
|
|
@@ -841,6 +851,12 @@ export function createRouter<
|
|
|
841
851
|
match.__.validate()
|
|
842
852
|
match.load(loaderOpts)
|
|
843
853
|
|
|
854
|
+
const search = match.search as { __data?: any }
|
|
855
|
+
|
|
856
|
+
if (search.__data && search.__data.matchId !== match.matchId) {
|
|
857
|
+
return
|
|
858
|
+
}
|
|
859
|
+
|
|
844
860
|
if (match.__.loadPromise) {
|
|
845
861
|
// Wait for the first sign of activity from the match
|
|
846
862
|
await match.__.loadPromise
|
|
@@ -852,6 +868,40 @@ export function createRouter<
|
|
|
852
868
|
await Promise.all(matchPromises)
|
|
853
869
|
},
|
|
854
870
|
|
|
871
|
+
loadMatchData: async (routeMatch) => {
|
|
872
|
+
if (isServer || !router.options.useServerData) {
|
|
873
|
+
return (
|
|
874
|
+
(await routeMatch.options.loader?.({
|
|
875
|
+
// parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
|
|
876
|
+
params: routeMatch.params,
|
|
877
|
+
search: routeMatch.routeSearch,
|
|
878
|
+
signal: routeMatch.__.abortController.signal,
|
|
879
|
+
})) ?? {}
|
|
880
|
+
)
|
|
881
|
+
} else {
|
|
882
|
+
const next = router.buildNext({
|
|
883
|
+
to: '.',
|
|
884
|
+
search: (d: any) => ({
|
|
885
|
+
...(d ?? {}),
|
|
886
|
+
__data: {
|
|
887
|
+
matchId: routeMatch.matchId,
|
|
888
|
+
},
|
|
889
|
+
}),
|
|
890
|
+
})
|
|
891
|
+
|
|
892
|
+
const res = await fetch(next.href, {
|
|
893
|
+
method: 'GET',
|
|
894
|
+
// signal: routeMatch.__.abortController.signal,
|
|
895
|
+
})
|
|
896
|
+
|
|
897
|
+
if (res.ok) {
|
|
898
|
+
return res.json()
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
throw new Error('Failed to fetch match data')
|
|
902
|
+
}
|
|
903
|
+
},
|
|
904
|
+
|
|
855
905
|
invalidateRoute: (opts: MatchLocation) => {
|
|
856
906
|
const next = router.buildNext(opts)
|
|
857
907
|
const unloadedMatchIds = router
|