@tanstack/react-router-devtools 0.0.1-alpha.6 → 0.0.1-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/packages/react-router-devtools/src/devtools.js +43 -42
- package/build/cjs/packages/react-router-devtools/src/devtools.js.map +1 -1
- package/build/cjs/packages/react-router-devtools/src/utils.js +36 -0
- package/build/cjs/packages/react-router-devtools/src/utils.js.map +1 -1
- package/build/esm/index.js +78 -42
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +2677 -2677
- package/build/umd/index.development.js +78 -42
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/devtools.tsx +172 -180
- package/src/utils.ts +30 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/react-router-devtools",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "0.0.1-alpha.
|
|
4
|
+
"version": "0.0.1-alpha.8",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "tanstack/router",
|
|
7
7
|
"homepage": "https://react-router.tanstack.com/",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"src"
|
|
36
36
|
],
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@tanstack/react-router": "0.0.1-alpha.
|
|
38
|
+
"@tanstack/react-router": "0.0.1-alpha.8",
|
|
39
39
|
"react": ">=16",
|
|
40
40
|
"react-dom": ">=16"
|
|
41
41
|
},
|
package/src/devtools.tsx
CHANGED
|
@@ -3,7 +3,12 @@ import { Router, last } from '@tanstack/react-router'
|
|
|
3
3
|
import { formatDistanceStrict } from 'date-fns'
|
|
4
4
|
|
|
5
5
|
import useLocalStorage from './useLocalStorage'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
getStatusColor,
|
|
8
|
+
multiSortBy,
|
|
9
|
+
useIsMounted,
|
|
10
|
+
useSafeState,
|
|
11
|
+
} from './utils'
|
|
7
12
|
import { Panel, Button, Code, ActivePanel } from './styledComponents'
|
|
8
13
|
import { ThemeProvider, defaultTheme as theme } from './theme'
|
|
9
14
|
// import { getQueryStatusLabel, getQueryStatusColor } from './utils'
|
|
@@ -363,37 +368,12 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
363
368
|
router,
|
|
364
369
|
...panelProps
|
|
365
370
|
} = props
|
|
366
|
-
const routerExplorerValue = React.useMemo(() => {
|
|
367
|
-
const {
|
|
368
|
-
listeners,
|
|
369
|
-
buildLocation,
|
|
370
|
-
mount,
|
|
371
|
-
update,
|
|
372
|
-
buildNext,
|
|
373
|
-
navigate,
|
|
374
|
-
cancelMatches,
|
|
375
|
-
loadLocation,
|
|
376
|
-
cleanPreloadCache,
|
|
377
|
-
loadRoute,
|
|
378
|
-
matchRoutes,
|
|
379
|
-
loadMatches,
|
|
380
|
-
invalidateRoute,
|
|
381
|
-
resolvePath,
|
|
382
|
-
matchRoute,
|
|
383
|
-
buildLink,
|
|
384
|
-
__experimental__createSnapshot,
|
|
385
|
-
destroy,
|
|
386
|
-
...rest
|
|
387
|
-
} = router
|
|
388
|
-
|
|
389
|
-
return rest
|
|
390
|
-
}, [router.state])
|
|
391
371
|
|
|
392
372
|
const rerender = React.useReducer(() => ({}), {})[1]
|
|
393
373
|
|
|
394
374
|
React.useEffect(() => {
|
|
395
375
|
let interval = setInterval(() => {
|
|
396
|
-
router.
|
|
376
|
+
router.cleanMatchCache()
|
|
397
377
|
// router.notify()
|
|
398
378
|
rerender()
|
|
399
379
|
}, 250)
|
|
@@ -408,30 +388,29 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
408
388
|
'',
|
|
409
389
|
)
|
|
410
390
|
|
|
411
|
-
const
|
|
412
|
-
|
|
391
|
+
const [activeMatchId, setActiveMatchId] = useLocalStorage(
|
|
392
|
+
'tanstackRouterDevtoolsActiveMatchId',
|
|
393
|
+
'',
|
|
413
394
|
)
|
|
414
395
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
return rest
|
|
434
|
-
}, [activeMatch])
|
|
396
|
+
React.useEffect(() => {
|
|
397
|
+
setActiveMatchId('')
|
|
398
|
+
}, [activeRouteId])
|
|
399
|
+
|
|
400
|
+
const activeMatch =
|
|
401
|
+
Object.values(router.matchCache)?.find(
|
|
402
|
+
(d) => d.match.matchId === activeMatchId,
|
|
403
|
+
)?.match ?? router.state.matches?.find((d) => d.routeId === activeRouteId)
|
|
404
|
+
|
|
405
|
+
const matchCacheValues = multiSortBy(
|
|
406
|
+
Object.keys(router.matchCache)
|
|
407
|
+
.filter((key) => {
|
|
408
|
+
const cacheEntry = router.matchCache[key]!
|
|
409
|
+
return cacheEntry.gc > Date.now()
|
|
410
|
+
})
|
|
411
|
+
.map((key) => router.matchCache[key]!),
|
|
412
|
+
[(d) => (d.match.isFetching ? -1 : 1), (d) => -d.match.updatedAt!],
|
|
413
|
+
)
|
|
435
414
|
|
|
436
415
|
return (
|
|
437
416
|
<ThemeProvider theme={theme}>
|
|
@@ -550,11 +529,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
550
529
|
padding: '.5em',
|
|
551
530
|
}}
|
|
552
531
|
>
|
|
553
|
-
<Explorer
|
|
554
|
-
label="Router"
|
|
555
|
-
value={routerExplorerValue}
|
|
556
|
-
defaultExpanded={{}}
|
|
557
|
-
/>
|
|
532
|
+
<Explorer label="Router" value={router} defaultExpanded={{}} />
|
|
558
533
|
</div>
|
|
559
534
|
</div>
|
|
560
535
|
</div>
|
|
@@ -578,7 +553,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
578
553
|
zIndex: 1,
|
|
579
554
|
}}
|
|
580
555
|
>
|
|
581
|
-
|
|
556
|
+
Active Matches
|
|
582
557
|
</div>
|
|
583
558
|
{router.state.matches.map((match, i) => {
|
|
584
559
|
return (
|
|
@@ -625,153 +600,165 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
625
600
|
</div>
|
|
626
601
|
)
|
|
627
602
|
})}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
marginTop: '2rem',
|
|
631
|
-
padding: '.5em',
|
|
632
|
-
background: theme.backgroundAlt,
|
|
633
|
-
position: 'sticky',
|
|
634
|
-
top: 0,
|
|
635
|
-
zIndex: 1,
|
|
636
|
-
}}
|
|
637
|
-
>
|
|
638
|
-
Pending Matches
|
|
639
|
-
</div>
|
|
640
|
-
{router.state.pending?.matches.map((match, i) => {
|
|
641
|
-
return (
|
|
603
|
+
{router.state.pending?.matches.length ? (
|
|
604
|
+
<>
|
|
642
605
|
<div
|
|
643
|
-
key={match.routeId || i}
|
|
644
|
-
role="button"
|
|
645
|
-
aria-label={`Open match details for ${match.routeId}`}
|
|
646
|
-
onClick={() =>
|
|
647
|
-
setActiveRouteId(
|
|
648
|
-
activeRouteId === match.routeId ? '' : match.routeId,
|
|
649
|
-
)
|
|
650
|
-
}
|
|
651
606
|
style={{
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
607
|
+
marginTop: '2rem',
|
|
608
|
+
padding: '.5em',
|
|
609
|
+
background: theme.backgroundAlt,
|
|
610
|
+
position: 'sticky',
|
|
611
|
+
top: 0,
|
|
612
|
+
zIndex: 1,
|
|
657
613
|
}}
|
|
658
614
|
>
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
615
|
+
Pending Matches
|
|
616
|
+
</div>
|
|
617
|
+
{router.state.pending?.matches.map((match, i) => {
|
|
618
|
+
return (
|
|
619
|
+
<div
|
|
620
|
+
key={match.routeId || i}
|
|
621
|
+
role="button"
|
|
622
|
+
aria-label={`Open match details for ${match.routeId}`}
|
|
623
|
+
onClick={() =>
|
|
624
|
+
setActiveRouteId(
|
|
625
|
+
activeRouteId === match.routeId ? '' : match.routeId,
|
|
626
|
+
)
|
|
627
|
+
}
|
|
628
|
+
style={{
|
|
629
|
+
display: 'flex',
|
|
630
|
+
borderBottom: `solid 1px ${theme.grayAlt}`,
|
|
631
|
+
cursor: 'pointer',
|
|
632
|
+
background:
|
|
633
|
+
match === activeMatch
|
|
634
|
+
? 'rgba(255,255,255,.1)'
|
|
635
|
+
: undefined,
|
|
636
|
+
}}
|
|
637
|
+
>
|
|
638
|
+
<div
|
|
639
|
+
style={{
|
|
640
|
+
flex: '0 0 auto',
|
|
641
|
+
width: '1.3rem',
|
|
642
|
+
height: '1.3rem',
|
|
643
|
+
marginLeft: '.25rem',
|
|
644
|
+
background: getStatusColor(match, theme),
|
|
645
|
+
alignItems: 'center',
|
|
646
|
+
justifyContent: 'center',
|
|
647
|
+
fontWeight: 'bold',
|
|
648
|
+
borderRadius: '.25rem',
|
|
649
|
+
transition: 'all .2s ease-out',
|
|
650
|
+
}}
|
|
651
|
+
/>
|
|
673
652
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
653
|
+
<Code
|
|
654
|
+
style={{
|
|
655
|
+
padding: '.5em',
|
|
656
|
+
}}
|
|
657
|
+
>
|
|
658
|
+
{`${match.matchId}`}
|
|
659
|
+
</Code>
|
|
660
|
+
</div>
|
|
661
|
+
)
|
|
662
|
+
})}
|
|
663
|
+
</>
|
|
664
|
+
) : null}
|
|
665
|
+
{matchCacheValues.length ? (
|
|
666
|
+
<>
|
|
667
|
+
<div
|
|
668
|
+
style={{
|
|
669
|
+
marginTop: '2rem',
|
|
670
|
+
padding: '.5em',
|
|
671
|
+
background: theme.backgroundAlt,
|
|
672
|
+
position: 'sticky',
|
|
673
|
+
top: 0,
|
|
674
|
+
bottom: 0,
|
|
675
|
+
zIndex: 1,
|
|
676
|
+
display: 'flex',
|
|
677
|
+
alignItems: 'center',
|
|
678
|
+
justifyContent: 'space-between',
|
|
679
|
+
}}
|
|
680
|
+
>
|
|
681
|
+
<div>Match Cache</div>
|
|
682
|
+
<Button
|
|
683
|
+
onClick={() => {
|
|
684
|
+
router.matchCache = {}
|
|
685
|
+
router.notify()
|
|
677
686
|
}}
|
|
678
687
|
>
|
|
679
|
-
|
|
680
|
-
</
|
|
688
|
+
Clear
|
|
689
|
+
</Button>
|
|
681
690
|
</div>
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
marginTop: '2rem',
|
|
687
|
-
padding: '.5em',
|
|
688
|
-
background: theme.backgroundAlt,
|
|
689
|
-
position: 'sticky',
|
|
690
|
-
top: 0,
|
|
691
|
-
zIndex: 1,
|
|
692
|
-
}}
|
|
693
|
-
>
|
|
694
|
-
Preloading Matches
|
|
695
|
-
</div>
|
|
696
|
-
{Object.keys(router.preloadCache)
|
|
697
|
-
.filter((key) => {
|
|
698
|
-
const cacheEntry = router.preloadCache[key]!
|
|
699
|
-
return (
|
|
700
|
-
(cacheEntry.match.updatedAt ?? Date.now()) + cacheEntry.maxAge >
|
|
701
|
-
Date.now()
|
|
702
|
-
)
|
|
703
|
-
})
|
|
704
|
-
.map((key, i) => {
|
|
705
|
-
const { match, maxAge } = router.preloadCache[key]!
|
|
706
|
-
|
|
707
|
-
return (
|
|
708
|
-
<div
|
|
709
|
-
key={match.matchId || i}
|
|
710
|
-
role="button"
|
|
711
|
-
aria-label={`Open match details for ${match.matchId}`}
|
|
712
|
-
onClick={() =>
|
|
713
|
-
setActiveRouteId(
|
|
714
|
-
activeRouteId === match.routeId ? '' : match.routeId,
|
|
715
|
-
)
|
|
716
|
-
}
|
|
717
|
-
style={{
|
|
718
|
-
display: 'flex',
|
|
719
|
-
borderBottom: `solid 1px ${theme.grayAlt}`,
|
|
720
|
-
cursor: 'pointer',
|
|
721
|
-
background:
|
|
722
|
-
match === activeMatch
|
|
723
|
-
? 'rgba(255,255,255,.1)'
|
|
724
|
-
: undefined,
|
|
725
|
-
}}
|
|
726
|
-
>
|
|
691
|
+
{matchCacheValues.map((d, i) => {
|
|
692
|
+
const { match, gc } = d
|
|
693
|
+
|
|
694
|
+
return (
|
|
727
695
|
<div
|
|
696
|
+
key={match.matchId || i}
|
|
697
|
+
role="button"
|
|
698
|
+
aria-label={`Open match details for ${match.matchId}`}
|
|
699
|
+
onClick={() =>
|
|
700
|
+
setActiveMatchId(
|
|
701
|
+
activeMatchId === match.matchId ? '' : match.matchId,
|
|
702
|
+
)
|
|
703
|
+
}
|
|
728
704
|
style={{
|
|
729
705
|
display: 'flex',
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
706
|
+
borderBottom: `solid 1px ${theme.grayAlt}`,
|
|
707
|
+
cursor: 'pointer',
|
|
708
|
+
background:
|
|
709
|
+
match === activeMatch
|
|
710
|
+
? 'rgba(255,255,255,.1)'
|
|
711
|
+
: undefined,
|
|
733
712
|
}}
|
|
734
713
|
>
|
|
735
714
|
<div
|
|
736
715
|
style={{
|
|
737
716
|
display: 'flex',
|
|
738
|
-
|
|
739
|
-
|
|
717
|
+
flexDirection: 'column',
|
|
718
|
+
padding: '.5rem',
|
|
719
|
+
gap: '.3rem',
|
|
740
720
|
}}
|
|
741
721
|
>
|
|
742
722
|
<div
|
|
743
723
|
style={{
|
|
744
|
-
|
|
745
|
-
width: '1.3rem',
|
|
746
|
-
height: '1.3rem',
|
|
747
|
-
background: getStatusColor(match, theme),
|
|
724
|
+
display: 'flex',
|
|
748
725
|
alignItems: 'center',
|
|
749
|
-
|
|
750
|
-
fontWeight: 'bold',
|
|
751
|
-
borderRadius: '.25rem',
|
|
752
|
-
transition: 'all .2s ease-out',
|
|
726
|
+
gap: '.5rem',
|
|
753
727
|
}}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
728
|
+
>
|
|
729
|
+
<div
|
|
730
|
+
style={{
|
|
731
|
+
flex: '0 0 auto',
|
|
732
|
+
width: '1.3rem',
|
|
733
|
+
height: '1.3rem',
|
|
734
|
+
background: getStatusColor(match, theme),
|
|
735
|
+
alignItems: 'center',
|
|
736
|
+
justifyContent: 'center',
|
|
737
|
+
fontWeight: 'bold',
|
|
738
|
+
borderRadius: '.25rem',
|
|
739
|
+
transition: 'all .2s ease-out',
|
|
740
|
+
}}
|
|
741
|
+
/>
|
|
742
|
+
<Code>{`${match.matchId}`}</Code>
|
|
743
|
+
</div>
|
|
744
|
+
<span
|
|
745
|
+
style={{
|
|
746
|
+
fontSize: '.7rem',
|
|
747
|
+
opacity: '.5',
|
|
748
|
+
lineHeight: 1,
|
|
749
|
+
}}
|
|
750
|
+
>
|
|
751
|
+
Expires{' '}
|
|
752
|
+
{formatDistanceStrict(new Date(gc), new Date(), {
|
|
767
753
|
addSuffix: true,
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
</
|
|
754
|
+
})}
|
|
755
|
+
</span>
|
|
756
|
+
</div>
|
|
771
757
|
</div>
|
|
772
|
-
|
|
773
|
-
)
|
|
774
|
-
|
|
758
|
+
)
|
|
759
|
+
})}
|
|
760
|
+
</>
|
|
761
|
+
) : null}
|
|
775
762
|
</div>
|
|
776
763
|
|
|
777
764
|
{activeMatch ? (
|
|
@@ -782,6 +769,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
782
769
|
background: theme.backgroundAlt,
|
|
783
770
|
position: 'sticky',
|
|
784
771
|
top: 0,
|
|
772
|
+
bottom: 0,
|
|
785
773
|
zIndex: 1,
|
|
786
774
|
}}
|
|
787
775
|
>
|
|
@@ -833,6 +821,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
833
821
|
padding: '.5em',
|
|
834
822
|
position: 'sticky',
|
|
835
823
|
top: 0,
|
|
824
|
+
bottom: 0,
|
|
836
825
|
zIndex: 1,
|
|
837
826
|
}}
|
|
838
827
|
>
|
|
@@ -872,6 +861,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
872
861
|
padding: '.5em',
|
|
873
862
|
position: 'sticky',
|
|
874
863
|
top: 0,
|
|
864
|
+
bottom: 0,
|
|
875
865
|
zIndex: 1,
|
|
876
866
|
}}
|
|
877
867
|
>
|
|
@@ -884,7 +874,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
884
874
|
>
|
|
885
875
|
<Explorer
|
|
886
876
|
label="Match"
|
|
887
|
-
value={
|
|
877
|
+
value={activeMatch}
|
|
888
878
|
defaultExpanded={{}}
|
|
889
879
|
/>
|
|
890
880
|
</div>
|
|
@@ -907,10 +897,11 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
907
897
|
background: theme.backgroundAlt,
|
|
908
898
|
position: 'sticky',
|
|
909
899
|
top: 0,
|
|
900
|
+
bottom: 0,
|
|
910
901
|
zIndex: 1,
|
|
911
902
|
}}
|
|
912
903
|
>
|
|
913
|
-
Loader Data
|
|
904
|
+
All Loader Data
|
|
914
905
|
</div>
|
|
915
906
|
<div
|
|
916
907
|
style={{
|
|
@@ -938,6 +929,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
|
|
|
938
929
|
background: theme.backgroundAlt,
|
|
939
930
|
position: 'sticky',
|
|
940
931
|
top: 0,
|
|
932
|
+
bottom: 0,
|
|
941
933
|
zIndex: 1,
|
|
942
934
|
}}
|
|
943
935
|
>
|
package/src/utils.ts
CHANGED
|
@@ -149,3 +149,33 @@ function scheduleMicrotask(callback: () => void) {
|
|
|
149
149
|
}),
|
|
150
150
|
)
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
export function multiSortBy<T>(
|
|
154
|
+
arr: T[],
|
|
155
|
+
accessors: ((item: T) => any)[] = [(d) => d],
|
|
156
|
+
): T[] {
|
|
157
|
+
return arr
|
|
158
|
+
.map((d, i) => [d, i] as const)
|
|
159
|
+
.sort(([a, ai], [b, bi]) => {
|
|
160
|
+
for (const accessor of accessors) {
|
|
161
|
+
const ao = accessor(a)
|
|
162
|
+
const bo = accessor(b)
|
|
163
|
+
|
|
164
|
+
if (typeof ao === 'undefined') {
|
|
165
|
+
if (typeof bo === 'undefined') {
|
|
166
|
+
continue
|
|
167
|
+
}
|
|
168
|
+
return 1
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (ao === bo) {
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return ao > bo ? 1 : -1
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return ai - bi
|
|
179
|
+
})
|
|
180
|
+
.map(([d]) => d)
|
|
181
|
+
}
|