@tanstack/react-router 0.0.1-beta.245 → 0.0.1-beta.247
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/index.js +2 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/path.js +7 -2
- package/build/cjs/path.js.map +1 -1
- package/build/cjs/route.js +10 -5
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +31 -12
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/useBlocker.js +1 -7
- package/build/cjs/useBlocker.js.map +1 -1
- package/build/esm/index.js +48 -27
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +363 -363
- package/build/types/fileRoute.d.ts +0 -1
- package/build/types/path.d.ts +1 -0
- package/build/types/route.d.ts +3 -2
- package/build/types/router.d.ts +2 -1
- package/build/umd/index.development.js +83 -48
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/path.ts +7 -2
- package/src/route.ts +59 -9
- package/src/router.ts +57 -25
- package/src/useBlocker.tsx +1 -9
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "0.0.1-beta.
|
|
4
|
+
"version": "0.0.1-beta.247",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "tanstack/router",
|
|
7
7
|
"homepage": "https://tanstack.com/router",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@tanstack/store": "^0.1.3",
|
|
45
45
|
"tiny-invariant": "^1.3.1",
|
|
46
46
|
"tiny-warning": "^1.0.3",
|
|
47
|
-
"@tanstack/history": "0.0.1-beta.
|
|
47
|
+
"@tanstack/history": "0.0.1-beta.247"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "rollup --config rollup.config.js"
|
package/src/path.ts
CHANGED
|
@@ -161,13 +161,17 @@ export function matchPathname(
|
|
|
161
161
|
return pathParams ?? {}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
export function removeBasepath(basepath: string, pathname: string) {
|
|
165
|
+
return basepath != '/' ? pathname.substring(basepath.length) : pathname
|
|
166
|
+
}
|
|
167
|
+
|
|
164
168
|
export function matchByPath(
|
|
165
169
|
basepath: string,
|
|
166
170
|
from: string,
|
|
167
171
|
matchLocation: Pick<MatchLocation, 'to' | 'caseSensitive' | 'fuzzy'>,
|
|
168
172
|
): Record<string, string> | undefined {
|
|
169
173
|
// Remove the base path from the pathname
|
|
170
|
-
from = basepath
|
|
174
|
+
from = removeBasepath(basepath, from)
|
|
171
175
|
// Default to to $ (wildcard)
|
|
172
176
|
const to = `${matchLocation.to ?? '$'}`
|
|
173
177
|
// Parse the from and to
|
|
@@ -245,7 +249,8 @@ export function matchByPath(
|
|
|
245
249
|
}
|
|
246
250
|
|
|
247
251
|
if (!isLastBaseSegment && isLastRouteSegment) {
|
|
248
|
-
|
|
252
|
+
params['**'] = joinPaths(baseSegments.slice(i + 1).map((d) => d.value))
|
|
253
|
+
return !!matchLocation.fuzzy && routeSegment?.value !== '/'
|
|
249
254
|
}
|
|
250
255
|
}
|
|
251
256
|
|
package/src/route.ts
CHANGED
|
@@ -224,9 +224,6 @@ export type UpdatableRouteOptions<
|
|
|
224
224
|
onEnter?: (match: AnyRouteMatch) => void
|
|
225
225
|
onTransition?: (match: AnyRouteMatch) => void
|
|
226
226
|
onLeave?: (match: AnyRouteMatch) => void
|
|
227
|
-
// Set this to true or false to specifically set whether or not this route should be preloaded. If unset, will
|
|
228
|
-
// default to router.options.reloadOnWindowFocus
|
|
229
|
-
reloadOnWindowFocus?: boolean
|
|
230
227
|
}
|
|
231
228
|
|
|
232
229
|
export type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<
|
|
@@ -459,7 +456,6 @@ export class Route<
|
|
|
459
456
|
) {
|
|
460
457
|
this.options = (options as any) || {}
|
|
461
458
|
this.isRoot = !options?.getParentRoute as any
|
|
462
|
-
Route.__onInit(this)
|
|
463
459
|
;(this as any).$$typeof = Symbol.for('react.memo')
|
|
464
460
|
}
|
|
465
461
|
|
|
@@ -585,11 +581,6 @@ export class Route<
|
|
|
585
581
|
return this
|
|
586
582
|
}
|
|
587
583
|
|
|
588
|
-
static __onInit = (route: any) => {
|
|
589
|
-
// This is a dummy static method that should get
|
|
590
|
-
// replaced by a framework specific implementation if necessary
|
|
591
|
-
}
|
|
592
|
-
|
|
593
584
|
useMatch = <TSelected = TAllContext>(opts?: {
|
|
594
585
|
select?: (search: TAllContext) => TSelected
|
|
595
586
|
}): TSelected => {
|
|
@@ -859,3 +850,62 @@ export type ComponentPropsFromRoute<TRoute> =
|
|
|
859
850
|
>
|
|
860
851
|
? RouteProps<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>
|
|
861
852
|
: {}
|
|
853
|
+
|
|
854
|
+
export class NotFoundRoute<
|
|
855
|
+
TParentRoute extends AnyRootRoute,
|
|
856
|
+
TSearchSchema extends RouteConstraints['TSearchSchema'] = {},
|
|
857
|
+
TFullSearchSchema extends
|
|
858
|
+
RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<
|
|
859
|
+
TParentRoute,
|
|
860
|
+
TSearchSchema
|
|
861
|
+
>,
|
|
862
|
+
TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,
|
|
863
|
+
TAllContext extends Expand<
|
|
864
|
+
Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
|
|
865
|
+
> = Expand<
|
|
866
|
+
Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>
|
|
867
|
+
>,
|
|
868
|
+
TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,
|
|
869
|
+
TLoaderData extends any = unknown,
|
|
870
|
+
TChildren extends RouteConstraints['TChildren'] = unknown,
|
|
871
|
+
TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,
|
|
872
|
+
> extends Route<
|
|
873
|
+
TParentRoute,
|
|
874
|
+
'/404',
|
|
875
|
+
'/404',
|
|
876
|
+
'404',
|
|
877
|
+
'404',
|
|
878
|
+
TSearchSchema,
|
|
879
|
+
TFullSearchSchema,
|
|
880
|
+
{},
|
|
881
|
+
{},
|
|
882
|
+
TRouteContext,
|
|
883
|
+
TAllContext,
|
|
884
|
+
TRouterContext,
|
|
885
|
+
TLoaderData,
|
|
886
|
+
TChildren,
|
|
887
|
+
TRouteTree
|
|
888
|
+
> {
|
|
889
|
+
constructor(
|
|
890
|
+
options: Omit<
|
|
891
|
+
RouteOptions<
|
|
892
|
+
TParentRoute,
|
|
893
|
+
string,
|
|
894
|
+
string,
|
|
895
|
+
TSearchSchema,
|
|
896
|
+
TFullSearchSchema,
|
|
897
|
+
{},
|
|
898
|
+
{},
|
|
899
|
+
TRouteContext,
|
|
900
|
+
TAllContext,
|
|
901
|
+
TLoaderData
|
|
902
|
+
>,
|
|
903
|
+
'caseSensitive' | 'parseParams' | 'stringifyParams' | 'path' | 'id'
|
|
904
|
+
>,
|
|
905
|
+
) {
|
|
906
|
+
super({
|
|
907
|
+
...(options as any),
|
|
908
|
+
id: '404',
|
|
909
|
+
})
|
|
910
|
+
}
|
|
911
|
+
}
|
package/src/router.ts
CHANGED
|
@@ -56,8 +56,10 @@ import {
|
|
|
56
56
|
joinPaths,
|
|
57
57
|
matchPathname,
|
|
58
58
|
parsePathname,
|
|
59
|
+
removeBasepath,
|
|
59
60
|
resolvePath,
|
|
60
61
|
trimPath,
|
|
62
|
+
trimPathLeft,
|
|
61
63
|
trimPathRight,
|
|
62
64
|
} from './path'
|
|
63
65
|
import invariant from 'tiny-invariant'
|
|
@@ -130,6 +132,7 @@ export interface RouterOptions<
|
|
|
130
132
|
routeMasks?: RouteMask<TRouteTree>[]
|
|
131
133
|
unmaskOnReload?: boolean
|
|
132
134
|
Wrap?: (props: { children: any }) => JSX.Element
|
|
135
|
+
notFoundRoute?: AnyRoute
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
export interface RouterState<TRouteTree extends AnyRoute = AnyRoute> {
|
|
@@ -316,11 +319,14 @@ export class Router<
|
|
|
316
319
|
this.routesById = {} as RoutesById<TRouteTree>
|
|
317
320
|
this.routesByPath = {} as RoutesByPath<TRouteTree>
|
|
318
321
|
|
|
322
|
+
const notFoundRoute = this.options.notFoundRoute
|
|
323
|
+
if (notFoundRoute) {
|
|
324
|
+
notFoundRoute.init({ originalIndex: 99999999999 })
|
|
325
|
+
;(this.routesById as any)[notFoundRoute.id] = notFoundRoute
|
|
326
|
+
}
|
|
327
|
+
|
|
319
328
|
const recurseRoutes = (childRoutes: AnyRoute[]) => {
|
|
320
329
|
childRoutes.forEach((childRoute, i) => {
|
|
321
|
-
// if (typeof childRoute === 'function') {
|
|
322
|
-
// childRoute = (childRoute as any)()
|
|
323
|
-
// }
|
|
324
330
|
childRoute.init({ originalIndex: i })
|
|
325
331
|
|
|
326
332
|
const existingRoute = (this.routesById as any)[childRoute.id]
|
|
@@ -351,29 +357,42 @@ export class Router<
|
|
|
351
357
|
|
|
352
358
|
recurseRoutes([this.routeTree])
|
|
353
359
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
360
|
+
const scoredRoutes: {
|
|
361
|
+
child: AnyRoute
|
|
362
|
+
trimmed: string
|
|
363
|
+
parsed: ReturnType<typeof parsePathname>
|
|
364
|
+
index: number
|
|
365
|
+
score: number[]
|
|
366
|
+
}[] = []
|
|
367
|
+
|
|
368
|
+
;(Object.values(this.routesById) as AnyRoute[]).forEach((d, i) => {
|
|
369
|
+
if (d.isRoot || !d.path) {
|
|
370
|
+
return
|
|
371
|
+
}
|
|
358
372
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
}
|
|
373
|
+
const trimmed = trimPathLeft(d.fullPath)
|
|
374
|
+
const parsed = parsePathname(trimmed)
|
|
362
375
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
376
|
+
while (parsed.length > 1 && parsed[0]?.value === '/') {
|
|
377
|
+
parsed.shift()
|
|
378
|
+
}
|
|
367
379
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
380
|
+
const score = parsed.map((d) => {
|
|
381
|
+
if (d.type === 'param') {
|
|
382
|
+
return 0.5
|
|
383
|
+
}
|
|
371
384
|
|
|
372
|
-
|
|
373
|
-
|
|
385
|
+
if (d.type === 'wildcard') {
|
|
386
|
+
return 0.25
|
|
387
|
+
}
|
|
374
388
|
|
|
375
|
-
return
|
|
389
|
+
return 1
|
|
376
390
|
})
|
|
391
|
+
|
|
392
|
+
scoredRoutes.push({ child: d, trimmed, parsed, index: i, score })
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
this.flatRoutes = scoredRoutes
|
|
377
396
|
.sort((a, b) => {
|
|
378
397
|
let isIndex = a.trimmed === '/' ? 1 : b.trimmed === '/' ? -1 : 0
|
|
379
398
|
|
|
@@ -498,7 +517,7 @@ export class Router<
|
|
|
498
517
|
locationSearch: AnySearchSchema,
|
|
499
518
|
opts?: { throwOnError?: boolean; debug?: boolean },
|
|
500
519
|
): RouteMatch<TRouteTree>[] => {
|
|
501
|
-
let routeParams:
|
|
520
|
+
let routeParams: Record<string, string> = {}
|
|
502
521
|
|
|
503
522
|
let foundRoute = this.flatRoutes.find((route) => {
|
|
504
523
|
const matchedParams = matchPathname(
|
|
@@ -508,7 +527,7 @@ export class Router<
|
|
|
508
527
|
to: route.fullPath,
|
|
509
528
|
caseSensitive:
|
|
510
529
|
route.options.caseSensitive ?? this.options.caseSensitive,
|
|
511
|
-
fuzzy:
|
|
530
|
+
fuzzy: true,
|
|
512
531
|
},
|
|
513
532
|
)
|
|
514
533
|
|
|
@@ -524,7 +543,20 @@ export class Router<
|
|
|
524
543
|
foundRoute || (this.routesById as any)['__root__']
|
|
525
544
|
|
|
526
545
|
let matchedRoutes: AnyRoute[] = [routeCursor]
|
|
527
|
-
|
|
546
|
+
|
|
547
|
+
// Check to see if the route needs a 404 entry
|
|
548
|
+
if (
|
|
549
|
+
// If we found a route, and it's not an index route and we have left over path
|
|
550
|
+
(foundRoute
|
|
551
|
+
? foundRoute.path !== '/' && routeParams['**']
|
|
552
|
+
: // Or if we didn't find a route and we have left over path
|
|
553
|
+
trimPathRight(pathname)) &&
|
|
554
|
+
// And we have a 404 route configured
|
|
555
|
+
this.options.notFoundRoute
|
|
556
|
+
) {
|
|
557
|
+
matchedRoutes.push(this.options.notFoundRoute)
|
|
558
|
+
}
|
|
559
|
+
|
|
528
560
|
while (routeCursor?.parentRoute) {
|
|
529
561
|
routeCursor = routeCursor.parentRoute
|
|
530
562
|
if (routeCursor) matchedRoutes.unshift(routeCursor)
|
|
@@ -1380,13 +1412,13 @@ export class Router<
|
|
|
1380
1412
|
throwOnError: true,
|
|
1381
1413
|
})
|
|
1382
1414
|
|
|
1383
|
-
await this.loadMatches({
|
|
1415
|
+
matches = await this.loadMatches({
|
|
1384
1416
|
matches,
|
|
1385
1417
|
preload: true,
|
|
1386
1418
|
checkLatest: () => undefined,
|
|
1387
1419
|
})
|
|
1388
1420
|
|
|
1389
|
-
return
|
|
1421
|
+
return matches
|
|
1390
1422
|
}
|
|
1391
1423
|
|
|
1392
1424
|
buildLink: BuildLinkFn<TRouteTree> = (dest) => {
|
package/src/useBlocker.tsx
CHANGED
|
@@ -10,15 +10,7 @@ export function useBlocker(
|
|
|
10
10
|
|
|
11
11
|
React.useEffect(() => {
|
|
12
12
|
if (!condition) return
|
|
13
|
-
|
|
14
|
-
let unblock = history.block((retry, cancel) => {
|
|
15
|
-
if (window.confirm(message)) {
|
|
16
|
-
unblock()
|
|
17
|
-
retry()
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
return unblock
|
|
13
|
+
return history.block(message)
|
|
22
14
|
})
|
|
23
15
|
}
|
|
24
16
|
|