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

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 (38) 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/index.d.ts +77 -1
  27. package/build/types/styledComponents.d.ts +3 -3
  28. package/build/types/theme.d.ts +13 -13
  29. package/build/types/utils.d.ts +3 -2
  30. package/build/umd/index.development.js +662 -145
  31. package/build/umd/index.development.js.map +1 -1
  32. package/build/umd/index.production.js +4 -14
  33. package/build/umd/index.production.js.map +1 -1
  34. package/package.json +2 -3
  35. package/src/Explorer.tsx +5 -0
  36. package/src/devtools.tsx +574 -287
  37. package/src/theme.tsx +6 -6
  38. 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
  *
@@ -9,15 +9,12 @@
9
9
  * @license MIT
10
10
  */
11
11
  (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('use-sync-external-store/shim/with-selector')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-sync-external-store/shim/with-selector'], factory) :
14
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TanStackRouterDevtools = {}, global.React, global.withSelector));
15
- })(this, (function (exports, React, withSelector) { 'use strict';
12
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('use-sync-external-store/shim')) :
13
+ typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-sync-external-store/shim'], factory) :
14
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TanStackRouterDevtools = {}, global.React, global.require$$1));
15
+ })(this, (function (exports, React, require$$1) { 'use strict';
16
16
 
17
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
-
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
17
+ function _interopNamespaceDefault(e) {
21
18
  var n = Object.create(null);
22
19
  if (e) {
23
20
  Object.keys(e).forEach(function (k) {
@@ -30,12 +27,11 @@
30
27
  }
31
28
  });
32
29
  }
33
- n["default"] = e;
30
+ n.default = e;
34
31
  return Object.freeze(n);
35
32
  }
36
33
 
37
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
34
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
39
35
 
40
36
  function _extends() {
41
37
  _extends = Object.assign ? Object.assign.bind() : function (target) {
@@ -52,36 +48,235 @@
52
48
  return _extends.apply(this, arguments);
53
49
  }
54
50
 
51
+ var isProduction$1 = "development" === 'production';
55
52
  var prefix = 'Invariant failed';
56
53
  function invariant(condition, message) {
57
54
  if (condition) {
58
55
  return;
59
56
  }
57
+ if (isProduction$1) {
58
+ throw new Error(prefix);
59
+ }
60
60
  var provided = typeof message === 'function' ? message() : message;
61
61
  var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
62
62
  throw new Error(value);
63
63
  }
64
64
 
65
+ var isProduction = "development" === 'production';
66
+ function warning(condition, message) {
67
+ if (!isProduction) {
68
+ if (condition) {
69
+ return;
70
+ }
71
+
72
+ var text = "Warning: " + message;
73
+
74
+ if (typeof console !== 'undefined') {
75
+ console.warn(text);
76
+ }
77
+
78
+ try {
79
+ throw Error(text);
80
+ } catch (x) {}
81
+ }
82
+ }
83
+
84
+ var withSelector = {exports: {}};
85
+
86
+ var withSelector_development = {};
87
+
65
88
  /**
66
- * react-store
89
+ * @license React
90
+ * use-sync-external-store-shim/with-selector.development.js
67
91
  *
68
- * Copyright (c) TanStack
92
+ * Copyright (c) Facebook, Inc. and its affiliates.
69
93
  *
70
94
  * This source code is licensed under the MIT license found in the
71
- * LICENSE.md file in the root directory of this source tree.
72
- *
73
- * @license MIT
95
+ * LICENSE file in the root directory of this source tree.
74
96
  */
75
97
 
76
- function useStore(store, selector = d => d) {
77
- const slice = withSelector.useSyncExternalStoreWithSelector(store.subscribe, () => store.state, () => store.state, selector, shallow);
98
+ var hasRequiredWithSelector_development;
99
+
100
+ function requireWithSelector_development () {
101
+ if (hasRequiredWithSelector_development) return withSelector_development;
102
+ hasRequiredWithSelector_development = 1;
103
+
104
+ {
105
+ (function() {
106
+
107
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
108
+ if (
109
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
110
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
111
+ 'function'
112
+ ) {
113
+ __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
114
+ }
115
+ var React$1 = React;
116
+ var shim = require$$1;
117
+
118
+ /**
119
+ * inlined Object.is polyfill to avoid requiring consumers ship their own
120
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
121
+ */
122
+ function is(x, y) {
123
+ return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
124
+ ;
125
+ }
126
+
127
+ var objectIs = typeof Object.is === 'function' ? Object.is : is;
128
+
129
+ var useSyncExternalStore = shim.useSyncExternalStore;
130
+
131
+ // for CommonJS interop.
132
+
133
+ var useRef = React$1.useRef,
134
+ useEffect = React$1.useEffect,
135
+ useMemo = React$1.useMemo,
136
+ useDebugValue = React$1.useDebugValue; // Same as useSyncExternalStore, but supports selector and isEqual arguments.
137
+
138
+ function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
139
+ // Use this to track the rendered snapshot.
140
+ var instRef = useRef(null);
141
+ var inst;
142
+
143
+ if (instRef.current === null) {
144
+ inst = {
145
+ hasValue: false,
146
+ value: null
147
+ };
148
+ instRef.current = inst;
149
+ } else {
150
+ inst = instRef.current;
151
+ }
152
+
153
+ var _useMemo = useMemo(function () {
154
+ // Track the memoized state using closure variables that are local to this
155
+ // memoized instance of a getSnapshot function. Intentionally not using a
156
+ // useRef hook, because that state would be shared across all concurrent
157
+ // copies of the hook/component.
158
+ var hasMemo = false;
159
+ var memoizedSnapshot;
160
+ var memoizedSelection;
161
+
162
+ var memoizedSelector = function (nextSnapshot) {
163
+ if (!hasMemo) {
164
+ // The first time the hook is called, there is no memoized result.
165
+ hasMemo = true;
166
+ memoizedSnapshot = nextSnapshot;
167
+
168
+ var _nextSelection = selector(nextSnapshot);
169
+
170
+ if (isEqual !== undefined) {
171
+ // Even if the selector has changed, the currently rendered selection
172
+ // may be equal to the new selection. We should attempt to reuse the
173
+ // current value if possible, to preserve downstream memoizations.
174
+ if (inst.hasValue) {
175
+ var currentSelection = inst.value;
176
+
177
+ if (isEqual(currentSelection, _nextSelection)) {
178
+ memoizedSelection = currentSelection;
179
+ return currentSelection;
180
+ }
181
+ }
182
+ }
183
+
184
+ memoizedSelection = _nextSelection;
185
+ return _nextSelection;
186
+ } // We may be able to reuse the previous invocation's result.
187
+
188
+
189
+ // We may be able to reuse the previous invocation's result.
190
+ var prevSnapshot = memoizedSnapshot;
191
+ var prevSelection = memoizedSelection;
192
+
193
+ if (objectIs(prevSnapshot, nextSnapshot)) {
194
+ // The snapshot is the same as last time. Reuse the previous selection.
195
+ return prevSelection;
196
+ } // The snapshot has changed, so we need to compute a new selection.
197
+
198
+
199
+ // The snapshot has changed, so we need to compute a new selection.
200
+ var nextSelection = selector(nextSnapshot); // If a custom isEqual function is provided, use that to check if the data
201
+ // has changed. If it hasn't, return the previous selection. That signals
202
+ // to React that the selections are conceptually equal, and we can bail
203
+ // out of rendering.
204
+
205
+ // If a custom isEqual function is provided, use that to check if the data
206
+ // has changed. If it hasn't, return the previous selection. That signals
207
+ // to React that the selections are conceptually equal, and we can bail
208
+ // out of rendering.
209
+ if (isEqual !== undefined && isEqual(prevSelection, nextSelection)) {
210
+ return prevSelection;
211
+ }
212
+
213
+ memoizedSnapshot = nextSnapshot;
214
+ memoizedSelection = nextSelection;
215
+ return nextSelection;
216
+ }; // Assigning this to a constant so that Flow knows it can't change.
217
+
218
+
219
+ // Assigning this to a constant so that Flow knows it can't change.
220
+ var maybeGetServerSnapshot = getServerSnapshot === undefined ? null : getServerSnapshot;
221
+
222
+ var getSnapshotWithSelector = function () {
223
+ return memoizedSelector(getSnapshot());
224
+ };
225
+
226
+ var getServerSnapshotWithSelector = maybeGetServerSnapshot === null ? undefined : function () {
227
+ return memoizedSelector(maybeGetServerSnapshot());
228
+ };
229
+ return [getSnapshotWithSelector, getServerSnapshotWithSelector];
230
+ }, [getSnapshot, getServerSnapshot, selector, isEqual]),
231
+ getSelection = _useMemo[0],
232
+ getServerSelection = _useMemo[1];
233
+
234
+ var value = useSyncExternalStore(subscribe, getSelection, getServerSelection);
235
+ useEffect(function () {
236
+ inst.hasValue = true;
237
+ inst.value = value;
238
+ }, [value]);
239
+ useDebugValue(value);
240
+ return value;
241
+ }
242
+
243
+ withSelector_development.useSyncExternalStoreWithSelector = useSyncExternalStoreWithSelector;
244
+ /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
245
+ if (
246
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
247
+ typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
248
+ 'function'
249
+ ) {
250
+ __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
251
+ }
252
+
253
+ })();
254
+ }
255
+ return withSelector_development;
256
+ }
257
+
258
+ {
259
+ withSelector.exports = requireWithSelector_development();
260
+ }
261
+
262
+ var withSelectorExports = withSelector.exports;
263
+
264
+ // src/index.ts
265
+ function useStore(store, selector = (d) => d) {
266
+ const slice = withSelectorExports.useSyncExternalStoreWithSelector(
267
+ store.subscribe,
268
+ () => store.state,
269
+ () => store.state,
270
+ selector,
271
+ shallow
272
+ );
78
273
  return slice;
79
274
  }
80
275
  function shallow(objA, objB) {
81
276
  if (Object.is(objA, objB)) {
82
277
  return true;
83
278
  }
84
- if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
279
+ if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
85
280
  return false;
86
281
  }
87
282
  const keysA = Object.keys(objA);
@@ -97,7 +292,7 @@
97
292
  }
98
293
 
99
294
  /**
100
- * router
295
+ * @tanstack/react-router/src/index.tsx
101
296
  *
102
297
  * Copyright (c) TanStack
103
298
  *
@@ -106,11 +301,58 @@
106
301
  *
107
302
  * @license MIT
108
303
  */
304
+ function isFunction(d) {
305
+ return typeof d === 'function';
306
+ }
307
+ function functionalUpdate(updater, previous) {
308
+ if (isFunction(updater)) {
309
+ return updater(previous);
310
+ }
311
+ return updater;
312
+ }
109
313
 
110
- function last(arr) {
111
- return arr[arr.length - 1];
314
+ let routerContext = /*#__PURE__*/React__namespace.createContext(null);
315
+ if (typeof document !== 'undefined') {
316
+ if (window.__TSR_ROUTER_CONTEXT__) {
317
+ routerContext = window.__TSR_ROUTER_CONTEXT__;
318
+ } else {
319
+ window.__TSR_ROUTER_CONTEXT__ = routerContext;
320
+ }
321
+ }
322
+ function useRouterState(opts) {
323
+ const router = useRouter();
324
+ return useStore(router.__store, opts?.select);
325
+ }
326
+ function useRouter() {
327
+ const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
328
+ const value = React__namespace.useContext(resolvedContext);
329
+ warning(value, 'useRouter must be used inside a <RouterProvider> component!');
330
+ return value;
331
+ }
332
+ function trimPathLeft(path) {
333
+ return path === '/' ? path : path.replace(/^\/{1,}/, '');
334
+ }
335
+ function trimPathRight(path) {
336
+ return path === '/' ? path : path.replace(/\/{1,}$/, '');
112
337
  }
113
- const routerContext = /*#__PURE__*/React__namespace.createContext(null);
338
+ function trimPath(path) {
339
+ return trimPathRight(trimPathLeft(path));
340
+ }
341
+ const sessionsStorage = typeof window !== 'undefined' && window.sessionStorage;
342
+ let cache = sessionsStorage ? (() => {
343
+ const storageKey = 'tsr-scroll-restoration-v2';
344
+ const state = JSON.parse(window.sessionStorage.getItem(storageKey) || 'null') || {
345
+ cached: {},
346
+ next: {}
347
+ };
348
+ return {
349
+ state,
350
+ set: updater => {
351
+ cache.state = functionalUpdate(updater, cache.state);
352
+ window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state));
353
+ }
354
+ };
355
+ })() : undefined;
114
356
 
115
357
  const getItem = key => {
116
358
  try {
@@ -124,8 +366,8 @@
124
366
  }
125
367
  };
126
368
  function useLocalStorage(key, defaultValue) {
127
- const [value, setValue] = React__default["default"].useState();
128
- React__default["default"].useEffect(() => {
369
+ const [value, setValue] = React.useState();
370
+ React.useEffect(() => {
129
371
  const initialValue = getItem(key);
130
372
  if (typeof initialValue === 'undefined' || initialValue === null) {
131
373
  setValue(typeof defaultValue === 'function' ? defaultValue() : defaultValue);
@@ -133,7 +375,7 @@
133
375
  setValue(initialValue);
134
376
  }
135
377
  }, [defaultValue, key]);
136
- const setter = React__default["default"].useCallback(updater => {
378
+ const setter = React.useCallback(updater => {
137
379
  setValue(old => {
138
380
  let newVal = updater;
139
381
  if (typeof updater == 'function') {
@@ -149,34 +391,34 @@
149
391
  }
150
392
 
151
393
  const defaultTheme = {
152
- background: '#0b1521',
153
- backgroundAlt: '#132337',
394
+ background: '#222222',
395
+ backgroundAlt: '#292929',
154
396
  foreground: 'white',
155
- gray: '#3f4e60',
156
- grayAlt: '#222e3e',
397
+ gray: '#444',
398
+ grayAlt: '#444',
157
399
  inputBackgroundColor: '#fff',
158
400
  inputTextColor: '#000',
159
- success: '#00ab52',
401
+ success: '#80cb00',
160
402
  danger: '#ff0085',
161
- active: '#006bff',
403
+ active: '#0099ff',
162
404
  warning: '#ffb200'
163
405
  };
164
- const ThemeContext = /*#__PURE__*/React__default["default"].createContext(defaultTheme);
406
+ const ThemeContext = /*#__PURE__*/React.createContext(defaultTheme);
165
407
  function ThemeProvider({
166
408
  theme,
167
409
  ...rest
168
410
  }) {
169
- return /*#__PURE__*/React__default["default"].createElement(ThemeContext.Provider, _extends({
411
+ return /*#__PURE__*/React.createElement(ThemeContext.Provider, _extends({
170
412
  value: theme
171
413
  }, rest));
172
414
  }
173
415
  function useTheme() {
174
- return React__default["default"].useContext(ThemeContext);
416
+ return React.useContext(ThemeContext);
175
417
  }
176
418
 
177
419
  function useMediaQuery(query) {
178
420
  // Keep track of the preference in state, start with the current match
179
- const [isMatch, setIsMatch] = React__default["default"].useState(() => {
421
+ const [isMatch, setIsMatch] = React.useState(() => {
180
422
  if (typeof window !== 'undefined') {
181
423
  return window.matchMedia && window.matchMedia(query).matches;
182
424
  }
@@ -184,7 +426,7 @@
184
426
  });
185
427
 
186
428
  // Watch for changes
187
- React__default["default"].useEffect(() => {
429
+ React.useEffect(() => {
188
430
  if (typeof window !== 'undefined') {
189
431
  if (!window.matchMedia) {
190
432
  return;
@@ -212,10 +454,15 @@
212
454
 
213
455
  const isServer$1 = typeof window === 'undefined';
214
456
  function getStatusColor(match, theme) {
215
- return match.state.status === 'pending' ? theme.active : match.state.status === 'error' ? theme.danger : match.state.status === 'success' ? theme.success : theme.gray;
457
+ return match.status === 'pending' || match.isFetching ? theme.active : match.status === 'error' ? theme.danger : match.status === 'success' ? theme.success : theme.gray;
458
+ }
459
+ function getRouteStatusColor(matches, route, theme) {
460
+ const found = matches.find(d => d.routeId === route.id);
461
+ if (!found) return theme.gray;
462
+ return getStatusColor(found, theme);
216
463
  }
217
464
  function styled(type, newStyles, queries = {}) {
218
- return /*#__PURE__*/React__default["default"].forwardRef(({
465
+ return /*#__PURE__*/React.forwardRef(({
219
466
  style,
220
467
  ...rest
221
468
  }, ref) => {
@@ -227,7 +474,7 @@
227
474
  ...(typeof value === 'function' ? value(rest, theme) : value)
228
475
  } : current;
229
476
  }, {});
230
- return /*#__PURE__*/React__default["default"].createElement(type, {
477
+ return /*#__PURE__*/React.createElement(type, {
231
478
  ...rest,
232
479
  style: {
233
480
  ...(typeof newStyles === 'function' ? newStyles(rest, theme) : newStyles),
@@ -239,9 +486,9 @@
239
486
  });
240
487
  }
241
488
  function useIsMounted() {
242
- const mountedRef = React__default["default"].useRef(false);
243
- const isMounted = React__default["default"].useCallback(() => mountedRef.current, []);
244
- React__default["default"][isServer$1 ? 'useEffect' : 'useLayoutEffect'](() => {
489
+ const mountedRef = React.useRef(false);
490
+ const isMounted = React.useCallback(() => mountedRef.current, []);
491
+ React[isServer$1 ? 'useEffect' : 'useLayoutEffect'](() => {
245
492
  mountedRef.current = true;
246
493
  return () => {
247
494
  mountedRef.current = false;
@@ -267,8 +514,8 @@
267
514
  */
268
515
  function useSafeState(initialState) {
269
516
  const isMounted = useIsMounted();
270
- const [state, setState] = React__default["default"].useState(initialState);
271
- const safeSetState = React__default["default"].useCallback(value => {
517
+ const [state, setState] = React.useState(initialState);
518
+ const safeSetState = React.useCallback(value => {
272
519
  scheduleMicrotask(() => {
273
520
  if (isMounted()) {
274
521
  setState(value);
@@ -287,6 +534,25 @@
287
534
  throw error;
288
535
  }));
289
536
  }
537
+ function multiSortBy(arr, accessors = [d => d]) {
538
+ return arr.map((d, i) => [d, i]).sort(([a, ai], [b, bi]) => {
539
+ for (const accessor of accessors) {
540
+ const ao = accessor(a);
541
+ const bo = accessor(b);
542
+ if (typeof ao === 'undefined') {
543
+ if (typeof bo === 'undefined') {
544
+ continue;
545
+ }
546
+ return 1;
547
+ }
548
+ if (ao === bo) {
549
+ continue;
550
+ }
551
+ return ao > bo ? 1 : -1;
552
+ }
553
+ return ai - bi;
554
+ }).map(([d]) => d);
555
+ }
290
556
 
291
557
  const Panel = styled('div', (_props, theme) => ({
292
558
  fontSize: 'clamp(12px, 1.5vw, 14px)',
@@ -303,7 +569,6 @@
303
569
  // flexDirection: 'column',
304
570
  }
305
571
  });
306
-
307
572
  const ActivePanel = styled('div', () => ({
308
573
  flex: '1 1 500px',
309
574
  display: 'flex',
@@ -460,6 +725,7 @@
460
725
  defaultExpanded,
461
726
  renderer = DefaultRenderer,
462
727
  pageSize = 100,
728
+ filterSubEntries,
463
729
  ...rest
464
730
  }) {
465
731
  const [expanded, setExpanded] = React__namespace.useState(Boolean(defaultExpanded));
@@ -494,12 +760,14 @@
494
760
  value: val
495
761
  }));
496
762
  }
763
+ subEntries = filterSubEntries ? filterSubEntries(subEntries) : subEntries;
497
764
  const subEntryPages = chunkArray(subEntries, pageSize);
498
765
  return renderer({
499
766
  handleEntry: entry => /*#__PURE__*/React__namespace.createElement(Explorer, _extends({
500
767
  key: entry.label,
501
768
  value: value,
502
- renderer: renderer
769
+ renderer: renderer,
770
+ filterSubEntries: filterSubEntries
503
771
  }, rest, entry)),
504
772
  type,
505
773
  subEntries,
@@ -514,7 +782,7 @@
514
782
 
515
783
  const isServer = typeof window === 'undefined';
516
784
  function Logo(props) {
517
- return /*#__PURE__*/React__default["default"].createElement("div", _extends({}, props, {
785
+ return /*#__PURE__*/React.createElement("div", _extends({}, props, {
518
786
  style: {
519
787
  ...(props.style ?? {}),
520
788
  display: 'flex',
@@ -524,11 +792,11 @@
524
792
  fontWeight: 'bolder',
525
793
  lineHeight: '1'
526
794
  }
527
- }), /*#__PURE__*/React__default["default"].createElement("div", {
795
+ }), /*#__PURE__*/React.createElement("div", {
528
796
  style: {
529
797
  letterSpacing: '-0.05rem'
530
798
  }
531
- }, "TANSTACK"), /*#__PURE__*/React__default["default"].createElement("div", {
799
+ }, "TANSTACK"), /*#__PURE__*/React.createElement("div", {
532
800
  style: {
533
801
  backgroundImage: 'linear-gradient(to right, var(--tw-gradient-stops))',
534
802
  // @ts-ignore
@@ -551,8 +819,8 @@
551
819
  containerElement: Container = 'footer',
552
820
  router
553
821
  }) {
554
- const rootRef = React__default["default"].useRef(null);
555
- const panelRef = React__default["default"].useRef(null);
822
+ const rootRef = React.useRef(null);
823
+ const panelRef = React.useRef(null);
556
824
  const [isOpen, setIsOpen] = useLocalStorage('tanstackRouterDevtoolsOpen', initialIsOpen);
557
825
  const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage('tanstackRouterDevtoolsHeight', null);
558
826
  const [isResolvedOpen, setIsResolvedOpen] = useSafeState(false);
@@ -584,13 +852,13 @@
584
852
  document.addEventListener('mousemove', run);
585
853
  document.addEventListener('mouseup', unsub);
586
854
  };
587
- React__default["default"].useEffect(() => {
855
+ React.useEffect(() => {
588
856
  setIsResolvedOpen(isOpen ?? false);
589
857
  }, [isOpen, isResolvedOpen, setIsResolvedOpen]);
590
858
 
591
859
  // Toggle panel visibility before/after transition (depending on direction).
592
860
  // Prevents focusing in a closed panel.
593
- React__default["default"].useEffect(() => {
861
+ React.useEffect(() => {
594
862
  const ref = panelRef.current;
595
863
  if (ref) {
596
864
  const handlePanelTransitionStart = () => {
@@ -612,7 +880,7 @@
612
880
  }
613
881
  return;
614
882
  }, [isResolvedOpen]);
615
- React__default["default"][isServer ? 'useEffect' : 'useLayoutEffect'](() => {
883
+ React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
616
884
  if (isResolvedOpen) {
617
885
  const previousValue = rootRef.current?.parentElement?.style.paddingBottom;
618
886
  const run = () => {
@@ -651,12 +919,12 @@
651
919
 
652
920
  // Do not render on the server
653
921
  if (!isMounted()) return null;
654
- return /*#__PURE__*/React__default["default"].createElement(Container, {
922
+ return /*#__PURE__*/React.createElement(Container, {
655
923
  ref: rootRef,
656
924
  className: "TanStackRouterDevtools"
657
- }, /*#__PURE__*/React__default["default"].createElement(ThemeProvider, {
925
+ }, /*#__PURE__*/React.createElement(ThemeProvider, {
658
926
  theme: defaultTheme
659
- }, /*#__PURE__*/React__default["default"].createElement(TanStackRouterDevtoolsPanel, _extends({
927
+ }, /*#__PURE__*/React.createElement(TanStackRouterDevtoolsPanel, _extends({
660
928
  ref: panelRef
661
929
  }, otherPanelProps, {
662
930
  router: router,
@@ -692,7 +960,7 @@
692
960
  isOpen: isResolvedOpen,
693
961
  setIsOpen: setIsOpen,
694
962
  handleDragStart: e => handleDragStart(panelRef.current, e)
695
- })), isResolvedOpen ? /*#__PURE__*/React__default["default"].createElement(Button, _extends({
963
+ })), isResolvedOpen ? /*#__PURE__*/React.createElement(Button, _extends({
696
964
  type: "button",
697
965
  "aria-label": "Close TanStack Router Devtools"
698
966
  }, otherCloseButtonProps, {
@@ -716,7 +984,7 @@
716
984
  }),
717
985
  ...closeButtonStyle
718
986
  }
719
- }), "Close") : null), !isResolvedOpen ? /*#__PURE__*/React__default["default"].createElement("button", _extends({
987
+ }), "Close") : null), !isResolvedOpen ? /*#__PURE__*/React.createElement("button", _extends({
720
988
  type: "button"
721
989
  }, otherToggleButtonProps, {
722
990
  "aria-label": "Open TanStack Router Devtools",
@@ -751,11 +1019,86 @@
751
1019
  }),
752
1020
  ...toggleButtonStyle
753
1021
  }
754
- }), /*#__PURE__*/React__default["default"].createElement(Logo, {
1022
+ }), /*#__PURE__*/React.createElement(Logo, {
755
1023
  "aria-hidden": true
756
1024
  })) : null);
757
1025
  }
758
- const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default["default"].forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
1026
+ function RouteComp({
1027
+ route,
1028
+ isRoot,
1029
+ activeId,
1030
+ setActiveId
1031
+ }) {
1032
+ const routerState = useRouterState();
1033
+ const matches = routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches;
1034
+ const match = routerState.matches.find(d => d.routeId === route.id);
1035
+ return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
1036
+ role: "button",
1037
+ "aria-label": `Open match details for ${route.id}`,
1038
+ onClick: () => {
1039
+ if (match) {
1040
+ setActiveId(activeId === route.id ? '' : route.id);
1041
+ }
1042
+ },
1043
+ style: {
1044
+ display: 'flex',
1045
+ borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
1046
+ cursor: match ? 'pointer' : 'default',
1047
+ alignItems: 'center',
1048
+ background: route.id === activeId ? 'rgba(255,255,255,.1)' : undefined,
1049
+ padding: '.25rem .5rem',
1050
+ gap: '.5rem'
1051
+ }
1052
+ }, isRoot ? null : /*#__PURE__*/React.createElement("div", {
1053
+ style: {
1054
+ flex: '0 0 auto',
1055
+ width: '.7rem',
1056
+ height: '.7rem',
1057
+ alignItems: 'center',
1058
+ justifyContent: 'center',
1059
+ fontWeight: 'bold',
1060
+ borderRadius: '100%',
1061
+ transition: 'all .2s ease-out',
1062
+ background: getRouteStatusColor(matches, route, defaultTheme),
1063
+ opacity: match ? 1 : 0.3
1064
+ }
1065
+ }), /*#__PURE__*/React.createElement("div", {
1066
+ style: {
1067
+ flex: '1 0 auto',
1068
+ display: 'flex',
1069
+ justifyContent: 'space-between',
1070
+ alignItems: 'center',
1071
+ padding: isRoot ? '0 .25rem' : 0,
1072
+ opacity: match ? 1 : 0.7,
1073
+ fontSize: '0.7rem'
1074
+ }
1075
+ }, /*#__PURE__*/React.createElement(Code, null, route.path || trimPath(route.id), " "), /*#__PURE__*/React.createElement("div", {
1076
+ style: {
1077
+ display: 'flex',
1078
+ alignItems: 'center',
1079
+ gap: '.5rem'
1080
+ }
1081
+ }, match ? /*#__PURE__*/React.createElement(Code, {
1082
+ style: {
1083
+ opacity: 0.3
1084
+ }
1085
+ }, match.id) : null, /*#__PURE__*/React.createElement(AgeTicker, {
1086
+ match: match
1087
+ })))), route.children?.length ? /*#__PURE__*/React.createElement("div", {
1088
+ style: {
1089
+ marginLeft: isRoot ? 0 : '1rem',
1090
+ borderLeft: isRoot ? '' : `solid 1px ${defaultTheme.grayAlt}`
1091
+ }
1092
+ }, [...route.children].sort((a, b) => {
1093
+ return a.rank - b.rank;
1094
+ }).map(r => /*#__PURE__*/React.createElement(RouteComp, {
1095
+ key: r.id,
1096
+ route: r,
1097
+ activeId: activeId,
1098
+ setActiveId: setActiveId
1099
+ }))) : null);
1100
+ }
1101
+ const TanStackRouterDevtoolsPanel = /*#__PURE__*/React.forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
759
1102
  const {
760
1103
  isOpen = true,
761
1104
  setIsOpen,
@@ -763,23 +1106,27 @@
763
1106
  router: userRouter,
764
1107
  ...panelProps
765
1108
  } = props;
766
- const routerContextValue = React__default["default"].useContext(routerContext);
767
- const router = userRouter ?? routerContextValue?.router;
1109
+ const router = useRouter();
1110
+ const routerState = useRouterState();
1111
+ const matches = [...(routerState.pendingMatches ?? []), ...routerState.matches, ...routerState.cachedMatches];
768
1112
  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.');
769
- useStore(router.__store);
770
- const [activeRouteId, setActiveRouteId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
771
- const [activeMatchId, setActiveMatchId] = useLocalStorage('tanstackRouterDevtoolsActiveMatchId', '');
772
- React__default["default"].useEffect(() => {
773
- setActiveMatchId('');
774
- }, [activeRouteId]);
775
- const allMatches = React__default["default"].useMemo(() => [...Object.values(router.state.currentMatches), ...Object.values(router.state.pendingMatches ?? [])], [router.state.currentMatches, router.state.pendingMatches]);
776
- const activeMatch = allMatches?.find(d => d.id === activeMatchId) || allMatches?.find(d => d.route.id === activeRouteId);
777
- return /*#__PURE__*/React__default["default"].createElement(ThemeProvider, {
1113
+
1114
+ // useStore(router.__store)
1115
+
1116
+ const [showMatches, setShowMatches] = useLocalStorage('tanstackRouterDevtoolsShowMatches', true);
1117
+ const [activeId, setActiveId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
1118
+ const activeMatch = React.useMemo(() => matches.find(d => d.routeId === activeId || d.id === activeId), [matches, activeId]);
1119
+ const hasSearch = Object.keys(routerState.location.search || {}).length;
1120
+ const explorerState = {
1121
+ ...router,
1122
+ state: router.state
1123
+ };
1124
+ return /*#__PURE__*/React.createElement(ThemeProvider, {
778
1125
  theme: defaultTheme
779
- }, /*#__PURE__*/React__default["default"].createElement(Panel, _extends({
1126
+ }, /*#__PURE__*/React.createElement(Panel, _extends({
780
1127
  ref: ref,
781
1128
  className: "TanStackRouterDevtoolsPanel"
782
- }, panelProps), /*#__PURE__*/React__default["default"].createElement("style", {
1129
+ }, panelProps), /*#__PURE__*/React.createElement("style", {
783
1130
  dangerouslySetInnerHTML: {
784
1131
  __html: `
785
1132
 
@@ -825,7 +1172,7 @@
825
1172
 
826
1173
  `
827
1174
  }
828
- }), /*#__PURE__*/React__default["default"].createElement("div", {
1175
+ }), /*#__PURE__*/React.createElement("div", {
829
1176
  style: {
830
1177
  position: 'absolute',
831
1178
  left: 0,
@@ -837,7 +1184,7 @@
837
1184
  zIndex: 100000
838
1185
  },
839
1186
  onMouseDown: handleDragStart
840
- }), /*#__PURE__*/React__default["default"].createElement("div", {
1187
+ }), /*#__PURE__*/React.createElement("div", {
841
1188
  style: {
842
1189
  flex: '1 1 500px',
843
1190
  minHeight: '40%',
@@ -847,7 +1194,7 @@
847
1194
  display: 'flex',
848
1195
  flexDirection: 'column'
849
1196
  }
850
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1197
+ }, /*#__PURE__*/React.createElement("div", {
851
1198
  style: {
852
1199
  display: 'flex',
853
1200
  justifyContent: 'start',
@@ -856,31 +1203,38 @@
856
1203
  alignItems: 'center',
857
1204
  background: defaultTheme.backgroundAlt
858
1205
  }
859
- }, /*#__PURE__*/React__default["default"].createElement(Logo, {
1206
+ }, /*#__PURE__*/React.createElement(Logo, {
860
1207
  "aria-hidden": true
861
- }), /*#__PURE__*/React__default["default"].createElement("div", {
1208
+ }), /*#__PURE__*/React.createElement("div", {
862
1209
  style: {
863
1210
  fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
864
1211
  fontWeight: 'bold'
865
1212
  }
866
- }, /*#__PURE__*/React__default["default"].createElement("span", {
1213
+ }, /*#__PURE__*/React.createElement("span", {
867
1214
  style: {
868
1215
  fontWeight: 100
869
1216
  }
870
- }, "Devtools"))), /*#__PURE__*/React__default["default"].createElement("div", {
1217
+ }, "Devtools"))), /*#__PURE__*/React.createElement("div", {
871
1218
  style: {
872
1219
  overflowY: 'auto',
873
1220
  flex: '1'
874
1221
  }
875
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1222
+ }, /*#__PURE__*/React.createElement("div", {
876
1223
  style: {
877
1224
  padding: '.5em'
878
1225
  }
879
- }, /*#__PURE__*/React__default["default"].createElement(Explorer, {
1226
+ }, /*#__PURE__*/React.createElement(Explorer, {
880
1227
  label: "Router",
881
- value: router,
882
- defaultExpanded: {}
883
- })))), /*#__PURE__*/React__default["default"].createElement("div", {
1228
+ 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]))),
1229
+ defaultExpanded: {
1230
+ state: {},
1231
+ context: {},
1232
+ options: {}
1233
+ },
1234
+ filterSubEntries: subEntries => {
1235
+ return subEntries.filter(d => typeof d.value !== 'function');
1236
+ }
1237
+ })))), /*#__PURE__*/React.createElement("div", {
884
1238
  style: {
885
1239
  flex: '1 1 500px',
886
1240
  minHeight: '40%',
@@ -890,20 +1244,110 @@
890
1244
  display: 'flex',
891
1245
  flexDirection: 'column'
892
1246
  }
893
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1247
+ }, /*#__PURE__*/React.createElement("div", {
1248
+ style: {
1249
+ flex: '1 1 auto',
1250
+ overflowY: 'auto'
1251
+ }
1252
+ }, /*#__PURE__*/React.createElement("div", {
894
1253
  style: {
895
1254
  padding: '.5em',
896
1255
  background: defaultTheme.backgroundAlt,
897
1256
  position: 'sticky',
898
1257
  top: 0,
899
- zIndex: 1
1258
+ zIndex: 1,
1259
+ display: 'flex',
1260
+ alignItems: 'center',
1261
+ gap: '.5rem',
1262
+ fontWeight: 'bold'
1263
+ }
1264
+ }, "Pathname", ' ', routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("div", {
1265
+ style: {
1266
+ padding: '.1rem .5rem',
1267
+ background: defaultTheme.warning,
1268
+ color: 'black',
1269
+ borderRadius: '.5rem'
1270
+ }
1271
+ }, "Masked") : null), /*#__PURE__*/React.createElement("div", {
1272
+ style: {
1273
+ padding: '.5rem',
1274
+ display: 'flex',
1275
+ gap: '.5rem',
1276
+ alignItems: 'center'
1277
+ }
1278
+ }, /*#__PURE__*/React.createElement("code", {
1279
+ style: {
1280
+ opacity: 0.6
1281
+ }
1282
+ }, routerState.location.pathname), routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("code", {
1283
+ style: {
1284
+ color: defaultTheme.warning,
1285
+ fontWeight: 'bold'
1286
+ }
1287
+ }, routerState.location.maskedLocation.pathname) : null), /*#__PURE__*/React.createElement("div", {
1288
+ style: {
1289
+ padding: '.5em',
1290
+ background: defaultTheme.backgroundAlt,
1291
+ position: 'sticky',
1292
+ top: 0,
1293
+ zIndex: 1,
1294
+ display: 'flex',
1295
+ alignItems: 'center',
1296
+ justifyContent: 'space-between',
1297
+ gap: '.5rem',
1298
+ fontWeight: 'bold'
1299
+ }
1300
+ }, /*#__PURE__*/React.createElement("div", {
1301
+ style: {
1302
+ display: 'flex',
1303
+ alignItems: 'center',
1304
+ gap: '.5rem'
1305
+ }
1306
+ }, /*#__PURE__*/React.createElement("button", {
1307
+ type: "button",
1308
+ onClick: () => {
1309
+ setShowMatches(false);
1310
+ },
1311
+ disabled: !showMatches,
1312
+ style: {
1313
+ appearance: 'none',
1314
+ opacity: showMatches ? 0.5 : 1,
1315
+ border: 0,
1316
+ background: 'transparent',
1317
+ color: 'inherit',
1318
+ cursor: 'pointer'
1319
+ }
1320
+ }, "Routes"), "/", /*#__PURE__*/React.createElement("button", {
1321
+ type: "button",
1322
+ onClick: () => {
1323
+ setShowMatches(true);
1324
+ },
1325
+ disabled: showMatches,
1326
+ style: {
1327
+ appearance: 'none',
1328
+ opacity: !showMatches ? 0.5 : 1,
1329
+ border: 0,
1330
+ background: 'transparent',
1331
+ color: 'inherit',
1332
+ cursor: 'pointer'
1333
+ }
1334
+ }, "Matches")), /*#__PURE__*/React.createElement("div", {
1335
+ style: {
1336
+ opacity: 0.3,
1337
+ fontSize: '0.7rem',
1338
+ fontWeight: 'normal'
900
1339
  }
901
- }, "Active Matches"), router.state.currentMatches.map((match, i) => {
902
- return /*#__PURE__*/React__default["default"].createElement("div", {
903
- key: match.route.id || i,
1340
+ }, "age / staleTime / gcTime")), !showMatches ? /*#__PURE__*/React.createElement(RouteComp, {
1341
+ route: router.routeTree,
1342
+ isRoot: true,
1343
+ activeId: activeId,
1344
+ setActiveId: setActiveId
1345
+ }) : /*#__PURE__*/React.createElement("div", null, (routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches).map((match, i) => {
1346
+ return /*#__PURE__*/React.createElement("div", {
1347
+ key: match.id || i,
904
1348
  role: "button",
905
- "aria-label": `Open match details for ${match.route.id}`,
906
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
1349
+ "aria-label": `Open match details for ${match.id}`,
1350
+ onClick: () => setActiveId(activeId === match.id ? '' : match.id),
907
1351
  style: {
908
1352
  display: 'flex',
909
1353
  borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
@@ -911,7 +1355,7 @@
911
1355
  alignItems: 'center',
912
1356
  background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
913
1357
  }
914
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1358
+ }, /*#__PURE__*/React.createElement("div", {
915
1359
  style: {
916
1360
  flex: '0 0 auto',
917
1361
  width: '1.3rem',
@@ -924,51 +1368,78 @@
924
1368
  borderRadius: '.25rem',
925
1369
  transition: 'all .2s ease-out'
926
1370
  }
927
- }), /*#__PURE__*/React__default["default"].createElement(Code, {
1371
+ }), /*#__PURE__*/React.createElement(Code, {
928
1372
  style: {
929
- padding: '.5em'
1373
+ padding: '.5em',
1374
+ fontSize: '0.7rem'
930
1375
  }
931
- }, `${match.id}`));
932
- }), router.state.pendingMatches?.length ? /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
1376
+ }, `${match.id}`), /*#__PURE__*/React.createElement(AgeTicker, {
1377
+ match: match
1378
+ }));
1379
+ }))), routerState.cachedMatches?.length ? /*#__PURE__*/React.createElement("div", {
1380
+ style: {
1381
+ flex: '1 1 auto',
1382
+ overflowY: 'auto',
1383
+ maxHeight: '50%'
1384
+ }
1385
+ }, /*#__PURE__*/React.createElement("div", {
933
1386
  style: {
934
- marginTop: '2rem',
935
1387
  padding: '.5em',
936
1388
  background: defaultTheme.backgroundAlt,
937
1389
  position: 'sticky',
938
1390
  top: 0,
939
- zIndex: 1
1391
+ zIndex: 1,
1392
+ display: 'flex',
1393
+ alignItems: 'center',
1394
+ justifyContent: 'space-between',
1395
+ gap: '.5rem',
1396
+ fontWeight: 'bold'
940
1397
  }
941
- }, "Pending Matches"), router.state.pendingMatches?.map((match, i) => {
942
- return /*#__PURE__*/React__default["default"].createElement("div", {
943
- key: match.route.id || i,
1398
+ }, /*#__PURE__*/React.createElement("div", null, "Cached Matches"), /*#__PURE__*/React.createElement("div", {
1399
+ style: {
1400
+ opacity: 0.3,
1401
+ fontSize: '0.7rem',
1402
+ fontWeight: 'normal'
1403
+ }
1404
+ }, "age / staleTime / gcTime")), /*#__PURE__*/React.createElement("div", null, routerState.cachedMatches.map(match => {
1405
+ return /*#__PURE__*/React.createElement("div", {
1406
+ key: match.id,
944
1407
  role: "button",
945
- "aria-label": `Open match details for ${match.route.id}`,
946
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
1408
+ "aria-label": `Open match details for ${match.id}`,
1409
+ onClick: () => setActiveId(activeId === match.id ? '' : match.id),
947
1410
  style: {
948
1411
  display: 'flex',
949
1412
  borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
950
1413
  cursor: 'pointer',
951
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
1414
+ alignItems: 'center',
1415
+ background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
1416
+ fontSize: '0.7rem'
952
1417
  }
953
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1418
+ }, /*#__PURE__*/React.createElement("div", {
954
1419
  style: {
955
1420
  flex: '0 0 auto',
956
- width: '1.3rem',
957
- height: '1.3rem',
1421
+ width: '.75rem',
1422
+ height: '.75rem',
958
1423
  marginLeft: '.25rem',
959
1424
  background: getStatusColor(match, defaultTheme),
960
1425
  alignItems: 'center',
961
1426
  justifyContent: 'center',
962
1427
  fontWeight: 'bold',
963
- borderRadius: '.25rem',
964
- transition: 'all .2s ease-out'
1428
+ borderRadius: '100%',
1429
+ transition: 'all 1s ease-out'
965
1430
  }
966
- }), /*#__PURE__*/React__default["default"].createElement(Code, {
1431
+ }), /*#__PURE__*/React.createElement(Code, {
967
1432
  style: {
968
1433
  padding: '.5em'
969
1434
  }
970
- }, `${match.id}`));
971
- })) : null), activeMatch ? /*#__PURE__*/React__default["default"].createElement(ActivePanel, null, /*#__PURE__*/React__default["default"].createElement("div", {
1435
+ }, `${match.id}`), /*#__PURE__*/React.createElement("div", {
1436
+ style: {
1437
+ marginLeft: 'auto'
1438
+ }
1439
+ }, /*#__PURE__*/React.createElement(AgeTicker, {
1440
+ match: match
1441
+ })));
1442
+ }))) : null), activeMatch ? /*#__PURE__*/React.createElement(ActivePanel, null, /*#__PURE__*/React.createElement("div", {
972
1443
  style: {
973
1444
  padding: '.5em',
974
1445
  background: defaultTheme.backgroundAlt,
@@ -977,23 +1448,27 @@
977
1448
  bottom: 0,
978
1449
  zIndex: 1
979
1450
  }
980
- }, "Match Details"), /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("table", null, /*#__PURE__*/React__default["default"].createElement("tbody", null, /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1451
+ }, "Match Details"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("table", {
1452
+ style: {
1453
+ fontSize: '0.8rem'
1454
+ }
1455
+ }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
981
1456
  style: {
982
1457
  opacity: '.5'
983
1458
  }
984
- }, "ID"), /*#__PURE__*/React__default["default"].createElement("td", null, /*#__PURE__*/React__default["default"].createElement(Code, {
1459
+ }, "ID"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Code, {
985
1460
  style: {
986
1461
  lineHeight: '1.8em'
987
1462
  }
988
- }, JSON.stringify(activeMatch.id, null, 2)))), /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1463
+ }, JSON.stringify(activeMatch.id, null, 2)))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
989
1464
  style: {
990
1465
  opacity: '.5'
991
1466
  }
992
- }, "Status"), /*#__PURE__*/React__default["default"].createElement("td", null, activeMatch.state.status)), /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1467
+ }, "Status"), /*#__PURE__*/React.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.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
993
1468
  style: {
994
1469
  opacity: '.5'
995
1470
  }
996
- }, "Last Updated"), /*#__PURE__*/React__default["default"].createElement("td", null, activeMatch.state.updatedAt ? new Date(activeMatch.state.updatedAt).toLocaleTimeString() : 'N/A'))))), /*#__PURE__*/React__default["default"].createElement("div", {
1471
+ }, "Last Updated"), /*#__PURE__*/React.createElement("td", null, activeMatch.updatedAt ? new Date(activeMatch.updatedAt).toLocaleTimeString() : 'N/A'))))), activeMatch.loaderData ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
997
1472
  style: {
998
1473
  background: defaultTheme.backgroundAlt,
999
1474
  padding: '.5em',
@@ -1002,17 +1477,15 @@
1002
1477
  bottom: 0,
1003
1478
  zIndex: 1
1004
1479
  }
1005
- }, "Actions"), /*#__PURE__*/React__default["default"].createElement("div", {
1006
- style: {
1007
- padding: '0.5em'
1008
- }
1009
- }, /*#__PURE__*/React__default["default"].createElement(Button, {
1010
- type: "button",
1011
- onClick: () => activeMatch.load(),
1480
+ }, "Loader Data"), /*#__PURE__*/React.createElement("div", {
1012
1481
  style: {
1013
- background: defaultTheme.gray
1482
+ padding: '.5em'
1014
1483
  }
1015
- }, "Reload")), /*#__PURE__*/React__default["default"].createElement("div", {
1484
+ }, /*#__PURE__*/React.createElement(Explorer, {
1485
+ label: "loaderData",
1486
+ value: activeMatch.loaderData,
1487
+ defaultExpanded: {}
1488
+ }))) : null, /*#__PURE__*/React.createElement("div", {
1016
1489
  style: {
1017
1490
  background: defaultTheme.backgroundAlt,
1018
1491
  padding: '.5em',
@@ -1021,15 +1494,15 @@
1021
1494
  bottom: 0,
1022
1495
  zIndex: 1
1023
1496
  }
1024
- }, "Explorer"), /*#__PURE__*/React__default["default"].createElement("div", {
1497
+ }, "Explorer"), /*#__PURE__*/React.createElement("div", {
1025
1498
  style: {
1026
1499
  padding: '.5em'
1027
1500
  }
1028
- }, /*#__PURE__*/React__default["default"].createElement(Explorer, {
1501
+ }, /*#__PURE__*/React.createElement(Explorer, {
1029
1502
  label: "Match",
1030
1503
  value: activeMatch,
1031
1504
  defaultExpanded: {}
1032
- }))) : null, /*#__PURE__*/React__default["default"].createElement("div", {
1505
+ }))) : null, hasSearch ? /*#__PURE__*/React.createElement("div", {
1033
1506
  style: {
1034
1507
  flex: '1 1 500px',
1035
1508
  minHeight: '40%',
@@ -1039,36 +1512,80 @@
1039
1512
  display: 'flex',
1040
1513
  flexDirection: 'column'
1041
1514
  }
1042
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1515
+ }, /*#__PURE__*/React.createElement("div", {
1043
1516
  style: {
1044
1517
  padding: '.5em',
1045
1518
  background: defaultTheme.backgroundAlt,
1046
1519
  position: 'sticky',
1047
1520
  top: 0,
1048
1521
  bottom: 0,
1049
- zIndex: 1
1522
+ zIndex: 1,
1523
+ fontWeight: 'bold'
1050
1524
  }
1051
- }, "Search Params"), /*#__PURE__*/React__default["default"].createElement("div", {
1525
+ }, "Search Params"), /*#__PURE__*/React.createElement("div", {
1052
1526
  style: {
1053
1527
  padding: '.5em'
1054
1528
  }
1055
- }, Object.keys(last(router.state.currentMatches)?.state.search || {}).length ? /*#__PURE__*/React__default["default"].createElement(Explorer, {
1056
- value: last(router.state.currentMatches)?.state.search || {},
1057
- defaultExpanded: Object.keys(last(router.state.currentMatches)?.state.search || {}).reduce((obj, next) => {
1529
+ }, /*#__PURE__*/React.createElement(Explorer, {
1530
+ value: routerState.location.search || {},
1531
+ defaultExpanded: Object.keys(routerState.location.search || {}).reduce((obj, next) => {
1058
1532
  obj[next] = {};
1059
1533
  return obj;
1060
1534
  }, {})
1061
- }) : /*#__PURE__*/React__default["default"].createElement("em", {
1535
+ }))) : null));
1536
+ });
1537
+ function AgeTicker({
1538
+ match
1539
+ }) {
1540
+ const router = useRouter();
1541
+ const rerender = React.useReducer(() => ({}), () => ({}))[1];
1542
+ React.useEffect(() => {
1543
+ const interval = setInterval(() => {
1544
+ rerender();
1545
+ }, 1000);
1546
+ return () => {
1547
+ clearInterval(interval);
1548
+ };
1549
+ }, []);
1550
+ if (!match) {
1551
+ return null;
1552
+ }
1553
+ const route = router.looseRoutesById[match?.routeId];
1554
+ if (!route.options.loader) {
1555
+ return null;
1556
+ }
1557
+ const age = Date.now() - match?.updatedAt;
1558
+ const staleTime = route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
1559
+ const gcTime = route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1000;
1560
+ return /*#__PURE__*/React.createElement("div", {
1062
1561
  style: {
1063
- opacity: 0.5
1562
+ display: 'inline-flex',
1563
+ alignItems: 'center',
1564
+ gap: '.25rem',
1565
+ color: age > staleTime ? defaultTheme.warning : undefined
1064
1566
  }
1065
- }, '{ }')))));
1066
- });
1567
+ }, /*#__PURE__*/React.createElement("div", {
1568
+ style: {}
1569
+ }, formatTime(age)), /*#__PURE__*/React.createElement("div", null, "/"), /*#__PURE__*/React.createElement("div", null, formatTime(staleTime)), /*#__PURE__*/React.createElement("div", null, "/"), /*#__PURE__*/React.createElement("div", null, formatTime(gcTime)));
1570
+ }
1571
+ function formatTime(ms) {
1572
+ const units = ['s', 'min', 'h', 'd'];
1573
+ const values = [ms / 1000, ms / 60000, ms / 3600000, ms / 86400000];
1574
+ let chosenUnitIndex = 0;
1575
+ for (let i = 1; i < values.length; i++) {
1576
+ if (values[i] < 1) break;
1577
+ chosenUnitIndex = i;
1578
+ }
1579
+ const formatter = new Intl.NumberFormat(navigator.language, {
1580
+ compactDisplay: 'short',
1581
+ notation: 'compact',
1582
+ maximumFractionDigits: 0
1583
+ });
1584
+ return formatter.format(values[chosenUnitIndex]) + units[chosenUnitIndex];
1585
+ }
1067
1586
 
1068
1587
  exports.TanStackRouterDevtools = TanStackRouterDevtools;
1069
1588
  exports.TanStackRouterDevtoolsPanel = TanStackRouterDevtoolsPanel;
1070
1589
 
1071
- Object.defineProperty(exports, '__esModule', { value: true });
1072
-
1073
1590
  }));
1074
1591
  //# sourceMappingURL=index.development.js.map