@tanstack/react-router 1.5.4 → 1.5.6

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.
Files changed (61) hide show
  1. package/build/cjs/Matches.js +15 -14
  2. package/build/cjs/Matches.js.map +1 -1
  3. package/build/cjs/RouterProvider.js +6 -27
  4. package/build/cjs/RouterProvider.js.map +1 -1
  5. package/build/cjs/awaited.js +2 -2
  6. package/build/cjs/awaited.js.map +1 -1
  7. package/build/cjs/index.js +11 -7
  8. package/build/cjs/index.js.map +1 -1
  9. package/build/cjs/link.js +4 -3
  10. package/build/cjs/link.js.map +1 -1
  11. package/build/cjs/router.js.map +1 -1
  12. package/build/cjs/routerContext.js +42 -0
  13. package/build/cjs/routerContext.js.map +1 -0
  14. package/build/cjs/scroll-restoration.js +3 -3
  15. package/build/cjs/scroll-restoration.js.map +1 -1
  16. package/build/cjs/useBlocker.js +2 -2
  17. package/build/cjs/useBlocker.js.map +1 -1
  18. package/build/cjs/useNavigate.js +3 -3
  19. package/build/cjs/useNavigate.js.map +1 -1
  20. package/build/cjs/useParams.js +2 -2
  21. package/build/cjs/useParams.js.map +1 -1
  22. package/build/cjs/useRouteContext.js +23 -0
  23. package/build/cjs/useRouteContext.js.map +1 -0
  24. package/build/cjs/useRouter.js +44 -0
  25. package/build/cjs/useRouter.js.map +1 -0
  26. package/build/cjs/useRouterState.js +24 -0
  27. package/build/cjs/useRouterState.js.map +1 -0
  28. package/build/cjs/utils.js +0 -8
  29. package/build/cjs/utils.js.map +1 -1
  30. package/build/esm/index.js +192 -188
  31. package/build/esm/index.js.map +1 -1
  32. package/build/stats-html.html +1 -1
  33. package/build/stats-react.json +582 -431
  34. package/build/types/RouterProvider.d.ts +2 -13
  35. package/build/types/index.d.ts +4 -1
  36. package/build/types/router.d.ts +6 -5
  37. package/build/types/routerContext.d.ts +3 -0
  38. package/build/types/useRouteContext.d.ts +7 -0
  39. package/build/types/useRouter.d.ts +5 -0
  40. package/build/types/useRouterState.d.ts +6 -0
  41. package/build/types/utils.d.ts +0 -6
  42. package/build/umd/index.development.js +367 -363
  43. package/build/umd/index.development.js.map +1 -1
  44. package/build/umd/index.production.js +1 -1
  45. package/build/umd/index.production.js.map +1 -1
  46. package/package.json +2 -2
  47. package/src/Matches.tsx +2 -1
  48. package/src/RouterProvider.tsx +8 -60
  49. package/src/awaited.tsx +1 -1
  50. package/src/index.tsx +4 -2
  51. package/src/link.tsx +8 -7
  52. package/src/router.ts +18 -5
  53. package/src/routerContext.tsx +11 -0
  54. package/src/scroll-restoration.tsx +1 -1
  55. package/src/useBlocker.tsx +1 -1
  56. package/src/useNavigate.tsx +1 -1
  57. package/src/useParams.tsx +1 -1
  58. package/src/useRouteContext.ts +24 -0
  59. package/src/useRouter.tsx +20 -0
  60. package/src/useRouterState.tsx +17 -0
  61. package/src/utils.ts +0 -24
@@ -359,6 +359,160 @@
359
359
  }
360
360
  }
361
361
 
362
+ exports.routerContext = /*#__PURE__*/React__namespace.createContext(null);
363
+ if (typeof document !== 'undefined') {
364
+ if (window.__TSR_ROUTER_CONTEXT__) {
365
+ exports.routerContext = window.__TSR_ROUTER_CONTEXT__;
366
+ } else {
367
+ window.__TSR_ROUTER_CONTEXT__ = exports.routerContext;
368
+ }
369
+ }
370
+
371
+ function useRouter(opts) {
372
+ const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || exports.routerContext : exports.routerContext;
373
+ const value = React__namespace.useContext(resolvedContext);
374
+ warning(!((opts?.warn ?? true) && !value), 'useRouter must be used inside a <RouterProvider> component!');
375
+ return value;
376
+ }
377
+
378
+ function defer(_promise) {
379
+ const promise = _promise;
380
+ if (!promise.__deferredState) {
381
+ promise.__deferredState = {
382
+ uid: Math.random().toString(36).slice(2),
383
+ status: 'pending'
384
+ };
385
+ const state = promise.__deferredState;
386
+ promise.then(data => {
387
+ state.status = 'success';
388
+ state.data = data;
389
+ }).catch(error => {
390
+ state.status = 'error';
391
+ state.error = error;
392
+ });
393
+ }
394
+ return promise;
395
+ }
396
+ function isDehydratedDeferred(obj) {
397
+ return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
398
+ }
399
+
400
+ function useAwaited({
401
+ promise
402
+ }) {
403
+ const router = useRouter();
404
+ let state = promise.__deferredState;
405
+ const key = `__TSR__DEFERRED__${state.uid}`;
406
+ if (isDehydratedDeferred(promise)) {
407
+ state = router.hydrateData(key);
408
+ promise = Promise.resolve(state.data);
409
+ promise.__deferredState = state;
410
+ }
411
+ if (state.status === 'pending') {
412
+ throw promise;
413
+ }
414
+ if (state.status === 'error') {
415
+ throw state.error;
416
+ }
417
+ router.dehydrateData(key, state);
418
+ return [state.data];
419
+ }
420
+ function Await(props) {
421
+ const awaited = useAwaited(props);
422
+ return props.children(...awaited);
423
+ }
424
+
425
+ function CatchBoundary(props) {
426
+ const errorComponent = props.errorComponent ?? ErrorComponent;
427
+ return /*#__PURE__*/React__namespace.createElement(CatchBoundaryImpl, {
428
+ getResetKey: props.getResetKey,
429
+ onCatch: props.onCatch,
430
+ children: ({
431
+ error
432
+ }) => {
433
+ if (error) {
434
+ return /*#__PURE__*/React__namespace.createElement(errorComponent, {
435
+ error
436
+ });
437
+ }
438
+ return props.children;
439
+ }
440
+ });
441
+ }
442
+ class CatchBoundaryImpl extends React__namespace.Component {
443
+ state = {
444
+ error: null
445
+ };
446
+ static getDerivedStateFromProps(props) {
447
+ return {
448
+ resetKey: props.getResetKey()
449
+ };
450
+ }
451
+ static getDerivedStateFromError(error) {
452
+ return {
453
+ error
454
+ };
455
+ }
456
+ componentDidUpdate(prevProps, prevState) {
457
+ if (prevState.error && prevState.resetKey !== this.state.resetKey) {
458
+ this.setState({
459
+ error: null
460
+ });
461
+ }
462
+ }
463
+ componentDidCatch(error) {
464
+ console.error(error);
465
+ this.props.onCatch?.(error);
466
+ }
467
+ render() {
468
+ return this.props.children(this.state);
469
+ }
470
+ }
471
+ function ErrorComponent({
472
+ error
473
+ }) {
474
+ const [show, setShow] = React__namespace.useState("development" !== 'production');
475
+ return /*#__PURE__*/React__namespace.createElement("div", {
476
+ style: {
477
+ padding: '.5rem',
478
+ maxWidth: '100%'
479
+ }
480
+ }, /*#__PURE__*/React__namespace.createElement("div", {
481
+ style: {
482
+ display: 'flex',
483
+ alignItems: 'center',
484
+ gap: '.5rem'
485
+ }
486
+ }, /*#__PURE__*/React__namespace.createElement("strong", {
487
+ style: {
488
+ fontSize: '1rem'
489
+ }
490
+ }, "Something went wrong!"), /*#__PURE__*/React__namespace.createElement("button", {
491
+ style: {
492
+ appearance: 'none',
493
+ fontSize: '.6em',
494
+ border: '1px solid currentColor',
495
+ padding: '.1rem .2rem',
496
+ fontWeight: 'bold',
497
+ borderRadius: '.25rem'
498
+ },
499
+ onClick: () => setShow(d => !d)
500
+ }, show ? 'Hide Error' : 'Show Error')), /*#__PURE__*/React__namespace.createElement("div", {
501
+ style: {
502
+ height: '.25rem'
503
+ }
504
+ }), show ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("pre", {
505
+ style: {
506
+ fontSize: '.7em',
507
+ border: '1px solid red',
508
+ borderRadius: '.25rem',
509
+ padding: '.3rem',
510
+ color: 'red',
511
+ overflow: 'auto'
512
+ }
513
+ }, error.message ? /*#__PURE__*/React__namespace.createElement("code", null, error.message) : null)) : null);
514
+ }
515
+
362
516
  var withSelector = {exports: {}};
363
517
 
364
518
  var withSelector_development = {};
@@ -625,95 +779,11 @@
625
779
  return true;
626
780
  }
627
781
 
628
- function CatchBoundary(props) {
629
- const errorComponent = props.errorComponent ?? ErrorComponent;
630
- return /*#__PURE__*/React__namespace.createElement(CatchBoundaryImpl, {
631
- getResetKey: props.getResetKey,
632
- onCatch: props.onCatch,
633
- children: ({
634
- error
635
- }) => {
636
- if (error) {
637
- return /*#__PURE__*/React__namespace.createElement(errorComponent, {
638
- error
639
- });
640
- }
641
- return props.children;
642
- }
782
+ function useRouterState(opts) {
783
+ const contextRouter = useRouter({
784
+ warn: opts?.router === undefined
643
785
  });
644
- }
645
- class CatchBoundaryImpl extends React__namespace.Component {
646
- state = {
647
- error: null
648
- };
649
- static getDerivedStateFromProps(props) {
650
- return {
651
- resetKey: props.getResetKey()
652
- };
653
- }
654
- static getDerivedStateFromError(error) {
655
- return {
656
- error
657
- };
658
- }
659
- componentDidUpdate(prevProps, prevState) {
660
- if (prevState.error && prevState.resetKey !== this.state.resetKey) {
661
- this.setState({
662
- error: null
663
- });
664
- }
665
- }
666
- componentDidCatch(error) {
667
- console.error(error);
668
- this.props.onCatch?.(error);
669
- }
670
- render() {
671
- return this.props.children(this.state);
672
- }
673
- }
674
- function ErrorComponent({
675
- error
676
- }) {
677
- const [show, setShow] = React__namespace.useState("development" !== 'production');
678
- return /*#__PURE__*/React__namespace.createElement("div", {
679
- style: {
680
- padding: '.5rem',
681
- maxWidth: '100%'
682
- }
683
- }, /*#__PURE__*/React__namespace.createElement("div", {
684
- style: {
685
- display: 'flex',
686
- alignItems: 'center',
687
- gap: '.5rem'
688
- }
689
- }, /*#__PURE__*/React__namespace.createElement("strong", {
690
- style: {
691
- fontSize: '1rem'
692
- }
693
- }, "Something went wrong!"), /*#__PURE__*/React__namespace.createElement("button", {
694
- style: {
695
- appearance: 'none',
696
- fontSize: '.6em',
697
- border: '1px solid currentColor',
698
- padding: '.1rem .2rem',
699
- fontWeight: 'bold',
700
- borderRadius: '.25rem'
701
- },
702
- onClick: () => setShow(d => !d)
703
- }, show ? 'Hide Error' : 'Show Error')), /*#__PURE__*/React__namespace.createElement("div", {
704
- style: {
705
- height: '.25rem'
706
- }
707
- }), show ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("pre", {
708
- style: {
709
- fontSize: '.7em',
710
- border: '1px solid red',
711
- borderRadius: '.25rem',
712
- padding: '.3rem',
713
- color: 'red',
714
- overflow: 'auto'
715
- }
716
- }, error.message ? /*#__PURE__*/React__namespace.createElement("code", null, error.message) : null)) : null);
786
+ return useStore((opts?.router || contextRouter).__store, opts?.select);
717
787
  }
718
788
 
719
789
  // from https://stackoverflow.com/a/76458160
@@ -908,12 +978,6 @@
908
978
  }
909
979
  return true;
910
980
  }
911
- function useRouteContext(opts) {
912
- return useMatch({
913
- ...opts,
914
- select: match => opts?.select ? opts.select(match.context) : match.context
915
- });
916
- }
917
981
  const useLayoutEffect$1 = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
918
982
  function escapeJSON(jsonString) {
919
983
  return jsonString.replace(/\\/g, '\\\\') // Escape backslashes
@@ -1012,282 +1076,100 @@
1012
1076
  return matches[index + 1]?.id;
1013
1077
  }
1014
1078
  });
1015
- if (!childMatchId) {
1016
- return null;
1017
- }
1018
- return /*#__PURE__*/React__namespace.createElement(Match, {
1019
- matchId: childMatchId
1020
- });
1021
- });
1022
- function useMatchRoute() {
1023
- useRouterState({
1024
- select: s => [s.location, s.resolvedLocation]
1025
- });
1026
- const {
1027
- matchRoute
1028
- } = useRouter();
1029
- return React__namespace.useCallback(opts => {
1030
- const {
1031
- pending,
1032
- caseSensitive,
1033
- fuzzy,
1034
- includeSearch,
1035
- ...rest
1036
- } = opts;
1037
- return matchRoute(rest, {
1038
- pending,
1039
- caseSensitive,
1040
- fuzzy,
1041
- includeSearch
1042
- });
1043
- }, []);
1044
- }
1045
- function MatchRoute(props) {
1046
- const matchRoute = useMatchRoute();
1047
- const params = matchRoute(props);
1048
- if (typeof props.children === 'function') {
1049
- return props.children(params);
1050
- }
1051
- return !!params ? props.children : null;
1052
- }
1053
- function getRenderedMatches(state) {
1054
- return state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1055
- }
1056
- function useMatch(opts) {
1057
- const router = useRouter();
1058
- const nearestMatchId = React__namespace.useContext(matchContext);
1059
- const nearestMatchRouteId = getRenderedMatches(router.state).find(d => d.id === nearestMatchId)?.routeId;
1060
- const matchRouteId = (() => {
1061
- const matches = getRenderedMatches(router.state);
1062
- const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatchId);
1063
- return match.routeId;
1064
- })();
1065
- if (opts?.strict ?? true) {
1066
- invariant(nearestMatchRouteId == matchRouteId, `useMatch("${matchRouteId}") is being called in a component that is meant to render the '${nearestMatchRouteId}' route. Did you mean to 'useMatch("${matchRouteId}", { strict: false })' or 'useRoute("${matchRouteId}")' instead?`);
1067
- }
1068
- const matchSelection = useRouterState({
1069
- select: state => {
1070
- const match = getRenderedMatches(state).find(d => d.id === nearestMatchId);
1071
- invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
1072
- return opts?.select ? opts.select(match) : match;
1073
- }
1074
- });
1075
- return matchSelection;
1076
- }
1077
- function useMatches(opts) {
1078
- return useRouterState({
1079
- select: state => {
1080
- let matches = getRenderedMatches(state);
1081
- return opts?.select ? opts.select(matches) : matches;
1082
- }
1083
- });
1084
- }
1085
- function useParentMatches(opts) {
1086
- const contextMatchId = React__namespace.useContext(matchContext);
1087
- return useMatches({
1088
- select: matches => {
1089
- matches = matches.slice(matches.findIndex(d => d.id === contextMatchId));
1090
- return opts?.select ? opts.select(matches) : matches;
1091
- }
1092
- });
1093
- }
1094
- function useLoaderDeps(opts) {
1095
- return useMatch({
1096
- ...opts,
1097
- select: s => {
1098
- return typeof opts.select === 'function' ? opts.select(s?.loaderDeps) : s?.loaderDeps;
1099
- }
1100
- });
1101
- }
1102
- function useLoaderData(opts) {
1103
- return useMatch({
1104
- ...opts,
1105
- select: s => {
1106
- return typeof opts.select === 'function' ? opts.select(s?.loaderData) : s?.loaderData;
1107
- }
1108
- });
1109
- }
1110
-
1111
- const useTransition = React__namespace.useTransition || (() => [false, cb => {
1112
- cb();
1113
- }]);
1114
- exports.routerContext = /*#__PURE__*/React__namespace.createContext(null);
1115
- if (typeof document !== 'undefined') {
1116
- if (window.__TSR_ROUTER_CONTEXT__) {
1117
- exports.routerContext = window.__TSR_ROUTER_CONTEXT__;
1118
- } else {
1119
- window.__TSR_ROUTER_CONTEXT__ = exports.routerContext;
1120
- }
1121
- }
1122
- function RouterProvider({
1123
- router,
1124
- ...rest
1125
- }) {
1126
- // Allow the router to update options on the router instance
1127
- router.update({
1128
- ...router.options,
1129
- ...rest,
1130
- context: {
1131
- ...router.options.context,
1132
- ...rest?.context
1133
- }
1134
- });
1135
- const matches = router.options.InnerWrap ? /*#__PURE__*/React__namespace.createElement(router.options.InnerWrap, null, /*#__PURE__*/React__namespace.createElement(Matches, null)) : /*#__PURE__*/React__namespace.createElement(Matches, null);
1136
- const provider = /*#__PURE__*/React__namespace.createElement(exports.routerContext.Provider, {
1137
- value: router
1138
- }, matches, /*#__PURE__*/React__namespace.createElement(Transitioner, null));
1139
- if (router.options.Wrap) {
1140
- return /*#__PURE__*/React__namespace.createElement(router.options.Wrap, null, provider);
1141
- }
1142
- return provider;
1143
- }
1144
- function Transitioner() {
1145
- const mountLoadCount = React__namespace.useRef(0);
1146
- const router = useRouter();
1147
- const routerState = useRouterState({
1148
- select: s => pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning'])
1149
- });
1150
- const [isTransitioning, startReactTransition] = useTransition();
1151
- router.startReactTransition = startReactTransition;
1152
- React__namespace.useEffect(() => {
1153
- if (isTransitioning) {
1154
- router.__store.setState(s => ({
1155
- ...s,
1156
- isTransitioning
1157
- }));
1158
- }
1159
- }, [isTransitioning]);
1160
- const tryLoad = () => {
1161
- const apply = cb => {
1162
- if (!routerState.isTransitioning) {
1163
- startReactTransition(() => cb());
1164
- } else {
1165
- cb();
1166
- }
1167
- };
1168
- apply(() => {
1169
- try {
1170
- router.load();
1171
- } catch (err) {
1172
- console.error(err);
1173
- }
1174
- });
1175
- };
1176
- useLayoutEffect$1(() => {
1177
- const unsub = router.history.subscribe(() => {
1178
- router.latestLocation = router.parseLocation(router.latestLocation);
1179
- if (routerState.location !== router.latestLocation) {
1180
- tryLoad();
1181
- }
1182
- });
1183
- const nextLocation = router.buildLocation({
1184
- search: true,
1185
- params: true,
1186
- hash: true,
1187
- state: true
1188
- });
1189
- if (routerState.location.href !== nextLocation.href) {
1190
- router.commitLocation({
1191
- ...nextLocation,
1192
- replace: true
1193
- });
1194
- }
1195
- return () => {
1196
- unsub();
1197
- };
1198
- }, [router.history]);
1199
- useLayoutEffect$1(() => {
1200
- if (React__namespace.useTransition ? routerState.isTransitioning && !isTransitioning : !routerState.isLoading && routerState.resolvedLocation !== routerState.location) {
1201
- router.emit({
1202
- type: 'onResolved',
1203
- fromLocation: routerState.resolvedLocation,
1204
- toLocation: routerState.location,
1205
- pathChanged: routerState.location.href !== routerState.resolvedLocation?.href
1206
- });
1207
- if (document.querySelector) {
1208
- if (routerState.location.hash !== '') {
1209
- const el = document.getElementById(routerState.location.hash);
1210
- if (el) {
1211
- el.scrollIntoView();
1212
- }
1213
- }
1214
- }
1215
- router.__store.setState(s => ({
1216
- ...s,
1217
- isTransitioning: false,
1218
- resolvedLocation: s.location
1219
- }));
1220
- }
1221
- }, [routerState.isTransitioning, isTransitioning, routerState.isLoading, routerState.resolvedLocation, routerState.location]);
1222
- useLayoutEffect$1(() => {
1223
- if (!window.__TSR_DEHYDRATED__ && !mountLoadCount.current) {
1224
- mountLoadCount.current++;
1225
- tryLoad();
1226
- }
1227
- }, []);
1228
- return null;
1229
- }
1230
- function getRouteMatch(state, id) {
1231
- return [...state.cachedMatches, ...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
1232
- }
1233
- function useRouterState(opts) {
1234
- const contextRouter = useRouter({
1235
- warn: opts?.router === undefined
1236
- });
1237
- return useStore((opts?.router || contextRouter).__store, opts?.select);
1238
- }
1239
- function useRouter(opts) {
1240
- const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || exports.routerContext : exports.routerContext;
1241
- const value = React__namespace.useContext(resolvedContext);
1242
- warning(!((opts?.warn ?? true) && !value), 'useRouter must be used inside a <RouterProvider> component!');
1243
- return value;
1244
- }
1245
-
1246
- function defer(_promise) {
1247
- const promise = _promise;
1248
- if (!promise.__deferredState) {
1249
- promise.__deferredState = {
1250
- uid: Math.random().toString(36).slice(2),
1251
- status: 'pending'
1252
- };
1253
- const state = promise.__deferredState;
1254
- promise.then(data => {
1255
- state.status = 'success';
1256
- state.data = data;
1257
- }).catch(error => {
1258
- state.status = 'error';
1259
- state.error = error;
1079
+ if (!childMatchId) {
1080
+ return null;
1081
+ }
1082
+ return /*#__PURE__*/React__namespace.createElement(Match, {
1083
+ matchId: childMatchId
1084
+ });
1085
+ });
1086
+ function useMatchRoute() {
1087
+ useRouterState({
1088
+ select: s => [s.location, s.resolvedLocation]
1089
+ });
1090
+ const {
1091
+ matchRoute
1092
+ } = useRouter();
1093
+ return React__namespace.useCallback(opts => {
1094
+ const {
1095
+ pending,
1096
+ caseSensitive,
1097
+ fuzzy,
1098
+ includeSearch,
1099
+ ...rest
1100
+ } = opts;
1101
+ return matchRoute(rest, {
1102
+ pending,
1103
+ caseSensitive,
1104
+ fuzzy,
1105
+ includeSearch
1260
1106
  });
1107
+ }, []);
1108
+ }
1109
+ function MatchRoute(props) {
1110
+ const matchRoute = useMatchRoute();
1111
+ const params = matchRoute(props);
1112
+ if (typeof props.children === 'function') {
1113
+ return props.children(params);
1261
1114
  }
1262
- return promise;
1115
+ return !!params ? props.children : null;
1263
1116
  }
1264
- function isDehydratedDeferred(obj) {
1265
- return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
1117
+ function getRenderedMatches(state) {
1118
+ return state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
1266
1119
  }
1267
-
1268
- function useAwaited({
1269
- promise
1270
- }) {
1120
+ function useMatch(opts) {
1271
1121
  const router = useRouter();
1272
- let state = promise.__deferredState;
1273
- const key = `__TSR__DEFERRED__${state.uid}`;
1274
- if (isDehydratedDeferred(promise)) {
1275
- state = router.hydrateData(key);
1276
- promise = Promise.resolve(state.data);
1277
- promise.__deferredState = state;
1278
- }
1279
- if (state.status === 'pending') {
1280
- throw promise;
1281
- }
1282
- if (state.status === 'error') {
1283
- throw state.error;
1122
+ const nearestMatchId = React__namespace.useContext(matchContext);
1123
+ const nearestMatchRouteId = getRenderedMatches(router.state).find(d => d.id === nearestMatchId)?.routeId;
1124
+ const matchRouteId = (() => {
1125
+ const matches = getRenderedMatches(router.state);
1126
+ const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatchId);
1127
+ return match.routeId;
1128
+ })();
1129
+ if (opts?.strict ?? true) {
1130
+ invariant(nearestMatchRouteId == matchRouteId, `useMatch("${matchRouteId}") is being called in a component that is meant to render the '${nearestMatchRouteId}' route. Did you mean to 'useMatch("${matchRouteId}", { strict: false })' or 'useRoute("${matchRouteId}")' instead?`);
1284
1131
  }
1285
- router.dehydrateData(key, state);
1286
- return [state.data];
1132
+ const matchSelection = useRouterState({
1133
+ select: state => {
1134
+ const match = getRenderedMatches(state).find(d => d.id === nearestMatchId);
1135
+ invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
1136
+ return opts?.select ? opts.select(match) : match;
1137
+ }
1138
+ });
1139
+ return matchSelection;
1287
1140
  }
1288
- function Await(props) {
1289
- const awaited = useAwaited(props);
1290
- return props.children(...awaited);
1141
+ function useMatches(opts) {
1142
+ return useRouterState({
1143
+ select: state => {
1144
+ let matches = getRenderedMatches(state);
1145
+ return opts?.select ? opts.select(matches) : matches;
1146
+ }
1147
+ });
1148
+ }
1149
+ function useParentMatches(opts) {
1150
+ const contextMatchId = React__namespace.useContext(matchContext);
1151
+ return useMatches({
1152
+ select: matches => {
1153
+ matches = matches.slice(matches.findIndex(d => d.id === contextMatchId));
1154
+ return opts?.select ? opts.select(matches) : matches;
1155
+ }
1156
+ });
1157
+ }
1158
+ function useLoaderDeps(opts) {
1159
+ return useMatch({
1160
+ ...opts,
1161
+ select: s => {
1162
+ return typeof opts.select === 'function' ? opts.select(s?.loaderDeps) : s?.loaderDeps;
1163
+ }
1164
+ });
1165
+ }
1166
+ function useLoaderData(opts) {
1167
+ return useMatch({
1168
+ ...opts,
1169
+ select: s => {
1170
+ return typeof opts.select === 'function' ? opts.select(s?.loaderData) : s?.loaderData;
1171
+ }
1172
+ });
1291
1173
  }
1292
1174
 
1293
1175
  function joinPaths(paths) {
@@ -2119,6 +2001,121 @@
2119
2001
  };
2120
2002
  }
2121
2003
 
2004
+ const useTransition = React__namespace.useTransition || (() => [false, cb => {
2005
+ cb();
2006
+ }]);
2007
+ function RouterProvider({
2008
+ router,
2009
+ ...rest
2010
+ }) {
2011
+ // Allow the router to update options on the router instance
2012
+ router.update({
2013
+ ...router.options,
2014
+ ...rest,
2015
+ context: {
2016
+ ...router.options.context,
2017
+ ...rest?.context
2018
+ }
2019
+ });
2020
+ const matches = router.options.InnerWrap ? /*#__PURE__*/React__namespace.createElement(router.options.InnerWrap, null, /*#__PURE__*/React__namespace.createElement(Matches, null)) : /*#__PURE__*/React__namespace.createElement(Matches, null);
2021
+ const provider = /*#__PURE__*/React__namespace.createElement(exports.routerContext.Provider, {
2022
+ value: router
2023
+ }, matches, /*#__PURE__*/React__namespace.createElement(Transitioner, null));
2024
+ if (router.options.Wrap) {
2025
+ return /*#__PURE__*/React__namespace.createElement(router.options.Wrap, null, provider);
2026
+ }
2027
+ return provider;
2028
+ }
2029
+ function Transitioner() {
2030
+ const mountLoadCount = React__namespace.useRef(0);
2031
+ const router = useRouter();
2032
+ const routerState = useRouterState({
2033
+ select: s => pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning'])
2034
+ });
2035
+ const [isTransitioning, startReactTransition] = useTransition();
2036
+ router.startReactTransition = startReactTransition;
2037
+ React__namespace.useEffect(() => {
2038
+ if (isTransitioning) {
2039
+ router.__store.setState(s => ({
2040
+ ...s,
2041
+ isTransitioning
2042
+ }));
2043
+ }
2044
+ }, [isTransitioning]);
2045
+ const tryLoad = () => {
2046
+ const apply = cb => {
2047
+ if (!routerState.isTransitioning) {
2048
+ startReactTransition(() => cb());
2049
+ } else {
2050
+ cb();
2051
+ }
2052
+ };
2053
+ apply(() => {
2054
+ try {
2055
+ router.load();
2056
+ } catch (err) {
2057
+ console.error(err);
2058
+ }
2059
+ });
2060
+ };
2061
+ useLayoutEffect$1(() => {
2062
+ const unsub = router.history.subscribe(() => {
2063
+ router.latestLocation = router.parseLocation(router.latestLocation);
2064
+ if (routerState.location !== router.latestLocation) {
2065
+ tryLoad();
2066
+ }
2067
+ });
2068
+ const nextLocation = router.buildLocation({
2069
+ search: true,
2070
+ params: true,
2071
+ hash: true,
2072
+ state: true
2073
+ });
2074
+ if (routerState.location.href !== nextLocation.href) {
2075
+ router.commitLocation({
2076
+ ...nextLocation,
2077
+ replace: true
2078
+ });
2079
+ }
2080
+ return () => {
2081
+ unsub();
2082
+ };
2083
+ }, [router.history]);
2084
+ useLayoutEffect$1(() => {
2085
+ if (React__namespace.useTransition ? routerState.isTransitioning && !isTransitioning : !routerState.isLoading && routerState.resolvedLocation !== routerState.location) {
2086
+ router.emit({
2087
+ type: 'onResolved',
2088
+ fromLocation: routerState.resolvedLocation,
2089
+ toLocation: routerState.location,
2090
+ pathChanged: routerState.location.href !== routerState.resolvedLocation?.href
2091
+ });
2092
+ if (document.querySelector) {
2093
+ if (routerState.location.hash !== '') {
2094
+ const el = document.getElementById(routerState.location.hash);
2095
+ if (el) {
2096
+ el.scrollIntoView();
2097
+ }
2098
+ }
2099
+ }
2100
+ router.__store.setState(s => ({
2101
+ ...s,
2102
+ isTransitioning: false,
2103
+ resolvedLocation: s.location
2104
+ }));
2105
+ }
2106
+ }, [routerState.isTransitioning, isTransitioning, routerState.isLoading, routerState.resolvedLocation, routerState.location]);
2107
+ useLayoutEffect$1(() => {
2108
+ if (!window.__TSR_DEHYDRATED__ && !mountLoadCount.current) {
2109
+ mountLoadCount.current++;
2110
+ tryLoad();
2111
+ }
2112
+ }, []);
2113
+ return null;
2114
+ }
2115
+ function getRouteMatch(state, id) {
2116
+ return [...state.cachedMatches, ...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
2117
+ }
2118
+
2122
2119
  // import warning from 'tiny-warning'
2123
2120
 
2124
2121
  //
@@ -3414,6 +3411,13 @@
3414
3411
  return null;
3415
3412
  }
3416
3413
 
3414
+ function useRouteContext(opts) {
3415
+ return useMatch({
3416
+ ...opts,
3417
+ select: match => opts?.select ? opts.select(match.context) : match.context
3418
+ });
3419
+ }
3420
+
3417
3421
  exports.Await = Await;
3418
3422
  exports.Block = Block;
3419
3423
  exports.CatchBoundary = CatchBoundary;