@tanstack/router-devtools 0.0.1-beta.99 → 1.0.1

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 (37) hide show
  1. package/LICENSE +1 -1
  2. package/build/cjs/Explorer.js +10 -8
  3. package/build/cjs/Explorer.js.map +1 -1
  4. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +2 -4
  5. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  6. package/build/cjs/devtools.js +351 -106
  7. package/build/cjs/devtools.js.map +1 -1
  8. package/build/cjs/index.js +1 -3
  9. package/build/cjs/index.js.map +1 -1
  10. package/build/cjs/styledComponents.js +1 -4
  11. package/build/cjs/styledComponents.js.map +1 -1
  12. package/build/cjs/theme.js +10 -16
  13. package/build/cjs/theme.js.map +1 -1
  14. package/build/cjs/useLocalStorage.js +5 -9
  15. package/build/cjs/useLocalStorage.js.map +1 -1
  16. package/build/cjs/useMediaQuery.js +4 -8
  17. package/build/cjs/useMediaQuery.js.map +1 -1
  18. package/build/cjs/utils.js +36 -16
  19. package/build/cjs/utils.js.map +1 -1
  20. package/build/esm/index.js +342 -65
  21. package/build/esm/index.js.map +1 -1
  22. package/build/stats-html.html +3494 -2700
  23. package/build/stats-react.json +393 -147
  24. package/build/types/Explorer.d.ts +10 -4
  25. package/build/types/devtools.d.ts +1 -1
  26. package/build/types/styledComponents.d.ts +3 -3
  27. package/build/types/theme.d.ts +13 -13
  28. package/build/types/utils.d.ts +3 -2
  29. package/build/umd/index.development.js +662 -145
  30. package/build/umd/index.development.js.map +1 -1
  31. package/build/umd/index.production.js +4 -14
  32. package/build/umd/index.production.js.map +1 -1
  33. package/package.json +2 -3
  34. package/src/Explorer.tsx +5 -0
  35. package/src/devtools.tsx +574 -287
  36. package/src/theme.tsx +6 -6
  37. package/src/utils.ts +14 -4
@@ -1,5 +1,5 @@
1
1
  /**
2
- * router-devtools
2
+ * @tanstack/router-devtools/src/index.tsx
3
3
  *
4
4
  * Copyright (c) TanStack
5
5
  *
@@ -10,7 +10,7 @@
10
10
  */
11
11
  import * as React from 'react';
12
12
  import React__default from 'react';
13
- import { routerContext, invariant, useStore, last } from '@tanstack/router';
13
+ import { useRouter, useRouterState, invariant, trimPath } from '@tanstack/react-router';
14
14
 
15
15
  function _extends() {
16
16
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -64,16 +64,16 @@ function useLocalStorage(key, defaultValue) {
64
64
  }
65
65
 
66
66
  const defaultTheme = {
67
- background: '#0b1521',
68
- backgroundAlt: '#132337',
67
+ background: '#222222',
68
+ backgroundAlt: '#292929',
69
69
  foreground: 'white',
70
- gray: '#3f4e60',
71
- grayAlt: '#222e3e',
70
+ gray: '#444',
71
+ grayAlt: '#444',
72
72
  inputBackgroundColor: '#fff',
73
73
  inputTextColor: '#000',
74
- success: '#00ab52',
74
+ success: '#80cb00',
75
75
  danger: '#ff0085',
76
- active: '#006bff',
76
+ active: '#0099ff',
77
77
  warning: '#ffb200'
78
78
  };
79
79
  const ThemeContext = /*#__PURE__*/React__default.createContext(defaultTheme);
@@ -127,7 +127,12 @@ function useMediaQuery(query) {
127
127
 
128
128
  const isServer$1 = typeof window === 'undefined';
129
129
  function getStatusColor(match, theme) {
130
- return match.state.status === 'pending' ? theme.active : match.state.status === 'error' ? theme.danger : match.state.status === 'success' ? theme.success : theme.gray;
130
+ return match.status === 'pending' || match.isFetching ? theme.active : match.status === 'error' ? theme.danger : match.status === 'success' ? theme.success : theme.gray;
131
+ }
132
+ function getRouteStatusColor(matches, route, theme) {
133
+ const found = matches.find(d => d.routeId === route.id);
134
+ if (!found) return theme.gray;
135
+ return getStatusColor(found, theme);
131
136
  }
132
137
  function styled(type, newStyles, queries = {}) {
133
138
  return /*#__PURE__*/React__default.forwardRef(({
@@ -202,6 +207,25 @@ function scheduleMicrotask(callback) {
202
207
  throw error;
203
208
  }));
204
209
  }
210
+ function multiSortBy(arr, accessors = [d => d]) {
211
+ return arr.map((d, i) => [d, i]).sort(([a, ai], [b, bi]) => {
212
+ for (const accessor of accessors) {
213
+ const ao = accessor(a);
214
+ const bo = accessor(b);
215
+ if (typeof ao === 'undefined') {
216
+ if (typeof bo === 'undefined') {
217
+ continue;
218
+ }
219
+ return 1;
220
+ }
221
+ if (ao === bo) {
222
+ continue;
223
+ }
224
+ return ao > bo ? 1 : -1;
225
+ }
226
+ return ai - bi;
227
+ }).map(([d]) => d);
228
+ }
205
229
 
206
230
  const Panel = styled('div', (_props, theme) => ({
207
231
  fontSize: 'clamp(12px, 1.5vw, 14px)',
@@ -218,7 +242,6 @@ const Panel = styled('div', (_props, theme) => ({
218
242
  // flexDirection: 'column',
219
243
  }
220
244
  });
221
-
222
245
  const ActivePanel = styled('div', () => ({
223
246
  flex: '1 1 500px',
224
247
  display: 'flex',
@@ -375,6 +398,7 @@ function Explorer({
375
398
  defaultExpanded,
376
399
  renderer = DefaultRenderer,
377
400
  pageSize = 100,
401
+ filterSubEntries,
378
402
  ...rest
379
403
  }) {
380
404
  const [expanded, setExpanded] = React.useState(Boolean(defaultExpanded));
@@ -409,12 +433,14 @@ function Explorer({
409
433
  value: val
410
434
  }));
411
435
  }
436
+ subEntries = filterSubEntries ? filterSubEntries(subEntries) : subEntries;
412
437
  const subEntryPages = chunkArray(subEntries, pageSize);
413
438
  return renderer({
414
439
  handleEntry: entry => /*#__PURE__*/React.createElement(Explorer, _extends({
415
440
  key: entry.label,
416
441
  value: value,
417
- renderer: renderer
442
+ renderer: renderer,
443
+ filterSubEntries: filterSubEntries
418
444
  }, rest, entry)),
419
445
  type,
420
446
  subEntries,
@@ -670,6 +696,81 @@ function TanStackRouterDevtools({
670
696
  "aria-hidden": true
671
697
  })) : null);
672
698
  }
699
+ function RouteComp({
700
+ route,
701
+ isRoot,
702
+ activeId,
703
+ setActiveId
704
+ }) {
705
+ const routerState = useRouterState();
706
+ const matches = routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches;
707
+ const match = routerState.matches.find(d => d.routeId === route.id);
708
+ return /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("div", {
709
+ role: "button",
710
+ "aria-label": `Open match details for ${route.id}`,
711
+ onClick: () => {
712
+ if (match) {
713
+ setActiveId(activeId === route.id ? '' : route.id);
714
+ }
715
+ },
716
+ style: {
717
+ display: 'flex',
718
+ borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
719
+ cursor: match ? 'pointer' : 'default',
720
+ alignItems: 'center',
721
+ background: route.id === activeId ? 'rgba(255,255,255,.1)' : undefined,
722
+ padding: '.25rem .5rem',
723
+ gap: '.5rem'
724
+ }
725
+ }, isRoot ? null : /*#__PURE__*/React__default.createElement("div", {
726
+ style: {
727
+ flex: '0 0 auto',
728
+ width: '.7rem',
729
+ height: '.7rem',
730
+ alignItems: 'center',
731
+ justifyContent: 'center',
732
+ fontWeight: 'bold',
733
+ borderRadius: '100%',
734
+ transition: 'all .2s ease-out',
735
+ background: getRouteStatusColor(matches, route, defaultTheme),
736
+ opacity: match ? 1 : 0.3
737
+ }
738
+ }), /*#__PURE__*/React__default.createElement("div", {
739
+ style: {
740
+ flex: '1 0 auto',
741
+ display: 'flex',
742
+ justifyContent: 'space-between',
743
+ alignItems: 'center',
744
+ padding: isRoot ? '0 .25rem' : 0,
745
+ opacity: match ? 1 : 0.7,
746
+ fontSize: '0.7rem'
747
+ }
748
+ }, /*#__PURE__*/React__default.createElement(Code, null, route.path || trimPath(route.id), " "), /*#__PURE__*/React__default.createElement("div", {
749
+ style: {
750
+ display: 'flex',
751
+ alignItems: 'center',
752
+ gap: '.5rem'
753
+ }
754
+ }, match ? /*#__PURE__*/React__default.createElement(Code, {
755
+ style: {
756
+ opacity: 0.3
757
+ }
758
+ }, match.id) : null, /*#__PURE__*/React__default.createElement(AgeTicker, {
759
+ match: match
760
+ })))), route.children?.length ? /*#__PURE__*/React__default.createElement("div", {
761
+ style: {
762
+ marginLeft: isRoot ? 0 : '1rem',
763
+ borderLeft: isRoot ? '' : `solid 1px ${defaultTheme.grayAlt}`
764
+ }
765
+ }, [...route.children].sort((a, b) => {
766
+ return a.rank - b.rank;
767
+ }).map(r => /*#__PURE__*/React__default.createElement(RouteComp, {
768
+ key: r.id,
769
+ route: r,
770
+ activeId: activeId,
771
+ setActiveId: setActiveId
772
+ }))) : null);
773
+ }
673
774
  const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
674
775
  const {
675
776
  isOpen = true,
@@ -678,17 +779,21 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
678
779
  router: userRouter,
679
780
  ...panelProps
680
781
  } = props;
681
- const routerContextValue = React__default.useContext(routerContext);
682
- const router = userRouter ?? routerContextValue?.router;
782
+ const router = useRouter();
783
+ const routerState = useRouterState();
784
+ const matches = [...(routerState.pendingMatches ?? []), ...routerState.matches, ...routerState.cachedMatches];
683
785
  invariant(router, 'No router was found for the TanStack Router Devtools. Please place the devtools in the <RouterProvider> component tree or pass the router instance to the devtools manually.');
684
- useStore(router.__store);
685
- const [activeRouteId, setActiveRouteId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
686
- const [activeMatchId, setActiveMatchId] = useLocalStorage('tanstackRouterDevtoolsActiveMatchId', '');
687
- React__default.useEffect(() => {
688
- setActiveMatchId('');
689
- }, [activeRouteId]);
690
- const allMatches = React__default.useMemo(() => [...Object.values(router.state.currentMatches), ...Object.values(router.state.pendingMatches ?? [])], [router.state.currentMatches, router.state.pendingMatches]);
691
- const activeMatch = allMatches?.find(d => d.id === activeMatchId) || allMatches?.find(d => d.route.id === activeRouteId);
786
+
787
+ // useStore(router.__store)
788
+
789
+ const [showMatches, setShowMatches] = useLocalStorage('tanstackRouterDevtoolsShowMatches', true);
790
+ const [activeId, setActiveId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
791
+ const activeMatch = React__default.useMemo(() => matches.find(d => d.routeId === activeId || d.id === activeId), [matches, activeId]);
792
+ const hasSearch = Object.keys(routerState.location.search || {}).length;
793
+ const explorerState = {
794
+ ...router,
795
+ state: router.state
796
+ };
692
797
  return /*#__PURE__*/React__default.createElement(ThemeProvider, {
693
798
  theme: defaultTheme
694
799
  }, /*#__PURE__*/React__default.createElement(Panel, _extends({
@@ -793,8 +898,15 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
793
898
  }
794
899
  }, /*#__PURE__*/React__default.createElement(Explorer, {
795
900
  label: "Router",
796
- value: router,
797
- defaultExpanded: {}
901
+ value: Object.fromEntries(multiSortBy(Object.keys(explorerState), ['state', 'routesById', 'routesByPath', 'flatRoutes', 'options'].map(d => dd => dd !== d)).map(key => [key, explorerState[key]]).filter(d => typeof d[1] !== 'function' && !['__store', 'basepath', 'injectedHtml', 'subscribers', 'latestLoadPromise', 'navigateTimeout', 'resetNextScroll', 'tempLocationKey', 'latestLocation', 'routeTree', 'history'].includes(d[0]))),
902
+ defaultExpanded: {
903
+ state: {},
904
+ context: {},
905
+ options: {}
906
+ },
907
+ filterSubEntries: subEntries => {
908
+ return subEntries.filter(d => typeof d.value !== 'function');
909
+ }
798
910
  })))), /*#__PURE__*/React__default.createElement("div", {
799
911
  style: {
800
912
  flex: '1 1 500px',
@@ -805,20 +917,110 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
805
917
  display: 'flex',
806
918
  flexDirection: 'column'
807
919
  }
920
+ }, /*#__PURE__*/React__default.createElement("div", {
921
+ style: {
922
+ flex: '1 1 auto',
923
+ overflowY: 'auto'
924
+ }
808
925
  }, /*#__PURE__*/React__default.createElement("div", {
809
926
  style: {
810
927
  padding: '.5em',
811
928
  background: defaultTheme.backgroundAlt,
812
929
  position: 'sticky',
813
930
  top: 0,
814
- zIndex: 1
931
+ zIndex: 1,
932
+ display: 'flex',
933
+ alignItems: 'center',
934
+ gap: '.5rem',
935
+ fontWeight: 'bold'
936
+ }
937
+ }, "Pathname", ' ', routerState.location.maskedLocation ? /*#__PURE__*/React__default.createElement("div", {
938
+ style: {
939
+ padding: '.1rem .5rem',
940
+ background: defaultTheme.warning,
941
+ color: 'black',
942
+ borderRadius: '.5rem'
943
+ }
944
+ }, "Masked") : null), /*#__PURE__*/React__default.createElement("div", {
945
+ style: {
946
+ padding: '.5rem',
947
+ display: 'flex',
948
+ gap: '.5rem',
949
+ alignItems: 'center'
950
+ }
951
+ }, /*#__PURE__*/React__default.createElement("code", {
952
+ style: {
953
+ opacity: 0.6
954
+ }
955
+ }, routerState.location.pathname), routerState.location.maskedLocation ? /*#__PURE__*/React__default.createElement("code", {
956
+ style: {
957
+ color: defaultTheme.warning,
958
+ fontWeight: 'bold'
959
+ }
960
+ }, routerState.location.maskedLocation.pathname) : null), /*#__PURE__*/React__default.createElement("div", {
961
+ style: {
962
+ padding: '.5em',
963
+ background: defaultTheme.backgroundAlt,
964
+ position: 'sticky',
965
+ top: 0,
966
+ zIndex: 1,
967
+ display: 'flex',
968
+ alignItems: 'center',
969
+ justifyContent: 'space-between',
970
+ gap: '.5rem',
971
+ fontWeight: 'bold'
972
+ }
973
+ }, /*#__PURE__*/React__default.createElement("div", {
974
+ style: {
975
+ display: 'flex',
976
+ alignItems: 'center',
977
+ gap: '.5rem'
978
+ }
979
+ }, /*#__PURE__*/React__default.createElement("button", {
980
+ type: "button",
981
+ onClick: () => {
982
+ setShowMatches(false);
983
+ },
984
+ disabled: !showMatches,
985
+ style: {
986
+ appearance: 'none',
987
+ opacity: showMatches ? 0.5 : 1,
988
+ border: 0,
989
+ background: 'transparent',
990
+ color: 'inherit',
991
+ cursor: 'pointer'
992
+ }
993
+ }, "Routes"), "/", /*#__PURE__*/React__default.createElement("button", {
994
+ type: "button",
995
+ onClick: () => {
996
+ setShowMatches(true);
997
+ },
998
+ disabled: showMatches,
999
+ style: {
1000
+ appearance: 'none',
1001
+ opacity: !showMatches ? 0.5 : 1,
1002
+ border: 0,
1003
+ background: 'transparent',
1004
+ color: 'inherit',
1005
+ cursor: 'pointer'
1006
+ }
1007
+ }, "Matches")), /*#__PURE__*/React__default.createElement("div", {
1008
+ style: {
1009
+ opacity: 0.3,
1010
+ fontSize: '0.7rem',
1011
+ fontWeight: 'normal'
815
1012
  }
816
- }, "Active Matches"), router.state.currentMatches.map((match, i) => {
1013
+ }, "age / staleTime / gcTime")), !showMatches ? /*#__PURE__*/React__default.createElement(RouteComp, {
1014
+ route: router.routeTree,
1015
+ isRoot: true,
1016
+ activeId: activeId,
1017
+ setActiveId: setActiveId
1018
+ }) : /*#__PURE__*/React__default.createElement("div", null, (routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches).map((match, i) => {
817
1019
  return /*#__PURE__*/React__default.createElement("div", {
818
- key: match.route.id || i,
1020
+ key: match.id || i,
819
1021
  role: "button",
820
- "aria-label": `Open match details for ${match.route.id}`,
821
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
1022
+ "aria-label": `Open match details for ${match.id}`,
1023
+ onClick: () => setActiveId(activeId === match.id ? '' : match.id),
822
1024
  style: {
823
1025
  display: 'flex',
824
1026
  borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
@@ -841,49 +1043,76 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
841
1043
  }
842
1044
  }), /*#__PURE__*/React__default.createElement(Code, {
843
1045
  style: {
844
- padding: '.5em'
1046
+ padding: '.5em',
1047
+ fontSize: '0.7rem'
845
1048
  }
846
- }, `${match.id}`));
847
- }), router.state.pendingMatches?.length ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
1049
+ }, `${match.id}`), /*#__PURE__*/React__default.createElement(AgeTicker, {
1050
+ match: match
1051
+ }));
1052
+ }))), routerState.cachedMatches?.length ? /*#__PURE__*/React__default.createElement("div", {
1053
+ style: {
1054
+ flex: '1 1 auto',
1055
+ overflowY: 'auto',
1056
+ maxHeight: '50%'
1057
+ }
1058
+ }, /*#__PURE__*/React__default.createElement("div", {
848
1059
  style: {
849
- marginTop: '2rem',
850
1060
  padding: '.5em',
851
1061
  background: defaultTheme.backgroundAlt,
852
1062
  position: 'sticky',
853
1063
  top: 0,
854
- zIndex: 1
1064
+ zIndex: 1,
1065
+ display: 'flex',
1066
+ alignItems: 'center',
1067
+ justifyContent: 'space-between',
1068
+ gap: '.5rem',
1069
+ fontWeight: 'bold'
1070
+ }
1071
+ }, /*#__PURE__*/React__default.createElement("div", null, "Cached Matches"), /*#__PURE__*/React__default.createElement("div", {
1072
+ style: {
1073
+ opacity: 0.3,
1074
+ fontSize: '0.7rem',
1075
+ fontWeight: 'normal'
855
1076
  }
856
- }, "Pending Matches"), router.state.pendingMatches?.map((match, i) => {
1077
+ }, "age / staleTime / gcTime")), /*#__PURE__*/React__default.createElement("div", null, routerState.cachedMatches.map(match => {
857
1078
  return /*#__PURE__*/React__default.createElement("div", {
858
- key: match.route.id || i,
1079
+ key: match.id,
859
1080
  role: "button",
860
- "aria-label": `Open match details for ${match.route.id}`,
861
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
1081
+ "aria-label": `Open match details for ${match.id}`,
1082
+ onClick: () => setActiveId(activeId === match.id ? '' : match.id),
862
1083
  style: {
863
1084
  display: 'flex',
864
1085
  borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
865
1086
  cursor: 'pointer',
866
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
1087
+ alignItems: 'center',
1088
+ background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
1089
+ fontSize: '0.7rem'
867
1090
  }
868
1091
  }, /*#__PURE__*/React__default.createElement("div", {
869
1092
  style: {
870
1093
  flex: '0 0 auto',
871
- width: '1.3rem',
872
- height: '1.3rem',
1094
+ width: '.75rem',
1095
+ height: '.75rem',
873
1096
  marginLeft: '.25rem',
874
1097
  background: getStatusColor(match, defaultTheme),
875
1098
  alignItems: 'center',
876
1099
  justifyContent: 'center',
877
1100
  fontWeight: 'bold',
878
- borderRadius: '.25rem',
879
- transition: 'all .2s ease-out'
1101
+ borderRadius: '100%',
1102
+ transition: 'all 1s ease-out'
880
1103
  }
881
1104
  }), /*#__PURE__*/React__default.createElement(Code, {
882
1105
  style: {
883
1106
  padding: '.5em'
884
1107
  }
885
- }, `${match.id}`));
886
- })) : null), activeMatch ? /*#__PURE__*/React__default.createElement(ActivePanel, null, /*#__PURE__*/React__default.createElement("div", {
1108
+ }, `${match.id}`), /*#__PURE__*/React__default.createElement("div", {
1109
+ style: {
1110
+ marginLeft: 'auto'
1111
+ }
1112
+ }, /*#__PURE__*/React__default.createElement(AgeTicker, {
1113
+ match: match
1114
+ })));
1115
+ }))) : null), activeMatch ? /*#__PURE__*/React__default.createElement(ActivePanel, null, /*#__PURE__*/React__default.createElement("div", {
887
1116
  style: {
888
1117
  padding: '.5em',
889
1118
  background: defaultTheme.backgroundAlt,
@@ -892,7 +1121,11 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
892
1121
  bottom: 0,
893
1122
  zIndex: 1
894
1123
  }
895
- }, "Match Details"), /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("table", null, /*#__PURE__*/React__default.createElement("tbody", null, /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
1124
+ }, "Match Details"), /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("table", {
1125
+ style: {
1126
+ fontSize: '0.8rem'
1127
+ }
1128
+ }, /*#__PURE__*/React__default.createElement("tbody", null, /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
896
1129
  style: {
897
1130
  opacity: '.5'
898
1131
  }
@@ -904,11 +1137,11 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
904
1137
  style: {
905
1138
  opacity: '.5'
906
1139
  }
907
- }, "Status"), /*#__PURE__*/React__default.createElement("td", null, activeMatch.state.status)), /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
1140
+ }, "Status"), /*#__PURE__*/React__default.createElement("td", null, routerState.pendingMatches?.find(d => d.id === activeMatch.id) ? 'Pending' : routerState.matches?.find(d => d.id === activeMatch.id) ? 'Active' : 'Cached', ' ', "- ", activeMatch.status)), /*#__PURE__*/React__default.createElement("tr", null, /*#__PURE__*/React__default.createElement("td", {
908
1141
  style: {
909
1142
  opacity: '.5'
910
1143
  }
911
- }, "Last Updated"), /*#__PURE__*/React__default.createElement("td", null, activeMatch.state.updatedAt ? new Date(activeMatch.state.updatedAt).toLocaleTimeString() : 'N/A'))))), /*#__PURE__*/React__default.createElement("div", {
1144
+ }, "Last Updated"), /*#__PURE__*/React__default.createElement("td", null, activeMatch.updatedAt ? new Date(activeMatch.updatedAt).toLocaleTimeString() : 'N/A'))))), activeMatch.loaderData ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
912
1145
  style: {
913
1146
  background: defaultTheme.backgroundAlt,
914
1147
  padding: '.5em',
@@ -917,17 +1150,15 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
917
1150
  bottom: 0,
918
1151
  zIndex: 1
919
1152
  }
920
- }, "Actions"), /*#__PURE__*/React__default.createElement("div", {
921
- style: {
922
- padding: '0.5em'
923
- }
924
- }, /*#__PURE__*/React__default.createElement(Button, {
925
- type: "button",
926
- onClick: () => activeMatch.load(),
1153
+ }, "Loader Data"), /*#__PURE__*/React__default.createElement("div", {
927
1154
  style: {
928
- background: defaultTheme.gray
1155
+ padding: '.5em'
929
1156
  }
930
- }, "Reload")), /*#__PURE__*/React__default.createElement("div", {
1157
+ }, /*#__PURE__*/React__default.createElement(Explorer, {
1158
+ label: "loaderData",
1159
+ value: activeMatch.loaderData,
1160
+ defaultExpanded: {}
1161
+ }))) : null, /*#__PURE__*/React__default.createElement("div", {
931
1162
  style: {
932
1163
  background: defaultTheme.backgroundAlt,
933
1164
  padding: '.5em',
@@ -944,7 +1175,7 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
944
1175
  label: "Match",
945
1176
  value: activeMatch,
946
1177
  defaultExpanded: {}
947
- }))) : null, /*#__PURE__*/React__default.createElement("div", {
1178
+ }))) : null, hasSearch ? /*#__PURE__*/React__default.createElement("div", {
948
1179
  style: {
949
1180
  flex: '1 1 500px',
950
1181
  minHeight: '40%',
@@ -961,24 +1192,70 @@ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default.forwardRef(funct
961
1192
  position: 'sticky',
962
1193
  top: 0,
963
1194
  bottom: 0,
964
- zIndex: 1
1195
+ zIndex: 1,
1196
+ fontWeight: 'bold'
965
1197
  }
966
1198
  }, "Search Params"), /*#__PURE__*/React__default.createElement("div", {
967
1199
  style: {
968
1200
  padding: '.5em'
969
1201
  }
970
- }, Object.keys(last(router.state.currentMatches)?.state.search || {}).length ? /*#__PURE__*/React__default.createElement(Explorer, {
971
- value: last(router.state.currentMatches)?.state.search || {},
972
- defaultExpanded: Object.keys(last(router.state.currentMatches)?.state.search || {}).reduce((obj, next) => {
1202
+ }, /*#__PURE__*/React__default.createElement(Explorer, {
1203
+ value: routerState.location.search || {},
1204
+ defaultExpanded: Object.keys(routerState.location.search || {}).reduce((obj, next) => {
973
1205
  obj[next] = {};
974
1206
  return obj;
975
1207
  }, {})
976
- }) : /*#__PURE__*/React__default.createElement("em", {
1208
+ }))) : null));
1209
+ });
1210
+ function AgeTicker({
1211
+ match
1212
+ }) {
1213
+ const router = useRouter();
1214
+ const rerender = React__default.useReducer(() => ({}), () => ({}))[1];
1215
+ React__default.useEffect(() => {
1216
+ const interval = setInterval(() => {
1217
+ rerender();
1218
+ }, 1000);
1219
+ return () => {
1220
+ clearInterval(interval);
1221
+ };
1222
+ }, []);
1223
+ if (!match) {
1224
+ return null;
1225
+ }
1226
+ const route = router.looseRoutesById[match?.routeId];
1227
+ if (!route.options.loader) {
1228
+ return null;
1229
+ }
1230
+ const age = Date.now() - match?.updatedAt;
1231
+ const staleTime = route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
1232
+ const gcTime = route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1000;
1233
+ return /*#__PURE__*/React__default.createElement("div", {
977
1234
  style: {
978
- opacity: 0.5
1235
+ display: 'inline-flex',
1236
+ alignItems: 'center',
1237
+ gap: '.25rem',
1238
+ color: age > staleTime ? defaultTheme.warning : undefined
979
1239
  }
980
- }, '{ }')))));
981
- });
1240
+ }, /*#__PURE__*/React__default.createElement("div", {
1241
+ style: {}
1242
+ }, formatTime(age)), /*#__PURE__*/React__default.createElement("div", null, "/"), /*#__PURE__*/React__default.createElement("div", null, formatTime(staleTime)), /*#__PURE__*/React__default.createElement("div", null, "/"), /*#__PURE__*/React__default.createElement("div", null, formatTime(gcTime)));
1243
+ }
1244
+ function formatTime(ms) {
1245
+ const units = ['s', 'min', 'h', 'd'];
1246
+ const values = [ms / 1000, ms / 60000, ms / 3600000, ms / 86400000];
1247
+ let chosenUnitIndex = 0;
1248
+ for (let i = 1; i < values.length; i++) {
1249
+ if (values[i] < 1) break;
1250
+ chosenUnitIndex = i;
1251
+ }
1252
+ const formatter = new Intl.NumberFormat(navigator.language, {
1253
+ compactDisplay: 'short',
1254
+ notation: 'compact',
1255
+ maximumFractionDigits: 0
1256
+ });
1257
+ return formatter.format(values[chosenUnitIndex]) + units[chosenUnitIndex];
1258
+ }
982
1259
 
983
1260
  export { TanStackRouterDevtools, TanStackRouterDevtoolsPanel };
984
1261
  //# sourceMappingURL=index.js.map