@tanstack/router-core 0.0.1-beta.3 → 0.0.1-beta.31
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/_virtual/_rollupPluginBabelHelpers.js +0 -2
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/build/cjs/{packages/router-core/src/index.js → index.js} +23 -7
- package/build/cjs/{packages/router-core/src/index.js.map → index.js.map} +1 -1
- package/build/cjs/{packages/router-core/src/path.js → path.js} +7 -34
- package/build/cjs/path.js.map +1 -0
- package/build/cjs/{packages/router-core/src/qss.js → qss.js} +9 -13
- package/build/cjs/qss.js.map +1 -0
- package/build/cjs/{packages/router-core/src/route.js → route.js} +15 -37
- package/build/cjs/route.js.map +1 -0
- package/build/cjs/{packages/router-core/src/routeConfig.js → routeConfig.js} +13 -12
- package/build/cjs/routeConfig.js.map +1 -0
- package/build/cjs/routeMatch.js +200 -0
- package/build/cjs/routeMatch.js.map +1 -0
- package/build/cjs/{packages/router-core/src/router.js → router.js} +257 -221
- package/build/cjs/router.js.map +1 -0
- package/build/cjs/{packages/router-core/src/searchParams.js → searchParams.js} +7 -10
- package/build/cjs/searchParams.js.map +1 -0
- package/build/cjs/{packages/router-core/src/utils.js → utils.js} +17 -30
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +395 -1322
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +59 -49
- package/build/stats-react.json +161 -168
- package/build/types/index.d.ts +247 -227
- package/build/umd/index.development.js +385 -495
- 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 +3 -2
- package/src/frameworks.ts +2 -2
- package/src/index.ts +0 -1
- package/src/link.ts +66 -31
- package/src/path.ts +2 -6
- package/src/qss.ts +1 -0
- package/src/route.ts +25 -33
- package/src/routeConfig.ts +100 -77
- package/src/routeInfo.ts +26 -8
- package/src/routeMatch.ts +100 -160
- package/src/router.ts +363 -141
- package/src/utils.ts +14 -7
- package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js +0 -33
- package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js.map +0 -1
- package/build/cjs/node_modules/history/index.js +0 -815
- package/build/cjs/node_modules/history/index.js.map +0 -1
- package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -30
- package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
- package/build/cjs/packages/router-core/src/path.js.map +0 -1
- package/build/cjs/packages/router-core/src/qss.js.map +0 -1
- package/build/cjs/packages/router-core/src/route.js.map +0 -1
- package/build/cjs/packages/router-core/src/routeConfig.js.map +0 -1
- package/build/cjs/packages/router-core/src/routeMatch.js +0 -266
- package/build/cjs/packages/router-core/src/routeMatch.js.map +0 -1
- package/build/cjs/packages/router-core/src/router.js.map +0 -1
- package/build/cjs/packages/router-core/src/searchParams.js.map +0 -1
- package/build/cjs/packages/router-core/src/utils.js.map +0 -1
package/src/routeMatch.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { GetFrameworkGeneric } from './frameworks'
|
|
2
2
|
import { Route } from './route'
|
|
3
|
-
import { AnyPathParams } from './routeConfig'
|
|
4
3
|
import {
|
|
5
4
|
AnyAllRouteInfo,
|
|
6
5
|
AnyRouteInfo,
|
|
@@ -8,7 +7,7 @@ import {
|
|
|
8
7
|
RouteInfo,
|
|
9
8
|
} from './routeInfo'
|
|
10
9
|
import { Router } from './router'
|
|
11
|
-
import {
|
|
10
|
+
import { Expand, replaceEqualDeep } from './utils'
|
|
12
11
|
|
|
13
12
|
export interface RouteMatch<
|
|
14
13
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
@@ -16,11 +15,13 @@ export interface RouteMatch<
|
|
|
16
15
|
> extends Route<TAllRouteInfo, TRouteInfo> {
|
|
17
16
|
matchId: string
|
|
18
17
|
pathname: string
|
|
19
|
-
params: TRouteInfo['
|
|
18
|
+
params: TRouteInfo['allParams']
|
|
20
19
|
parentMatch?: RouteMatch
|
|
21
20
|
childMatches: RouteMatch[]
|
|
22
21
|
routeSearch: TRouteInfo['searchSchema']
|
|
23
|
-
search:
|
|
22
|
+
search: Expand<
|
|
23
|
+
TAllRouteInfo['fullSearchSchema'] & TRouteInfo['fullSearchSchema']
|
|
24
|
+
>
|
|
24
25
|
status: 'idle' | 'loading' | 'success' | 'error'
|
|
25
26
|
updatedAt?: number
|
|
26
27
|
error?: unknown
|
|
@@ -29,20 +30,14 @@ export interface RouteMatch<
|
|
|
29
30
|
loaderData: TRouteInfo['loaderData']
|
|
30
31
|
routeLoaderData: TRouteInfo['routeLoaderData']
|
|
31
32
|
isFetching: boolean
|
|
32
|
-
isPending: boolean
|
|
33
33
|
invalidAt: number
|
|
34
34
|
__: {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pendingElement?: GetFrameworkGeneric<'Element'> // , TRouteInfo['loaderData']>
|
|
35
|
+
component?: GetFrameworkGeneric<'Component'>
|
|
36
|
+
errorComponent?: GetFrameworkGeneric<'ErrorComponent'>
|
|
37
|
+
pendingComponent?: GetFrameworkGeneric<'Component'>
|
|
39
38
|
loadPromise?: Promise<void>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
dataPromise?: Promise<void>
|
|
43
|
-
pendingTimeout?: Timeout
|
|
44
|
-
pendingMinTimeout?: Timeout
|
|
45
|
-
pendingMinPromise?: Promise<void>
|
|
39
|
+
componentsPromise?: Promise<void>
|
|
40
|
+
dataPromise?: Promise<TRouteInfo['routeLoaderData']>
|
|
46
41
|
onExit?:
|
|
47
42
|
| void
|
|
48
43
|
| ((matchContext: {
|
|
@@ -54,37 +49,34 @@ export interface RouteMatch<
|
|
|
54
49
|
// setParentMatch: (parentMatch: RouteMatch) => void
|
|
55
50
|
// addChildMatch: (childMatch: RouteMatch) => void
|
|
56
51
|
validate: () => void
|
|
57
|
-
startPending: () => void
|
|
58
|
-
cancelPending: () => void
|
|
59
52
|
notify: () => void
|
|
60
53
|
resolve: () => void
|
|
61
54
|
}
|
|
62
55
|
cancel: () => void
|
|
63
56
|
load: (
|
|
64
|
-
loaderOpts?:
|
|
57
|
+
loaderOpts?:
|
|
65
58
|
| { preload: true; maxAge: number; gcMaxAge: number }
|
|
66
|
-
| { preload?: false; maxAge?: never; gcMaxAge?: never }
|
|
67
|
-
),
|
|
59
|
+
| { preload?: false; maxAge?: never; gcMaxAge?: never },
|
|
68
60
|
) => Promise<TRouteInfo['routeLoaderData']>
|
|
69
61
|
fetch: (opts?: { maxAge?: number }) => Promise<TRouteInfo['routeLoaderData']>
|
|
70
62
|
invalidate: () => void
|
|
71
63
|
hasLoaders: () => boolean
|
|
72
64
|
}
|
|
73
65
|
|
|
74
|
-
const
|
|
75
|
-
'
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'pendingElement',
|
|
66
|
+
const componentTypes = [
|
|
67
|
+
'component',
|
|
68
|
+
'errorComponent',
|
|
69
|
+
'pendingComponent',
|
|
79
70
|
] as const
|
|
80
71
|
|
|
81
72
|
export function createRouteMatch<
|
|
82
73
|
TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
|
|
83
74
|
TRouteInfo extends AnyRouteInfo = RouteInfo,
|
|
84
75
|
>(
|
|
85
|
-
router: Router<any, any>,
|
|
76
|
+
router: Router<any, any, any>,
|
|
86
77
|
route: Route<TAllRouteInfo, TRouteInfo>,
|
|
87
78
|
opts: {
|
|
79
|
+
parentMatch?: RouteMatch<any, any>
|
|
88
80
|
matchId: string
|
|
89
81
|
params: TRouteInfo['allParams']
|
|
90
82
|
pathname: string
|
|
@@ -95,15 +87,15 @@ export function createRouteMatch<
|
|
|
95
87
|
...opts,
|
|
96
88
|
router,
|
|
97
89
|
routeSearch: {},
|
|
98
|
-
search: {},
|
|
90
|
+
search: {} as any,
|
|
99
91
|
childMatches: [],
|
|
100
92
|
status: 'idle',
|
|
101
93
|
routeLoaderData: {} as TRouteInfo['routeLoaderData'],
|
|
102
94
|
loaderData: {} as TRouteInfo['loaderData'],
|
|
103
|
-
isPending: false,
|
|
104
95
|
isFetching: false,
|
|
105
96
|
isInvalid: false,
|
|
106
97
|
invalidAt: Infinity,
|
|
98
|
+
// pendingActions: [],
|
|
107
99
|
getIsInvalid: () => {
|
|
108
100
|
const now = Date.now()
|
|
109
101
|
return routeMatch.isInvalid || routeMatch.invalidAt < now
|
|
@@ -116,53 +108,10 @@ export function createRouteMatch<
|
|
|
116
108
|
routeMatch.__.resolve()
|
|
117
109
|
routeMatch.router.notify()
|
|
118
110
|
},
|
|
119
|
-
startPending: () => {
|
|
120
|
-
const pendingMs =
|
|
121
|
-
routeMatch.options.pendingMs ?? router.options.defaultPendingMs
|
|
122
|
-
const pendingMinMs =
|
|
123
|
-
routeMatch.options.pendingMinMs ?? router.options.defaultPendingMinMs
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
routeMatch.__.pendingTimeout ||
|
|
127
|
-
routeMatch.status !== 'loading' ||
|
|
128
|
-
typeof pendingMs === 'undefined'
|
|
129
|
-
) {
|
|
130
|
-
return
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
routeMatch.__.pendingTimeout = setTimeout(() => {
|
|
134
|
-
routeMatch.isPending = true
|
|
135
|
-
routeMatch.__.resolve()
|
|
136
|
-
if (typeof pendingMinMs !== 'undefined') {
|
|
137
|
-
routeMatch.__.pendingMinPromise = new Promise(
|
|
138
|
-
(r) =>
|
|
139
|
-
(routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs)),
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
}, pendingMs)
|
|
143
|
-
},
|
|
144
|
-
cancelPending: () => {
|
|
145
|
-
routeMatch.isPending = false
|
|
146
|
-
clearTimeout(routeMatch.__.pendingTimeout)
|
|
147
|
-
clearTimeout(routeMatch.__.pendingMinTimeout)
|
|
148
|
-
delete routeMatch.__.pendingMinPromise
|
|
149
|
-
},
|
|
150
|
-
// setParentMatch: (parentMatch?: RouteMatch) => {
|
|
151
|
-
// routeMatch.parentMatch = parentMatch
|
|
152
|
-
// },
|
|
153
|
-
// addChildMatch: (childMatch: RouteMatch) => {
|
|
154
|
-
// if (
|
|
155
|
-
// routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
|
|
156
|
-
// ) {
|
|
157
|
-
// return
|
|
158
|
-
// }
|
|
159
|
-
|
|
160
|
-
// routeMatch.childMatches.push(childMatch)
|
|
161
|
-
// },
|
|
162
111
|
validate: () => {
|
|
163
112
|
// Validate the search params and stabilize them
|
|
164
113
|
const parentSearch =
|
|
165
|
-
routeMatch.parentMatch?.search ?? router.
|
|
114
|
+
routeMatch.parentMatch?.search ?? router.__location.search
|
|
166
115
|
|
|
167
116
|
try {
|
|
168
117
|
const prevSearch = routeMatch.routeSearch
|
|
@@ -174,7 +123,7 @@ export function createRouteMatch<
|
|
|
174
123
|
|
|
175
124
|
let nextSearch = replaceEqualDeep(
|
|
176
125
|
prevSearch,
|
|
177
|
-
validator?.(parentSearch),
|
|
126
|
+
validator?.(parentSearch) ?? {},
|
|
178
127
|
)
|
|
179
128
|
|
|
180
129
|
// Invalidate route matches when search param stability changes
|
|
@@ -188,6 +137,14 @@ export function createRouteMatch<
|
|
|
188
137
|
...parentSearch,
|
|
189
138
|
...nextSearch,
|
|
190
139
|
})
|
|
140
|
+
|
|
141
|
+
componentTypes.map(async (type) => {
|
|
142
|
+
const component = routeMatch.options[type]
|
|
143
|
+
|
|
144
|
+
if (typeof routeMatch.__[type] !== 'function') {
|
|
145
|
+
routeMatch.__[type] = component
|
|
146
|
+
}
|
|
147
|
+
})
|
|
191
148
|
} catch (err: any) {
|
|
192
149
|
console.error(err)
|
|
193
150
|
const error = new (Error as any)('Invalid search params found', {
|
|
@@ -203,7 +160,6 @@ export function createRouteMatch<
|
|
|
203
160
|
},
|
|
204
161
|
cancel: () => {
|
|
205
162
|
routeMatch.__.abortController?.abort()
|
|
206
|
-
routeMatch.__.cancelPending()
|
|
207
163
|
},
|
|
208
164
|
invalidate: () => {
|
|
209
165
|
routeMatch.isInvalid = true
|
|
@@ -211,7 +167,7 @@ export function createRouteMatch<
|
|
|
211
167
|
hasLoaders: () => {
|
|
212
168
|
return !!(
|
|
213
169
|
route.options.loader ||
|
|
214
|
-
|
|
170
|
+
componentTypes.some((d) => route.options[d]?.preload)
|
|
215
171
|
)
|
|
216
172
|
},
|
|
217
173
|
load: async (loaderOpts) => {
|
|
@@ -243,12 +199,18 @@ export function createRouteMatch<
|
|
|
243
199
|
) {
|
|
244
200
|
const maxAge = loaderOpts?.preload ? loaderOpts?.maxAge : undefined
|
|
245
201
|
|
|
246
|
-
routeMatch.fetch({ maxAge })
|
|
202
|
+
await routeMatch.fetch({ maxAge })
|
|
247
203
|
}
|
|
248
204
|
},
|
|
249
205
|
fetch: async (opts) => {
|
|
250
|
-
const
|
|
251
|
-
routeMatch.__.latestId =
|
|
206
|
+
const loadId = '' + Date.now() + Math.random()
|
|
207
|
+
routeMatch.__.latestId = loadId
|
|
208
|
+
const checkLatest = async () => {
|
|
209
|
+
if (loadId !== routeMatch.__.latestId) {
|
|
210
|
+
// warning(true, 'Data loader is out of date!')
|
|
211
|
+
return new Promise(() => {})
|
|
212
|
+
}
|
|
213
|
+
}
|
|
252
214
|
|
|
253
215
|
// If the match was in an error state, set it
|
|
254
216
|
// to a loading state again. Otherwise, keep it
|
|
@@ -266,103 +228,81 @@ export function createRouteMatch<
|
|
|
266
228
|
routeMatch.isFetching = true
|
|
267
229
|
routeMatch.__.resolve = resolve as () => void
|
|
268
230
|
|
|
269
|
-
|
|
270
|
-
//
|
|
271
|
-
|
|
272
|
-
routeMatch.__.elementsPromise = (async () => {
|
|
273
|
-
// then run all element and data loaders in parallel
|
|
274
|
-
// For each element type, potentially load it asynchronously
|
|
231
|
+
routeMatch.__.componentsPromise = (async () => {
|
|
232
|
+
// then run all component and data loaders in parallel
|
|
233
|
+
// For each component type, potentially load it asynchronously
|
|
275
234
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
235
|
+
await Promise.all(
|
|
236
|
+
componentTypes.map(async (type) => {
|
|
237
|
+
const component = routeMatch.options[type]
|
|
279
238
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
routeMatch.__[type] = await router.options.createElement!(
|
|
285
|
-
routeElement,
|
|
286
|
-
)
|
|
287
|
-
}),
|
|
288
|
-
)
|
|
289
|
-
})()
|
|
290
|
-
|
|
291
|
-
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
292
|
-
try {
|
|
293
|
-
if (routeMatch.options.loader) {
|
|
294
|
-
const data = await routeMatch.options.loader({
|
|
295
|
-
params: routeMatch.params,
|
|
296
|
-
search: routeMatch.routeSearch,
|
|
297
|
-
signal: routeMatch.__.abortController.signal,
|
|
298
|
-
})
|
|
299
|
-
if (id !== routeMatch.__.latestId) {
|
|
300
|
-
return routeMatch.__.loaderPromise
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
routeMatch.routeLoaderData = replaceEqualDeep(
|
|
304
|
-
routeMatch.routeLoaderData,
|
|
305
|
-
data,
|
|
239
|
+
if (routeMatch.__[type]?.preload) {
|
|
240
|
+
routeMatch.__[type] = await router.options.loadComponent!(
|
|
241
|
+
component,
|
|
306
242
|
)
|
|
307
243
|
}
|
|
244
|
+
}),
|
|
245
|
+
)
|
|
246
|
+
})()
|
|
308
247
|
|
|
309
|
-
|
|
310
|
-
routeMatch.status = 'success'
|
|
311
|
-
routeMatch.updatedAt = Date.now()
|
|
312
|
-
routeMatch.invalidAt =
|
|
313
|
-
routeMatch.updatedAt +
|
|
314
|
-
(opts?.maxAge ??
|
|
315
|
-
routeMatch.options.loaderMaxAge ??
|
|
316
|
-
router.options.defaultLoaderMaxAge ??
|
|
317
|
-
0)
|
|
318
|
-
} catch (err) {
|
|
319
|
-
if (id !== routeMatch.__.latestId) {
|
|
320
|
-
return routeMatch.__.loaderPromise
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
324
|
-
console.error(err)
|
|
325
|
-
}
|
|
326
|
-
routeMatch.error = err
|
|
327
|
-
routeMatch.status = 'error'
|
|
328
|
-
routeMatch.updatedAt = Date.now()
|
|
329
|
-
}
|
|
330
|
-
})
|
|
331
|
-
|
|
248
|
+
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
332
249
|
try {
|
|
333
|
-
|
|
334
|
-
routeMatch
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
250
|
+
if (routeMatch.options.loader) {
|
|
251
|
+
const data = await router.loadMatchData(routeMatch)
|
|
252
|
+
await checkLatest()
|
|
253
|
+
|
|
254
|
+
routeMatch.routeLoaderData = replaceEqualDeep(
|
|
255
|
+
routeMatch.routeLoaderData,
|
|
256
|
+
data,
|
|
257
|
+
)
|
|
339
258
|
}
|
|
340
259
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
260
|
+
routeMatch.error = undefined
|
|
261
|
+
routeMatch.status = 'success'
|
|
262
|
+
routeMatch.updatedAt = Date.now()
|
|
263
|
+
routeMatch.invalidAt =
|
|
264
|
+
routeMatch.updatedAt +
|
|
265
|
+
(opts?.maxAge ??
|
|
266
|
+
routeMatch.options.loaderMaxAge ??
|
|
267
|
+
router.options.defaultLoaderMaxAge ??
|
|
268
|
+
0)
|
|
269
|
+
|
|
270
|
+
return routeMatch.routeLoaderData
|
|
271
|
+
} catch (err) {
|
|
272
|
+
await checkLatest()
|
|
273
|
+
|
|
274
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
275
|
+
console.error(err)
|
|
344
276
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
routeMatch.isFetching = false
|
|
352
|
-
routeMatch.__.notify()
|
|
277
|
+
|
|
278
|
+
routeMatch.error = err
|
|
279
|
+
routeMatch.status = 'error'
|
|
280
|
+
routeMatch.updatedAt = Date.now()
|
|
281
|
+
|
|
282
|
+
throw err
|
|
353
283
|
}
|
|
354
|
-
})
|
|
284
|
+
})
|
|
355
285
|
|
|
356
|
-
|
|
357
|
-
|
|
286
|
+
const after = async () => {
|
|
287
|
+
await checkLatest()
|
|
288
|
+
routeMatch.isFetching = false
|
|
289
|
+
delete routeMatch.__.loadPromise
|
|
290
|
+
routeMatch.__.notify()
|
|
291
|
+
}
|
|
358
292
|
|
|
359
|
-
|
|
360
|
-
|
|
293
|
+
try {
|
|
294
|
+
await Promise.all([
|
|
295
|
+
routeMatch.__.componentsPromise,
|
|
296
|
+
routeMatch.__.dataPromise.catch(() => {}),
|
|
297
|
+
])
|
|
298
|
+
after()
|
|
299
|
+
} catch {
|
|
300
|
+
after()
|
|
361
301
|
}
|
|
362
|
-
delete routeMatch.__.loaderPromise
|
|
363
302
|
})
|
|
364
303
|
|
|
365
|
-
|
|
304
|
+
await routeMatch.__.loadPromise
|
|
305
|
+
await checkLatest()
|
|
366
306
|
},
|
|
367
307
|
}
|
|
368
308
|
|