@tanstack/react-router 0.0.1-beta.226 → 0.0.1-beta.227
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/Matches.js +8 -6
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +0 -25
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/fileRoute.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +45 -50
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +52 -81
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +293 -287
- package/build/types/Matches.d.ts +0 -1
- package/build/types/fileRoute.d.ts +2 -2
- package/build/types/route.d.ts +6 -2
- package/build/umd/index.development.js +52 -82
- 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 +2 -2
- package/src/Matches.tsx +21 -23
- package/src/RouterProvider.tsx +4 -71
- package/src/fileRoute.ts +7 -6
- package/src/route.ts +3 -2
- package/src/router.ts +75 -75
package/build/esm/index.js
CHANGED
|
@@ -637,7 +637,6 @@ function Matches() {
|
|
|
637
637
|
matches: matches
|
|
638
638
|
}) : null));
|
|
639
639
|
}
|
|
640
|
-
const defaultPending = () => null;
|
|
641
640
|
function SafeFragment(props) {
|
|
642
641
|
return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
|
|
643
642
|
}
|
|
@@ -652,9 +651,9 @@ function Match({
|
|
|
652
651
|
const routeId = match?.routeId;
|
|
653
652
|
const route = routesById[routeId];
|
|
654
653
|
const locationKey = useRouterState().location.state?.key;
|
|
655
|
-
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent
|
|
654
|
+
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent;
|
|
656
655
|
const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
|
|
657
|
-
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ? React.Suspense : SafeFragment;
|
|
656
|
+
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ?? PendingComponent ? React.Suspense : SafeFragment;
|
|
658
657
|
const errorComponent = routeErrorComponent ? React.useCallback(props => {
|
|
659
658
|
return /*#__PURE__*/React.createElement(routeErrorComponent, {
|
|
660
659
|
...props,
|
|
@@ -664,6 +663,7 @@ function Match({
|
|
|
664
663
|
useParams: route.useParams
|
|
665
664
|
});
|
|
666
665
|
}, [route]) : undefined;
|
|
666
|
+
const ResolvedCatchBoundary = errorComponent ? CatchBoundary : SafeFragment;
|
|
667
667
|
return /*#__PURE__*/React.createElement(matchesContext.Provider, {
|
|
668
668
|
value: matches
|
|
669
669
|
}, /*#__PURE__*/React.createElement(ResolvedSuspenseBoundary, {
|
|
@@ -673,7 +673,7 @@ function Match({
|
|
|
673
673
|
useSearch: route.useSearch,
|
|
674
674
|
useParams: route.useParams
|
|
675
675
|
})
|
|
676
|
-
},
|
|
676
|
+
}, /*#__PURE__*/React.createElement(ResolvedCatchBoundary, {
|
|
677
677
|
resetKey: locationKey,
|
|
678
678
|
errorComponent: errorComponent,
|
|
679
679
|
onCatch: () => {
|
|
@@ -681,8 +681,6 @@ function Match({
|
|
|
681
681
|
}
|
|
682
682
|
}, /*#__PURE__*/React.createElement(MatchInner, {
|
|
683
683
|
match: match
|
|
684
|
-
})) : /*#__PURE__*/React.createElement(SafeFragment, null, /*#__PURE__*/React.createElement(MatchInner, {
|
|
685
|
-
match: match
|
|
686
684
|
}))));
|
|
687
685
|
}
|
|
688
686
|
function MatchInner({
|
|
@@ -693,6 +691,9 @@ function MatchInner({
|
|
|
693
691
|
routesById
|
|
694
692
|
} = useRouter();
|
|
695
693
|
const route = routesById[match.routeId];
|
|
694
|
+
if (match.id.split('/').length === 4) {
|
|
695
|
+
console.log(match.id, pick(match, ['status', 'cause', 'isFetching']));
|
|
696
|
+
}
|
|
696
697
|
if (match.status === 'error') {
|
|
697
698
|
throw match.error;
|
|
698
699
|
}
|
|
@@ -786,31 +787,6 @@ function useLoaderData(opts) {
|
|
|
786
787
|
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
787
788
|
}
|
|
788
789
|
|
|
789
|
-
// export type RouterContext<
|
|
790
|
-
// TRouteTree extends AnyRoute,
|
|
791
|
-
// // TDehydrated extends Record<string, any>,
|
|
792
|
-
// > = {
|
|
793
|
-
// buildLink: BuildLinkFn<TRouteTree>
|
|
794
|
-
// state: RouterState<TRouteTree>
|
|
795
|
-
// navigate: NavigateFn<TRouteTree>
|
|
796
|
-
// matchRoute: MatchRouteFn<TRouteTree>
|
|
797
|
-
// routeTree: TRouteTree
|
|
798
|
-
// routesById: RoutesById<TRouteTree>
|
|
799
|
-
// options: RouterOptions<TRouteTree>
|
|
800
|
-
// history: RouterHistory
|
|
801
|
-
// load: LoadFn
|
|
802
|
-
// buildLocation: BuildLocationFn<TRouteTree>
|
|
803
|
-
// subscribe: Router<TRouteTree>['subscribe']
|
|
804
|
-
// resetNextScrollRef: React.MutableRefObject<boolean>
|
|
805
|
-
// injectedHtmlRef: React.MutableRefObject<InjectedHtmlEntry[]>
|
|
806
|
-
// injectHtml: (entry: InjectedHtmlEntry) => void
|
|
807
|
-
// dehydrateData: <T>(
|
|
808
|
-
// key: any,
|
|
809
|
-
// getData: T | (() => Promise<T> | T),
|
|
810
|
-
// ) => () => void
|
|
811
|
-
// hydrateData: <T>(key: any) => T | undefined
|
|
812
|
-
// }
|
|
813
|
-
|
|
814
790
|
const routerContext = /*#__PURE__*/React.createContext(null);
|
|
815
791
|
if (typeof document !== 'undefined') {
|
|
816
792
|
window.__TSR_ROUTER_CONTEXT__ = routerContext;
|
|
@@ -1484,38 +1460,66 @@ class Router {
|
|
|
1484
1460
|
}
|
|
1485
1461
|
return;
|
|
1486
1462
|
});
|
|
1487
|
-
const matches =
|
|
1463
|
+
const matches = [];
|
|
1464
|
+
matchedRoutes.forEach((route, index) => {
|
|
1465
|
+
// Take each matched route and resolve + validate its search params
|
|
1466
|
+
// This has to happen serially because each route's search params
|
|
1467
|
+
// can depend on the parent route's search params
|
|
1468
|
+
// It must also happen before we create the match so that we can
|
|
1469
|
+
// pass the search params to the route's potential key function
|
|
1470
|
+
// which is used to uniquely identify the route match in state
|
|
1471
|
+
|
|
1472
|
+
const parentMatch = matches[index - 1];
|
|
1473
|
+
const [preMatchSearch, searchError] = (() => {
|
|
1474
|
+
// Validate the search params and stabilize them
|
|
1475
|
+
const parentSearch = parentMatch?.search ?? locationSearch;
|
|
1476
|
+
try {
|
|
1477
|
+
const validator = typeof route.options.validateSearch === 'object' ? route.options.validateSearch.parse : route.options.validateSearch;
|
|
1478
|
+
let search = validator?.(parentSearch) ?? {};
|
|
1479
|
+
return [{
|
|
1480
|
+
...parentSearch,
|
|
1481
|
+
...search
|
|
1482
|
+
}, undefined];
|
|
1483
|
+
} catch (err) {
|
|
1484
|
+
const searchError = new SearchParamError(err.message, {
|
|
1485
|
+
cause: err
|
|
1486
|
+
});
|
|
1487
|
+
if (opts?.throwOnError) {
|
|
1488
|
+
throw searchError;
|
|
1489
|
+
}
|
|
1490
|
+
return [parentSearch, searchError];
|
|
1491
|
+
}
|
|
1492
|
+
})();
|
|
1488
1493
|
const interpolatedPath = interpolatePath(route.path, routeParams);
|
|
1489
|
-
const matchId = interpolatePath(route.id, routeParams, true)
|
|
1494
|
+
const matchId = interpolatePath(route.id, routeParams, true) + (route.options.key?.({
|
|
1495
|
+
search: preMatchSearch,
|
|
1496
|
+
location: this.state.location
|
|
1497
|
+
}) ?? '');
|
|
1490
1498
|
|
|
1491
1499
|
// Waste not, want not. If we already have a match for this route,
|
|
1492
1500
|
// reuse it. This is important for layout routes, which might stick
|
|
1493
1501
|
// around between navigation actions that only change leaf routes.
|
|
1494
1502
|
const existingMatch = getRouteMatch(this.state, matchId);
|
|
1495
1503
|
const cause = this.state.matches.find(d => d.id === matchId) ? 'stay' : 'enter';
|
|
1496
|
-
if (existingMatch) {
|
|
1497
|
-
return {
|
|
1498
|
-
...existingMatch,
|
|
1499
|
-
cause
|
|
1500
|
-
};
|
|
1501
|
-
}
|
|
1502
1504
|
|
|
1503
1505
|
// Create a fresh route match
|
|
1504
1506
|
const hasLoaders = !!(route.options.loader || componentTypes.some(d => route.options[d]?.preload));
|
|
1505
|
-
const
|
|
1507
|
+
const match = existingMatch ? {
|
|
1508
|
+
...existingMatch,
|
|
1509
|
+
cause
|
|
1510
|
+
} : {
|
|
1506
1511
|
id: matchId,
|
|
1507
1512
|
routeId: route.id,
|
|
1508
1513
|
params: routeParams,
|
|
1509
1514
|
pathname: joinPaths([this.basepath, interpolatedPath]),
|
|
1510
1515
|
updatedAt: Date.now(),
|
|
1511
|
-
routeSearch: {},
|
|
1512
1516
|
search: {},
|
|
1517
|
+
searchError: undefined,
|
|
1513
1518
|
status: hasLoaders ? 'pending' : 'success',
|
|
1514
1519
|
isFetching: false,
|
|
1515
1520
|
invalid: false,
|
|
1516
1521
|
error: undefined,
|
|
1517
1522
|
paramsError: parseErrors[index],
|
|
1518
|
-
searchError: undefined,
|
|
1519
1523
|
loadPromise: Promise.resolve(),
|
|
1520
1524
|
context: undefined,
|
|
1521
1525
|
abortController: new AbortController(),
|
|
@@ -1523,46 +1527,13 @@ class Router {
|
|
|
1523
1527
|
fetchedAt: 0,
|
|
1524
1528
|
cause
|
|
1525
1529
|
};
|
|
1526
|
-
return routeMatch;
|
|
1527
|
-
});
|
|
1528
1530
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
const searchInfo = (() => {
|
|
1536
|
-
// Validate the search params and stabilize them
|
|
1537
|
-
const parentSearchInfo = {
|
|
1538
|
-
search: parentMatch?.search ?? locationSearch,
|
|
1539
|
-
routeSearch: parentMatch?.routeSearch ?? locationSearch
|
|
1540
|
-
};
|
|
1541
|
-
try {
|
|
1542
|
-
const validator = typeof route.options.validateSearch === 'object' ? route.options.validateSearch.parse : route.options.validateSearch;
|
|
1543
|
-
let routeSearch = validator?.(parentSearchInfo.search) ?? {};
|
|
1544
|
-
let search = {
|
|
1545
|
-
...parentSearchInfo.search,
|
|
1546
|
-
...routeSearch
|
|
1547
|
-
};
|
|
1548
|
-
routeSearch = replaceEqualDeep(match.routeSearch, routeSearch);
|
|
1549
|
-
search = replaceEqualDeep(match.search, search);
|
|
1550
|
-
return {
|
|
1551
|
-
routeSearch,
|
|
1552
|
-
search,
|
|
1553
|
-
searchDidChange: match.routeSearch !== routeSearch
|
|
1554
|
-
};
|
|
1555
|
-
} catch (err) {
|
|
1556
|
-
match.searchError = new SearchParamError(err.message, {
|
|
1557
|
-
cause: err
|
|
1558
|
-
});
|
|
1559
|
-
if (opts?.throwOnError) {
|
|
1560
|
-
throw match.searchError;
|
|
1561
|
-
}
|
|
1562
|
-
return parentSearchInfo;
|
|
1563
|
-
}
|
|
1564
|
-
})();
|
|
1565
|
-
Object.assign(match, searchInfo);
|
|
1531
|
+
// Regardless of whether we're reusing an existing match or creating
|
|
1532
|
+
// a new one, we need to update the match's search params
|
|
1533
|
+
match.search = replaceEqualDeep(match.search, preMatchSearch);
|
|
1534
|
+
// And also update the searchError if there is one
|
|
1535
|
+
match.searchError = searchError;
|
|
1536
|
+
matches.push(match);
|
|
1566
1537
|
});
|
|
1567
1538
|
return matches;
|
|
1568
1539
|
};
|