@tanstack/query-devtools 5.0.3 → 5.1.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.
- package/build/Devtools/{B2H37NSB.js → BWLPXLBN.js} +1466 -390
- package/build/Devtools/{3Y5CBXUA.js → CRASJTHY.js} +1466 -390
- package/build/Devtools/{Y2E2LEWB.jsx → QHGCTHEZ.jsx} +1170 -142
- package/build/Devtools/{7SMWYMBY.jsx → QHLLQ2XL.jsx} +1170 -142
- package/build/chunk/{AHAJNSNO.jsx → JRAMSUCV.jsx} +5 -0
- package/build/dev.cjs +1478 -395
- package/build/dev.js +1 -1
- package/build/dev.jsx +2 -2
- package/build/index.cjs +1478 -395
- package/build/index.js +1 -1
- package/build/index.jsx +2 -2
- package/package.json +3 -3
- package/src/Devtools.tsx +773 -121
- package/src/__tests__/devtools.test.tsx +2 -0
- package/src/__tests__/utils.test.ts +1 -0
- package/src/icons/index.tsx +89 -0
- package/src/theme.ts +11 -11
- package/src/utils.tsx +46 -1
package/src/Devtools.tsx
CHANGED
|
@@ -15,16 +15,18 @@ import { TransitionGroup } from 'solid-transition-group'
|
|
|
15
15
|
import { Key } from '@solid-primitives/keyed'
|
|
16
16
|
import { createLocalStorage } from '@solid-primitives/storage'
|
|
17
17
|
import { createResizeObserver } from '@solid-primitives/resize-observer'
|
|
18
|
-
import { DropdownMenu } from '@kobalte/core'
|
|
18
|
+
import { DropdownMenu, RadioGroup } from '@kobalte/core'
|
|
19
19
|
import { tokens } from './theme'
|
|
20
20
|
import {
|
|
21
21
|
convertRemToPixels,
|
|
22
22
|
displayValue,
|
|
23
|
+
getMutationStatusColor,
|
|
23
24
|
getPreferredColorScheme,
|
|
24
25
|
getQueryStatusColor,
|
|
25
26
|
getQueryStatusColorByLabel,
|
|
26
27
|
getQueryStatusLabel,
|
|
27
28
|
getSidedProp,
|
|
29
|
+
mutationSortFns,
|
|
28
30
|
sortFns,
|
|
29
31
|
} from './utils'
|
|
30
32
|
import {
|
|
@@ -32,16 +34,20 @@ import {
|
|
|
32
34
|
ArrowLeft,
|
|
33
35
|
ArrowRight,
|
|
34
36
|
ArrowUp,
|
|
37
|
+
CheckCircle,
|
|
35
38
|
ChevronDown,
|
|
39
|
+
LoadingCircle,
|
|
36
40
|
Monitor,
|
|
37
41
|
Moon,
|
|
38
42
|
Offline,
|
|
43
|
+
PauseCircle,
|
|
39
44
|
Search,
|
|
40
45
|
Settings,
|
|
41
46
|
Sun,
|
|
42
47
|
TanstackLogo,
|
|
43
48
|
Trash,
|
|
44
49
|
Wifi,
|
|
50
|
+
XCircle,
|
|
45
51
|
} from './icons'
|
|
46
52
|
import Explorer from './Explorer'
|
|
47
53
|
import {
|
|
@@ -57,7 +63,13 @@ import type {
|
|
|
57
63
|
DevtoolsPosition,
|
|
58
64
|
QueryDevtoolsProps,
|
|
59
65
|
} from './Context'
|
|
60
|
-
import type {
|
|
66
|
+
import type {
|
|
67
|
+
Mutation,
|
|
68
|
+
MutationCache,
|
|
69
|
+
Query,
|
|
70
|
+
QueryCache,
|
|
71
|
+
QueryState,
|
|
72
|
+
} from '@tanstack/query-core'
|
|
61
73
|
import type { StorageObject, StorageSetter } from '@solid-primitives/storage'
|
|
62
74
|
import type { Accessor, Component, JSX, Setter } from 'solid-js'
|
|
63
75
|
|
|
@@ -68,7 +80,7 @@ interface DevtoolsPanelProps {
|
|
|
68
80
|
|
|
69
81
|
interface QueryStatusProps {
|
|
70
82
|
label: string
|
|
71
|
-
color: 'green' | 'yellow' | 'gray' | 'blue' | 'purple'
|
|
83
|
+
color: 'green' | 'yellow' | 'gray' | 'blue' | 'purple' | 'red'
|
|
72
84
|
count: number
|
|
73
85
|
}
|
|
74
86
|
|
|
@@ -84,10 +96,14 @@ const DEFAULT_HEIGHT = 500
|
|
|
84
96
|
const DEFAULT_WIDTH = 500
|
|
85
97
|
const DEFAULT_SORT_FN_NAME = Object.keys(sortFns)[0]
|
|
86
98
|
const DEFAULT_SORT_ORDER = 1
|
|
99
|
+
const DEFAULT_MUTATION_SORT_FN_NAME = Object.keys(mutationSortFns)[0]
|
|
87
100
|
|
|
88
101
|
const [selectedQueryHash, setSelectedQueryHash] = createSignal<string | null>(
|
|
89
102
|
null,
|
|
90
103
|
)
|
|
104
|
+
const [selectedMutationId, setSelectedMutationId] = createSignal<number | null>(
|
|
105
|
+
null,
|
|
106
|
+
)
|
|
91
107
|
const [panelWidth, setPanelWidth] = createSignal(0)
|
|
92
108
|
|
|
93
109
|
export const DevtoolsComponent: Component<QueryDevtoolsProps> = (props) => {
|
|
@@ -234,13 +250,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
234
250
|
|
|
235
251
|
const [isResizing, setIsResizing] = createSignal(false)
|
|
236
252
|
|
|
237
|
-
const sort = createMemo(() => props.localStore.sort || DEFAULT_SORT_FN_NAME)
|
|
238
|
-
const sortOrder = createMemo(
|
|
239
|
-
() => Number(props.localStore.sortOrder) || DEFAULT_SORT_ORDER,
|
|
240
|
-
) as () => 1 | -1
|
|
241
|
-
|
|
242
|
-
const [offline, setOffline] = createSignal(false)
|
|
243
|
-
|
|
244
253
|
const position = createMemo(
|
|
245
254
|
() =>
|
|
246
255
|
(props.localStore.position ||
|
|
@@ -248,41 +257,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
248
257
|
POSITION) as DevtoolsPosition,
|
|
249
258
|
)
|
|
250
259
|
|
|
251
|
-
const sortFn = createMemo(() => sortFns[sort() as string])
|
|
252
|
-
|
|
253
|
-
const onlineManager = createMemo(
|
|
254
|
-
() => useQueryDevtoolsContext().onlineManager,
|
|
255
|
-
)
|
|
256
|
-
|
|
257
|
-
const cache = createMemo(() => {
|
|
258
|
-
return useQueryDevtoolsContext().client.getQueryCache()
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
const queryCount = createSubscribeToQueryCacheBatcher((queryCache) => {
|
|
262
|
-
return queryCache().getAll().length
|
|
263
|
-
}, false)
|
|
264
|
-
|
|
265
|
-
const queries = createMemo(
|
|
266
|
-
on(
|
|
267
|
-
() => [queryCount(), props.localStore.filter, sort(), sortOrder()],
|
|
268
|
-
() => {
|
|
269
|
-
const curr = cache().getAll()
|
|
270
|
-
|
|
271
|
-
const filtered = props.localStore.filter
|
|
272
|
-
? curr.filter(
|
|
273
|
-
(item) =>
|
|
274
|
-
rankItem(item.queryHash, props.localStore.filter || '').passed,
|
|
275
|
-
)
|
|
276
|
-
: [...curr]
|
|
277
|
-
|
|
278
|
-
const sorted = sortFn()
|
|
279
|
-
? filtered.sort((a, b) => sortFn()!(a, b) * sortOrder())
|
|
280
|
-
: filtered
|
|
281
|
-
return sorted
|
|
282
|
-
},
|
|
283
|
-
),
|
|
284
|
-
)
|
|
285
|
-
|
|
286
260
|
const handleDragStart: JSX.EventHandler<HTMLDivElement, MouseEvent> = (
|
|
287
261
|
event,
|
|
288
262
|
) => {
|
|
@@ -344,9 +318,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
344
318
|
document.addEventListener('mouseup', unsub, false)
|
|
345
319
|
}
|
|
346
320
|
|
|
347
|
-
setupQueryCacheSubscription()
|
|
348
|
-
|
|
349
|
-
let queriesContainerRef!: HTMLDivElement
|
|
350
321
|
let panelRef!: HTMLDivElement
|
|
351
322
|
|
|
352
323
|
onMount(() => {
|
|
@@ -357,10 +328,6 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
357
328
|
})
|
|
358
329
|
})
|
|
359
330
|
|
|
360
|
-
const setDevtoolsPosition = (pos: DevtoolsPosition) => {
|
|
361
|
-
props.setLocalStore('position', pos)
|
|
362
|
-
}
|
|
363
|
-
|
|
364
331
|
createEffect(() => {
|
|
365
332
|
const rootContainer = panelRef.parentElement?.parentElement?.parentElement
|
|
366
333
|
if (!rootContainer) return
|
|
@@ -465,14 +432,136 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
465
432
|
>
|
|
466
433
|
<ChevronDown />
|
|
467
434
|
</button>
|
|
435
|
+
<ContentView
|
|
436
|
+
localStore={props.localStore}
|
|
437
|
+
setLocalStore={props.setLocalStore}
|
|
438
|
+
/>
|
|
439
|
+
</aside>
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const ContentView: Component<DevtoolsPanelProps> = (props) => {
|
|
444
|
+
setupQueryCacheSubscription()
|
|
445
|
+
setupMutationCacheSubscription()
|
|
446
|
+
|
|
447
|
+
const theme = useTheme()
|
|
448
|
+
const styles = createMemo(() => {
|
|
449
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
const [selectedView, setSelectedView] = createSignal<'queries' | 'mutations'>(
|
|
453
|
+
'queries',
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
const sort = createMemo(() => props.localStore.sort || DEFAULT_SORT_FN_NAME)
|
|
457
|
+
const sortOrder = createMemo(
|
|
458
|
+
() => Number(props.localStore.sortOrder) || DEFAULT_SORT_ORDER,
|
|
459
|
+
) as () => 1 | -1
|
|
460
|
+
|
|
461
|
+
const mutationSort = createMemo(
|
|
462
|
+
() => props.localStore.mutationSort || DEFAULT_MUTATION_SORT_FN_NAME,
|
|
463
|
+
)
|
|
464
|
+
const mutationSortOrder = createMemo(
|
|
465
|
+
() => Number(props.localStore.mutationSortOrder) || DEFAULT_SORT_ORDER,
|
|
466
|
+
) as () => 1 | -1
|
|
467
|
+
|
|
468
|
+
const [offline, setOffline] = createSignal(false)
|
|
469
|
+
|
|
470
|
+
const sortFn = createMemo(() => sortFns[sort() as string])
|
|
471
|
+
const mutationSortFn = createMemo(
|
|
472
|
+
() => mutationSortFns[mutationSort() as string],
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
const onlineManager = createMemo(
|
|
476
|
+
() => useQueryDevtoolsContext().onlineManager,
|
|
477
|
+
)
|
|
478
|
+
|
|
479
|
+
const query_cache = createMemo(() => {
|
|
480
|
+
return useQueryDevtoolsContext().client.getQueryCache()
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
const mutation_cache = createMemo(() => {
|
|
484
|
+
return useQueryDevtoolsContext().client.getMutationCache()
|
|
485
|
+
})
|
|
486
|
+
|
|
487
|
+
const queryCount = createSubscribeToQueryCacheBatcher((queryCache) => {
|
|
488
|
+
return queryCache().getAll().length
|
|
489
|
+
}, false)
|
|
490
|
+
|
|
491
|
+
const queries = createMemo(
|
|
492
|
+
on(
|
|
493
|
+
() => [queryCount(), props.localStore.filter, sort(), sortOrder()],
|
|
494
|
+
() => {
|
|
495
|
+
const curr = query_cache().getAll()
|
|
496
|
+
|
|
497
|
+
const filtered = props.localStore.filter
|
|
498
|
+
? curr.filter(
|
|
499
|
+
(item) =>
|
|
500
|
+
rankItem(item.queryHash, props.localStore.filter || '').passed,
|
|
501
|
+
)
|
|
502
|
+
: [...curr]
|
|
503
|
+
|
|
504
|
+
const sorted = sortFn()
|
|
505
|
+
? filtered.sort((a, b) => sortFn()!(a, b) * sortOrder())
|
|
506
|
+
: filtered
|
|
507
|
+
return sorted
|
|
508
|
+
},
|
|
509
|
+
),
|
|
510
|
+
)
|
|
511
|
+
|
|
512
|
+
const mutationCount = createSubscribeToMutationCacheBatcher(
|
|
513
|
+
(mutationCache) => {
|
|
514
|
+
return mutationCache().getAll().length
|
|
515
|
+
},
|
|
516
|
+
false,
|
|
517
|
+
)
|
|
518
|
+
|
|
519
|
+
const mutations = createMemo(
|
|
520
|
+
on(
|
|
521
|
+
() => [
|
|
522
|
+
mutationCount(),
|
|
523
|
+
props.localStore.mutationFilter,
|
|
524
|
+
mutationSort(),
|
|
525
|
+
mutationSortOrder(),
|
|
526
|
+
],
|
|
527
|
+
() => {
|
|
528
|
+
const curr = mutation_cache().getAll()
|
|
529
|
+
|
|
530
|
+
const filtered = props.localStore.mutationFilter
|
|
531
|
+
? curr.filter((item) => {
|
|
532
|
+
const value = `${
|
|
533
|
+
item.options.mutationKey
|
|
534
|
+
? JSON.stringify(item.options.mutationKey) + ' - '
|
|
535
|
+
: ''
|
|
536
|
+
}${new Date(item.state.submittedAt).toLocaleString()}`
|
|
537
|
+
return rankItem(value, props.localStore.mutationFilter || '')
|
|
538
|
+
.passed
|
|
539
|
+
})
|
|
540
|
+
: [...curr]
|
|
541
|
+
|
|
542
|
+
const sorted = mutationSortFn()
|
|
543
|
+
? filtered.sort(
|
|
544
|
+
(a, b) => mutationSortFn()!(a, b) * mutationSortOrder(),
|
|
545
|
+
)
|
|
546
|
+
: filtered
|
|
547
|
+
return sorted
|
|
548
|
+
},
|
|
549
|
+
),
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
const setDevtoolsPosition = (pos: DevtoolsPosition) => {
|
|
553
|
+
props.setLocalStore('position', pos)
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
return (
|
|
557
|
+
<>
|
|
468
558
|
<div
|
|
469
|
-
ref={queriesContainerRef}
|
|
470
559
|
// When the panels are stacked we use the height style
|
|
471
560
|
// to divide the panels into two equal parts
|
|
472
561
|
class={cx(
|
|
473
562
|
styles().queriesContainer,
|
|
474
563
|
panelWidth() < secondBreakpoint &&
|
|
475
|
-
selectedQueryHash() &&
|
|
564
|
+
(selectedQueryHash() || selectedMutationId()) &&
|
|
476
565
|
css`
|
|
477
566
|
height: 50%;
|
|
478
567
|
max-height: 50%;
|
|
@@ -481,35 +570,65 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
481
570
|
)}
|
|
482
571
|
>
|
|
483
572
|
<div class={cx(styles().row, 'tsqd-header')}>
|
|
484
|
-
<
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
<span class={cx(styles().tanstackLogo, 'tsqd-text-logo-tanstack')}>
|
|
490
|
-
TANSTACK
|
|
491
|
-
</span>
|
|
492
|
-
<span
|
|
493
|
-
class={cx(
|
|
494
|
-
styles().queryFlavorLogo,
|
|
495
|
-
'tsqd-text-logo-query-flavor',
|
|
496
|
-
)}
|
|
573
|
+
<div class={styles().logoAndToggleContainer}>
|
|
574
|
+
<button
|
|
575
|
+
class={cx(styles().logo, 'tsqd-text-logo-container')}
|
|
576
|
+
onClick={() => props.setLocalStore('open', 'false')}
|
|
577
|
+
aria-label="Close Tanstack query devtools"
|
|
497
578
|
>
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
579
|
+
<span
|
|
580
|
+
class={cx(styles().tanstackLogo, 'tsqd-text-logo-tanstack')}
|
|
581
|
+
>
|
|
582
|
+
TANSTACK
|
|
583
|
+
</span>
|
|
584
|
+
<span
|
|
585
|
+
class={cx(
|
|
586
|
+
styles().queryFlavorLogo,
|
|
587
|
+
'tsqd-text-logo-query-flavor',
|
|
588
|
+
)}
|
|
589
|
+
>
|
|
590
|
+
{useQueryDevtoolsContext().queryFlavor} v
|
|
591
|
+
{useQueryDevtoolsContext().version}
|
|
592
|
+
</span>
|
|
593
|
+
</button>
|
|
594
|
+
<RadioGroup.Root
|
|
595
|
+
class={cx(styles().viewToggle)}
|
|
596
|
+
value={selectedView()}
|
|
597
|
+
onChange={(value) => {
|
|
598
|
+
setSelectedView(value as 'queries' | 'mutations')
|
|
599
|
+
setSelectedQueryHash(null)
|
|
600
|
+
setSelectedMutationId(null)
|
|
601
|
+
}}
|
|
602
|
+
>
|
|
603
|
+
<RadioGroup.Item value="queries" class="tsqd-radio-toggle">
|
|
604
|
+
<RadioGroup.ItemInput />
|
|
605
|
+
<RadioGroup.ItemControl>
|
|
606
|
+
<RadioGroup.ItemIndicator />
|
|
607
|
+
</RadioGroup.ItemControl>
|
|
608
|
+
<RadioGroup.ItemLabel title="Toggle Queries View">
|
|
609
|
+
Queries
|
|
610
|
+
</RadioGroup.ItemLabel>
|
|
611
|
+
</RadioGroup.Item>
|
|
612
|
+
<RadioGroup.Item value="mutations" class="tsqd-radio-toggle">
|
|
613
|
+
<RadioGroup.ItemInput />
|
|
614
|
+
<RadioGroup.ItemControl>
|
|
615
|
+
<RadioGroup.ItemIndicator />
|
|
616
|
+
</RadioGroup.ItemControl>
|
|
617
|
+
<RadioGroup.ItemLabel title="Toggle Mutations View">
|
|
618
|
+
Mutations
|
|
619
|
+
</RadioGroup.ItemLabel>
|
|
620
|
+
</RadioGroup.Item>
|
|
621
|
+
</RadioGroup.Root>
|
|
622
|
+
</div>
|
|
623
|
+
|
|
624
|
+
<Show when={selectedView() === 'queries'}>
|
|
625
|
+
<QueryStatusCount />
|
|
626
|
+
</Show>
|
|
627
|
+
<Show when={selectedView() === 'mutations'}>
|
|
628
|
+
<MutationStatusCount />
|
|
629
|
+
</Show>
|
|
503
630
|
</div>
|
|
504
|
-
<div
|
|
505
|
-
class={cx(
|
|
506
|
-
styles().row,
|
|
507
|
-
css`
|
|
508
|
-
gap: ${tokens.size[2.5]};
|
|
509
|
-
`,
|
|
510
|
-
'tsqd-filters-actions-container',
|
|
511
|
-
)}
|
|
512
|
-
>
|
|
631
|
+
<div class={cx(styles().row, 'tsqd-filters-actions-container')}>
|
|
513
632
|
<div class={cx(styles().filtersContainer, 'tsqd-filters-container')}>
|
|
514
633
|
<div
|
|
515
634
|
class={cx(
|
|
@@ -522,11 +641,19 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
522
641
|
aria-label="Filter queries by query key"
|
|
523
642
|
type="text"
|
|
524
643
|
placeholder="Filter"
|
|
525
|
-
onInput={(e) =>
|
|
526
|
-
|
|
527
|
-
|
|
644
|
+
onInput={(e) => {
|
|
645
|
+
if (selectedView() === 'queries') {
|
|
646
|
+
props.setLocalStore('filter', e.currentTarget.value)
|
|
647
|
+
} else {
|
|
648
|
+
props.setLocalStore('mutationFilter', e.currentTarget.value)
|
|
649
|
+
}
|
|
650
|
+
}}
|
|
528
651
|
class="tsqd-query-filter-textfield"
|
|
529
|
-
value={
|
|
652
|
+
value={
|
|
653
|
+
selectedView() === 'queries'
|
|
654
|
+
? props.localStore.filter || ''
|
|
655
|
+
: props.localStore.mutationFilter || ''
|
|
656
|
+
}
|
|
530
657
|
/>
|
|
531
658
|
</div>
|
|
532
659
|
<div
|
|
@@ -535,33 +662,74 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
535
662
|
'tsqd-query-filter-sort-container',
|
|
536
663
|
)}
|
|
537
664
|
>
|
|
538
|
-
<
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
665
|
+
<Show when={selectedView() === 'queries'}>
|
|
666
|
+
<select
|
|
667
|
+
value={sort()}
|
|
668
|
+
onChange={(e) => {
|
|
669
|
+
props.setLocalStore('sort', e.currentTarget.value)
|
|
670
|
+
}}
|
|
671
|
+
>
|
|
672
|
+
{Object.keys(sortFns).map((key) => (
|
|
673
|
+
<option value={key}>Sort by {key}</option>
|
|
674
|
+
))}
|
|
675
|
+
</select>
|
|
676
|
+
</Show>
|
|
677
|
+
<Show when={selectedView() === 'mutations'}>
|
|
678
|
+
<select
|
|
679
|
+
value={mutationSort()}
|
|
680
|
+
onChange={(e) => {
|
|
681
|
+
props.setLocalStore('mutationSort', e.currentTarget.value)
|
|
682
|
+
}}
|
|
683
|
+
>
|
|
684
|
+
{Object.keys(mutationSortFns).map((key) => (
|
|
685
|
+
<option value={key}>Sort by {key}</option>
|
|
686
|
+
))}
|
|
687
|
+
</select>
|
|
688
|
+
</Show>
|
|
548
689
|
<ChevronDown />
|
|
549
690
|
</div>
|
|
550
691
|
<button
|
|
551
692
|
onClick={() => {
|
|
552
|
-
|
|
693
|
+
if (selectedView() === 'queries') {
|
|
694
|
+
props.setLocalStore('sortOrder', String(sortOrder() * -1))
|
|
695
|
+
} else {
|
|
696
|
+
props.setLocalStore(
|
|
697
|
+
'mutationSortOrder',
|
|
698
|
+
String(mutationSortOrder() * -1),
|
|
699
|
+
)
|
|
700
|
+
}
|
|
553
701
|
}}
|
|
554
702
|
aria-label={`Sort order ${
|
|
555
|
-
|
|
703
|
+
(selectedView() === 'queries'
|
|
704
|
+
? sortOrder()
|
|
705
|
+
: mutationSortOrder()) === -1
|
|
706
|
+
? 'descending'
|
|
707
|
+
: 'ascending'
|
|
556
708
|
}`}
|
|
557
|
-
aria-pressed={
|
|
709
|
+
aria-pressed={
|
|
710
|
+
(selectedView() === 'queries'
|
|
711
|
+
? sortOrder()
|
|
712
|
+
: mutationSortOrder()) === -1
|
|
713
|
+
}
|
|
558
714
|
class="tsqd-query-filter-sort-order-btn"
|
|
559
715
|
>
|
|
560
|
-
<Show
|
|
716
|
+
<Show
|
|
717
|
+
when={
|
|
718
|
+
(selectedView() === 'queries'
|
|
719
|
+
? sortOrder()
|
|
720
|
+
: mutationSortOrder()) === 1
|
|
721
|
+
}
|
|
722
|
+
>
|
|
561
723
|
<span>Asc</span>
|
|
562
724
|
<ArrowUp />
|
|
563
725
|
</Show>
|
|
564
|
-
<Show
|
|
726
|
+
<Show
|
|
727
|
+
when={
|
|
728
|
+
(selectedView() === 'queries'
|
|
729
|
+
? sortOrder()
|
|
730
|
+
: mutationSortOrder()) === -1
|
|
731
|
+
}
|
|
732
|
+
>
|
|
565
733
|
<span>Desc</span>
|
|
566
734
|
<ArrowDown />
|
|
567
735
|
</Show>
|
|
@@ -571,7 +739,11 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
571
739
|
<div class={cx(styles().actionsContainer, 'tsqd-actions-container')}>
|
|
572
740
|
<button
|
|
573
741
|
onClick={() => {
|
|
574
|
-
|
|
742
|
+
if (selectedView() === 'queries') {
|
|
743
|
+
query_cache().clear()
|
|
744
|
+
} else {
|
|
745
|
+
mutation_cache().clear()
|
|
746
|
+
}
|
|
575
747
|
}}
|
|
576
748
|
class={cx(
|
|
577
749
|
styles().actionsBtn,
|
|
@@ -579,7 +751,7 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
579
751
|
'tsqd-action-clear-cache',
|
|
580
752
|
)}
|
|
581
753
|
aria-label="Clear query cache"
|
|
582
|
-
title=
|
|
754
|
+
title={`Clear ${selectedView()} cache`}
|
|
583
755
|
>
|
|
584
756
|
<Trash />
|
|
585
757
|
</button>
|
|
@@ -787,23 +959,43 @@ export const DevtoolsPanel: Component<DevtoolsPanelProps> = (props) => {
|
|
|
787
959
|
</DropdownMenu.Root>
|
|
788
960
|
</div>
|
|
789
961
|
</div>
|
|
790
|
-
<
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
<
|
|
798
|
-
{(
|
|
799
|
-
|
|
962
|
+
<Show when={selectedView() === 'queries'}>
|
|
963
|
+
<div
|
|
964
|
+
class={cx(
|
|
965
|
+
styles().overflowQueryContainer,
|
|
966
|
+
'tsqd-queries-overflow-container',
|
|
967
|
+
)}
|
|
968
|
+
>
|
|
969
|
+
<div class="tsqd-queries-container">
|
|
970
|
+
<Key by={(q) => q.queryHash} each={queries()}>
|
|
971
|
+
{(query) => <QueryRow query={query()} />}
|
|
972
|
+
</Key>
|
|
973
|
+
</div>
|
|
800
974
|
</div>
|
|
801
|
-
</
|
|
975
|
+
</Show>
|
|
976
|
+
<Show when={selectedView() === 'mutations'}>
|
|
977
|
+
<div
|
|
978
|
+
class={cx(
|
|
979
|
+
styles().overflowQueryContainer,
|
|
980
|
+
'tsqd-mutations-overflow-container',
|
|
981
|
+
)}
|
|
982
|
+
>
|
|
983
|
+
<div class="tsqd-mutations-container">
|
|
984
|
+
<Key by={(m) => m.mutationId} each={mutations()}>
|
|
985
|
+
{(mutation) => <MutationRow mutation={mutation()} />}
|
|
986
|
+
</Key>
|
|
987
|
+
</div>
|
|
988
|
+
</div>
|
|
989
|
+
</Show>
|
|
802
990
|
</div>
|
|
803
|
-
<Show when={selectedQueryHash()}>
|
|
991
|
+
<Show when={selectedView() === 'queries' && selectedQueryHash()}>
|
|
804
992
|
<QueryDetails />
|
|
805
993
|
</Show>
|
|
806
|
-
|
|
994
|
+
|
|
995
|
+
<Show when={selectedView() === 'mutations' && selectedMutationId()}>
|
|
996
|
+
<MutationDetails />
|
|
997
|
+
</Show>
|
|
998
|
+
</>
|
|
807
999
|
)
|
|
808
1000
|
}
|
|
809
1001
|
|
|
@@ -907,6 +1099,114 @@ export const QueryRow: Component<{ query: Query }> = (props) => {
|
|
|
907
1099
|
)
|
|
908
1100
|
}
|
|
909
1101
|
|
|
1102
|
+
export const MutationRow: Component<{ mutation: Mutation }> = (props) => {
|
|
1103
|
+
const theme = useTheme()
|
|
1104
|
+
const styles = createMemo(() => {
|
|
1105
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1106
|
+
})
|
|
1107
|
+
|
|
1108
|
+
const { colors, alpha } = tokens
|
|
1109
|
+
const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
|
|
1110
|
+
|
|
1111
|
+
const mutationState = createSubscribeToMutationCacheBatcher(
|
|
1112
|
+
(mutationCache) => {
|
|
1113
|
+
const mutations = mutationCache().getAll()
|
|
1114
|
+
const mutation = mutations.find(
|
|
1115
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1116
|
+
)
|
|
1117
|
+
return mutation?.state
|
|
1118
|
+
},
|
|
1119
|
+
)
|
|
1120
|
+
|
|
1121
|
+
const isPaused = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1122
|
+
const mutations = mutationCache().getAll()
|
|
1123
|
+
const mutation = mutations.find(
|
|
1124
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1125
|
+
)
|
|
1126
|
+
if (!mutation) return false
|
|
1127
|
+
return mutation.state.isPaused
|
|
1128
|
+
})
|
|
1129
|
+
|
|
1130
|
+
const status = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1131
|
+
const mutations = mutationCache().getAll()
|
|
1132
|
+
const mutation = mutations.find(
|
|
1133
|
+
(m) => m.mutationId === props.mutation.mutationId,
|
|
1134
|
+
)
|
|
1135
|
+
if (!mutation) return 'idle'
|
|
1136
|
+
return mutation.state.status
|
|
1137
|
+
})
|
|
1138
|
+
|
|
1139
|
+
const color = createMemo(() =>
|
|
1140
|
+
getMutationStatusColor({
|
|
1141
|
+
isPaused: isPaused(),
|
|
1142
|
+
status: status(),
|
|
1143
|
+
}),
|
|
1144
|
+
)
|
|
1145
|
+
|
|
1146
|
+
const getObserverCountColorStyles = () => {
|
|
1147
|
+
if (color() === 'gray') {
|
|
1148
|
+
return css`
|
|
1149
|
+
background-color: ${t(colors[color()][200], colors[color()][700])};
|
|
1150
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1151
|
+
`
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
return css`
|
|
1155
|
+
background-color: ${t(
|
|
1156
|
+
colors[color()][200] + alpha[80],
|
|
1157
|
+
colors[color()][900],
|
|
1158
|
+
)};
|
|
1159
|
+
color: ${t(colors[color()][800], colors[color()][300])};
|
|
1160
|
+
`
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
return (
|
|
1164
|
+
<Show when={mutationState()}>
|
|
1165
|
+
<button
|
|
1166
|
+
onClick={() => {
|
|
1167
|
+
setSelectedMutationId(
|
|
1168
|
+
props.mutation.mutationId === selectedMutationId()
|
|
1169
|
+
? null
|
|
1170
|
+
: props.mutation.mutationId,
|
|
1171
|
+
)
|
|
1172
|
+
}}
|
|
1173
|
+
class={cx(
|
|
1174
|
+
styles().queryRow,
|
|
1175
|
+
selectedMutationId() === props.mutation.mutationId &&
|
|
1176
|
+
styles().selectedQueryRow,
|
|
1177
|
+
'tsqd-query-row',
|
|
1178
|
+
)}
|
|
1179
|
+
aria-label={`Mutation submitted at ${new Date(
|
|
1180
|
+
props.mutation.state.submittedAt,
|
|
1181
|
+
).toLocaleString()}`}
|
|
1182
|
+
>
|
|
1183
|
+
<div
|
|
1184
|
+
class={cx(getObserverCountColorStyles(), 'tsqd-query-observer-count')}
|
|
1185
|
+
>
|
|
1186
|
+
<Show when={color() === 'purple'}>
|
|
1187
|
+
<PauseCircle />
|
|
1188
|
+
</Show>
|
|
1189
|
+
<Show when={color() === 'green'}>
|
|
1190
|
+
<CheckCircle />
|
|
1191
|
+
</Show>
|
|
1192
|
+
<Show when={color() === 'red'}>
|
|
1193
|
+
<XCircle />
|
|
1194
|
+
</Show>
|
|
1195
|
+
<Show when={color() === 'yellow'}>
|
|
1196
|
+
<LoadingCircle />
|
|
1197
|
+
</Show>
|
|
1198
|
+
</div>
|
|
1199
|
+
<code class="tsqd-query-hash">
|
|
1200
|
+
<Show when={props.mutation.options.mutationKey}>
|
|
1201
|
+
{JSON.stringify(props.mutation.options.mutationKey)} -{' '}
|
|
1202
|
+
</Show>
|
|
1203
|
+
{new Date(props.mutation.state.submittedAt).toLocaleString()}
|
|
1204
|
+
</code>
|
|
1205
|
+
</button>
|
|
1206
|
+
</Show>
|
|
1207
|
+
)
|
|
1208
|
+
}
|
|
1209
|
+
|
|
910
1210
|
export const QueryStatusCount: Component = () => {
|
|
911
1211
|
const stale = createSubscribeToQueryCacheBatcher(
|
|
912
1212
|
(queryCache) =>
|
|
@@ -961,6 +1261,76 @@ export const QueryStatusCount: Component = () => {
|
|
|
961
1261
|
)
|
|
962
1262
|
}
|
|
963
1263
|
|
|
1264
|
+
export const MutationStatusCount: Component = () => {
|
|
1265
|
+
const success = createSubscribeToMutationCacheBatcher(
|
|
1266
|
+
(mutationCache) =>
|
|
1267
|
+
mutationCache()
|
|
1268
|
+
.getAll()
|
|
1269
|
+
.filter(
|
|
1270
|
+
(m) =>
|
|
1271
|
+
getMutationStatusColor({
|
|
1272
|
+
isPaused: m.state.isPaused,
|
|
1273
|
+
status: m.state.status,
|
|
1274
|
+
}) === 'green',
|
|
1275
|
+
).length,
|
|
1276
|
+
)
|
|
1277
|
+
|
|
1278
|
+
const pending = createSubscribeToMutationCacheBatcher(
|
|
1279
|
+
(mutationCache) =>
|
|
1280
|
+
mutationCache()
|
|
1281
|
+
.getAll()
|
|
1282
|
+
.filter(
|
|
1283
|
+
(m) =>
|
|
1284
|
+
getMutationStatusColor({
|
|
1285
|
+
isPaused: m.state.isPaused,
|
|
1286
|
+
status: m.state.status,
|
|
1287
|
+
}) === 'yellow',
|
|
1288
|
+
).length,
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
const paused = createSubscribeToMutationCacheBatcher(
|
|
1292
|
+
(mutationCache) =>
|
|
1293
|
+
mutationCache()
|
|
1294
|
+
.getAll()
|
|
1295
|
+
.filter(
|
|
1296
|
+
(m) =>
|
|
1297
|
+
getMutationStatusColor({
|
|
1298
|
+
isPaused: m.state.isPaused,
|
|
1299
|
+
status: m.state.status,
|
|
1300
|
+
}) === 'purple',
|
|
1301
|
+
).length,
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
const error = createSubscribeToMutationCacheBatcher(
|
|
1305
|
+
(mutationCache) =>
|
|
1306
|
+
mutationCache()
|
|
1307
|
+
.getAll()
|
|
1308
|
+
.filter(
|
|
1309
|
+
(m) =>
|
|
1310
|
+
getMutationStatusColor({
|
|
1311
|
+
isPaused: m.state.isPaused,
|
|
1312
|
+
status: m.state.status,
|
|
1313
|
+
}) === 'red',
|
|
1314
|
+
).length,
|
|
1315
|
+
)
|
|
1316
|
+
|
|
1317
|
+
const theme = useTheme()
|
|
1318
|
+
const styles = createMemo(() => {
|
|
1319
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1320
|
+
})
|
|
1321
|
+
|
|
1322
|
+
return (
|
|
1323
|
+
<div
|
|
1324
|
+
class={cx(styles().queryStatusContainer, 'tsqd-query-status-container')}
|
|
1325
|
+
>
|
|
1326
|
+
<QueryStatus label="Paused" color="purple" count={paused()} />
|
|
1327
|
+
<QueryStatus label="Pending" color="yellow" count={pending()} />
|
|
1328
|
+
<QueryStatus label="Success" color="green" count={success()} />
|
|
1329
|
+
<QueryStatus label="Error" color="red" count={error()} />
|
|
1330
|
+
</div>
|
|
1331
|
+
)
|
|
1332
|
+
}
|
|
1333
|
+
|
|
964
1334
|
export const QueryStatus: Component<QueryStatusProps> = (props) => {
|
|
965
1335
|
const theme = useTheme()
|
|
966
1336
|
const styles = createMemo(() => {
|
|
@@ -1462,7 +1832,170 @@ const QueryDetails = () => {
|
|
|
1462
1832
|
)
|
|
1463
1833
|
}
|
|
1464
1834
|
|
|
1465
|
-
const
|
|
1835
|
+
const MutationDetails = () => {
|
|
1836
|
+
const theme = useTheme()
|
|
1837
|
+
const styles = createMemo(() => {
|
|
1838
|
+
return theme() === 'dark' ? darkStyles : lightStyles
|
|
1839
|
+
})
|
|
1840
|
+
|
|
1841
|
+
const { colors } = tokens
|
|
1842
|
+
const t = (light: string, dark: string) => (theme() === 'dark' ? dark : light)
|
|
1843
|
+
|
|
1844
|
+
const isPaused = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1845
|
+
const mutations = mutationCache().getAll()
|
|
1846
|
+
const mutation = mutations.find(
|
|
1847
|
+
(m) => m.mutationId === selectedMutationId(),
|
|
1848
|
+
)
|
|
1849
|
+
if (!mutation) return false
|
|
1850
|
+
return mutation.state.isPaused
|
|
1851
|
+
})
|
|
1852
|
+
|
|
1853
|
+
const status = createSubscribeToMutationCacheBatcher((mutationCache) => {
|
|
1854
|
+
const mutations = mutationCache().getAll()
|
|
1855
|
+
const mutation = mutations.find(
|
|
1856
|
+
(m) => m.mutationId === selectedMutationId(),
|
|
1857
|
+
)
|
|
1858
|
+
if (!mutation) return 'idle'
|
|
1859
|
+
return mutation.state.status
|
|
1860
|
+
})
|
|
1861
|
+
|
|
1862
|
+
const color = createMemo(() =>
|
|
1863
|
+
getMutationStatusColor({
|
|
1864
|
+
isPaused: isPaused(),
|
|
1865
|
+
status: status(),
|
|
1866
|
+
}),
|
|
1867
|
+
)
|
|
1868
|
+
|
|
1869
|
+
const activeMutation = createSubscribeToMutationCacheBatcher(
|
|
1870
|
+
(mutationCache) =>
|
|
1871
|
+
mutationCache()
|
|
1872
|
+
.getAll()
|
|
1873
|
+
.find((mutation) => mutation.mutationId === selectedMutationId()),
|
|
1874
|
+
false,
|
|
1875
|
+
)
|
|
1876
|
+
|
|
1877
|
+
const getQueryStatusColors = () => {
|
|
1878
|
+
if (color() === 'gray') {
|
|
1879
|
+
return css`
|
|
1880
|
+
background-color: ${t(colors[color()][200], colors[color()][700])};
|
|
1881
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1882
|
+
border-color: ${t(colors[color()][400], colors[color()][600])};
|
|
1883
|
+
`
|
|
1884
|
+
}
|
|
1885
|
+
return css`
|
|
1886
|
+
background-color: ${t(colors[color()][100], colors[color()][900])};
|
|
1887
|
+
color: ${t(colors[color()][700], colors[color()][300])};
|
|
1888
|
+
border-color: ${t(colors[color()][400], colors[color()][600])};
|
|
1889
|
+
`
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
return (
|
|
1893
|
+
<Show when={activeMutation()}>
|
|
1894
|
+
<div
|
|
1895
|
+
class={cx(styles().detailsContainer, 'tsqd-query-details-container')}
|
|
1896
|
+
>
|
|
1897
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1898
|
+
Mutation Details
|
|
1899
|
+
</div>
|
|
1900
|
+
<div
|
|
1901
|
+
class={cx(
|
|
1902
|
+
styles().detailsBody,
|
|
1903
|
+
'tsqd-query-details-summary-container',
|
|
1904
|
+
)}
|
|
1905
|
+
>
|
|
1906
|
+
<div class="tsqd-query-details-summary">
|
|
1907
|
+
<pre>
|
|
1908
|
+
<code>
|
|
1909
|
+
<Show
|
|
1910
|
+
when={activeMutation()!.options.mutationKey}
|
|
1911
|
+
fallback={'No mutationKey found'}
|
|
1912
|
+
>
|
|
1913
|
+
{displayValue(activeMutation()!.options.mutationKey, true)}
|
|
1914
|
+
</Show>
|
|
1915
|
+
</code>
|
|
1916
|
+
</pre>
|
|
1917
|
+
<span
|
|
1918
|
+
class={cx(styles().queryDetailsStatus, getQueryStatusColors())}
|
|
1919
|
+
>
|
|
1920
|
+
<Show when={color() === 'purple'}>pending</Show>
|
|
1921
|
+
<Show when={color() !== 'purple'}>{status()}</Show>
|
|
1922
|
+
</span>
|
|
1923
|
+
</div>
|
|
1924
|
+
<div class="tsqd-query-details-last-updated">
|
|
1925
|
+
<span>Submitted At:</span>
|
|
1926
|
+
<span>
|
|
1927
|
+
{new Date(
|
|
1928
|
+
activeMutation()!.state.submittedAt,
|
|
1929
|
+
).toLocaleTimeString()}
|
|
1930
|
+
</span>
|
|
1931
|
+
</div>
|
|
1932
|
+
</div>
|
|
1933
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1934
|
+
Variables Details
|
|
1935
|
+
</div>
|
|
1936
|
+
<div
|
|
1937
|
+
style={{
|
|
1938
|
+
padding: '0.5rem',
|
|
1939
|
+
}}
|
|
1940
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1941
|
+
>
|
|
1942
|
+
<Explorer
|
|
1943
|
+
label="Variables"
|
|
1944
|
+
defaultExpanded={['Variables']}
|
|
1945
|
+
value={activeMutation()!.state.variables}
|
|
1946
|
+
/>
|
|
1947
|
+
</div>
|
|
1948
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1949
|
+
Context Details
|
|
1950
|
+
</div>
|
|
1951
|
+
<div
|
|
1952
|
+
style={{
|
|
1953
|
+
padding: '0.5rem',
|
|
1954
|
+
}}
|
|
1955
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1956
|
+
>
|
|
1957
|
+
<Explorer
|
|
1958
|
+
label="Context"
|
|
1959
|
+
defaultExpanded={['Context']}
|
|
1960
|
+
value={activeMutation()!.state.context}
|
|
1961
|
+
/>
|
|
1962
|
+
</div>
|
|
1963
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1964
|
+
Data Explorer
|
|
1965
|
+
</div>
|
|
1966
|
+
<div
|
|
1967
|
+
style={{
|
|
1968
|
+
padding: '0.5rem',
|
|
1969
|
+
}}
|
|
1970
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1971
|
+
>
|
|
1972
|
+
<Explorer
|
|
1973
|
+
label="Data"
|
|
1974
|
+
defaultExpanded={['Data']}
|
|
1975
|
+
value={activeMutation()!.state.data}
|
|
1976
|
+
/>
|
|
1977
|
+
</div>
|
|
1978
|
+
<div class={cx(styles().detailsHeader, 'tsqd-query-details-header')}>
|
|
1979
|
+
Mutations Explorer
|
|
1980
|
+
</div>
|
|
1981
|
+
<div
|
|
1982
|
+
style={{
|
|
1983
|
+
padding: '0.5rem',
|
|
1984
|
+
}}
|
|
1985
|
+
class="tsqd-query-details-explorer-container tsqd-query-details-query-explorer"
|
|
1986
|
+
>
|
|
1987
|
+
<Explorer
|
|
1988
|
+
label="Mutation"
|
|
1989
|
+
defaultExpanded={['Mutation']}
|
|
1990
|
+
value={activeMutation()}
|
|
1991
|
+
/>
|
|
1992
|
+
</div>
|
|
1993
|
+
</div>
|
|
1994
|
+
</Show>
|
|
1995
|
+
)
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
const queryCacheMap = new Map<(q: Accessor<QueryCache>) => any, Setter<any>>()
|
|
1466
1999
|
|
|
1467
2000
|
const setupQueryCacheSubscription = () => {
|
|
1468
2001
|
const queryCache = createMemo(() => {
|
|
@@ -1471,7 +2004,7 @@ const setupQueryCacheSubscription = () => {
|
|
|
1471
2004
|
})
|
|
1472
2005
|
|
|
1473
2006
|
const unsub = queryCache().subscribe(() => {
|
|
1474
|
-
for (const [callback, setter] of
|
|
2007
|
+
for (const [callback, setter] of queryCacheMap.entries()) {
|
|
1475
2008
|
queueMicrotask(() => {
|
|
1476
2009
|
setter(callback(queryCache))
|
|
1477
2010
|
})
|
|
@@ -1479,7 +2012,7 @@ const setupQueryCacheSubscription = () => {
|
|
|
1479
2012
|
})
|
|
1480
2013
|
|
|
1481
2014
|
onCleanup(() => {
|
|
1482
|
-
|
|
2015
|
+
queryCacheMap.clear()
|
|
1483
2016
|
unsub()
|
|
1484
2017
|
})
|
|
1485
2018
|
|
|
@@ -1505,11 +2038,67 @@ const createSubscribeToQueryCacheBatcher = <T,>(
|
|
|
1505
2038
|
})
|
|
1506
2039
|
|
|
1507
2040
|
// @ts-ignore
|
|
1508
|
-
|
|
2041
|
+
queryCacheMap.set(callback, setValue)
|
|
1509
2042
|
|
|
1510
2043
|
onCleanup(() => {
|
|
1511
2044
|
// @ts-ignore
|
|
1512
|
-
|
|
2045
|
+
queryCacheMap.delete(callback)
|
|
2046
|
+
})
|
|
2047
|
+
|
|
2048
|
+
return value
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
const mutationCacheMap = new Map<
|
|
2052
|
+
(q: Accessor<MutationCache>) => any,
|
|
2053
|
+
Setter<any>
|
|
2054
|
+
>()
|
|
2055
|
+
|
|
2056
|
+
const setupMutationCacheSubscription = () => {
|
|
2057
|
+
const mutationCache = createMemo(() => {
|
|
2058
|
+
const client = useQueryDevtoolsContext().client
|
|
2059
|
+
return client.getMutationCache()
|
|
2060
|
+
})
|
|
2061
|
+
|
|
2062
|
+
const unsub = mutationCache().subscribe(() => {
|
|
2063
|
+
for (const [callback, setter] of mutationCacheMap.entries()) {
|
|
2064
|
+
queueMicrotask(() => {
|
|
2065
|
+
setter(callback(mutationCache))
|
|
2066
|
+
})
|
|
2067
|
+
}
|
|
2068
|
+
})
|
|
2069
|
+
|
|
2070
|
+
onCleanup(() => {
|
|
2071
|
+
mutationCacheMap.clear()
|
|
2072
|
+
unsub()
|
|
2073
|
+
})
|
|
2074
|
+
|
|
2075
|
+
return unsub
|
|
2076
|
+
}
|
|
2077
|
+
|
|
2078
|
+
const createSubscribeToMutationCacheBatcher = <T,>(
|
|
2079
|
+
callback: (queryCache: Accessor<MutationCache>) => Exclude<T, Function>,
|
|
2080
|
+
equalityCheck: boolean = true,
|
|
2081
|
+
) => {
|
|
2082
|
+
const mutationCache = createMemo(() => {
|
|
2083
|
+
const client = useQueryDevtoolsContext().client
|
|
2084
|
+
return client.getMutationCache()
|
|
2085
|
+
})
|
|
2086
|
+
|
|
2087
|
+
const [value, setValue] = createSignal<T>(
|
|
2088
|
+
callback(mutationCache),
|
|
2089
|
+
!equalityCheck ? { equals: false } : undefined,
|
|
2090
|
+
)
|
|
2091
|
+
|
|
2092
|
+
createEffect(() => {
|
|
2093
|
+
setValue(callback(mutationCache))
|
|
2094
|
+
})
|
|
2095
|
+
|
|
2096
|
+
// @ts-ignore
|
|
2097
|
+
mutationCacheMap.set(callback, setValue)
|
|
2098
|
+
|
|
2099
|
+
onCleanup(() => {
|
|
2100
|
+
// @ts-ignore
|
|
2101
|
+
mutationCacheMap.delete(callback)
|
|
1513
2102
|
})
|
|
1514
2103
|
|
|
1515
2104
|
return value
|
|
@@ -1788,7 +2377,7 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1788
2377
|
justify-content: space-between;
|
|
1789
2378
|
align-items: center;
|
|
1790
2379
|
padding: ${tokens.size[2]} ${tokens.size[2.5]};
|
|
1791
|
-
gap: ${tokens.size[
|
|
2380
|
+
gap: ${tokens.size[2.5]};
|
|
1792
2381
|
border-bottom: ${t(colors.gray[300], colors.darkGray[500])} 1px solid;
|
|
1793
2382
|
align-items: center;
|
|
1794
2383
|
& > button {
|
|
@@ -1800,8 +2389,19 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
1800
2389
|
flex-direction: column;
|
|
1801
2390
|
}
|
|
1802
2391
|
`,
|
|
2392
|
+
logoAndToggleContainer: css`
|
|
2393
|
+
display: flex;
|
|
2394
|
+
gap: ${tokens.size[3]};
|
|
2395
|
+
align-items: center;
|
|
2396
|
+
`,
|
|
1803
2397
|
logo: css`
|
|
1804
2398
|
cursor: pointer;
|
|
2399
|
+
display: flex;
|
|
2400
|
+
flex-direction: column;
|
|
2401
|
+
background-color: transparent;
|
|
2402
|
+
border: none;
|
|
2403
|
+
gap: ${tokens.size[0.5]};
|
|
2404
|
+
padding: 0px;
|
|
1805
2405
|
&:hover {
|
|
1806
2406
|
opacity: 0.7;
|
|
1807
2407
|
}
|
|
@@ -2173,6 +2773,8 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
2173
2773
|
|
|
2174
2774
|
& pre {
|
|
2175
2775
|
margin: 0;
|
|
2776
|
+
display: flex;
|
|
2777
|
+
align-items: center;
|
|
2176
2778
|
}
|
|
2177
2779
|
`,
|
|
2178
2780
|
queryDetailsStatus: css`
|
|
@@ -2353,6 +2955,56 @@ const stylesFactory = (theme: 'light' | 'dark') => {
|
|
|
2353
2955
|
background-color: ${t(colors.purple[100], colors.purple[900])};
|
|
2354
2956
|
}
|
|
2355
2957
|
`,
|
|
2958
|
+
viewToggle: css`
|
|
2959
|
+
border-radius: ${tokens.border.radius.sm};
|
|
2960
|
+
background-color: ${t(colors.gray[200], colors.darkGray[600])};
|
|
2961
|
+
border: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
|
|
2962
|
+
display: flex;
|
|
2963
|
+
padding: 0;
|
|
2964
|
+
font-size: ${font.size.xs};
|
|
2965
|
+
color: ${t(colors.gray[700], colors.gray[300])};
|
|
2966
|
+
overflow: hidden;
|
|
2967
|
+
|
|
2968
|
+
&:has(:focus-visible) {
|
|
2969
|
+
outline: 2px solid ${colors.blue[800]};
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
& .tsqd-radio-toggle {
|
|
2973
|
+
opacity: 0.5;
|
|
2974
|
+
display: flex;
|
|
2975
|
+
& label {
|
|
2976
|
+
display: flex;
|
|
2977
|
+
align-items: center;
|
|
2978
|
+
cursor: pointer;
|
|
2979
|
+
line-height: ${font.lineHeight.md};
|
|
2980
|
+
}
|
|
2981
|
+
|
|
2982
|
+
& label:hover {
|
|
2983
|
+
background-color: ${t(colors.gray[100], colors.darkGray[500])};
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2987
|
+
& > [data-checked] {
|
|
2988
|
+
opacity: 1;
|
|
2989
|
+
background-color: ${t(colors.gray[100], colors.darkGray[400])};
|
|
2990
|
+
& label:hover {
|
|
2991
|
+
background-color: ${t(colors.gray[100], colors.darkGray[400])};
|
|
2992
|
+
}
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2995
|
+
& .tsqd-radio-toggle:first-child {
|
|
2996
|
+
& label {
|
|
2997
|
+
padding: 0 ${tokens.size[1.5]} 0 ${tokens.size[2]};
|
|
2998
|
+
}
|
|
2999
|
+
border-right: 1px solid ${t(colors.gray[300], colors.darkGray[200])};
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
& .tsqd-radio-toggle:nth-child(2) {
|
|
3003
|
+
& label {
|
|
3004
|
+
padding: 0 ${tokens.size[2]} 0 ${tokens.size[1.5]};
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
`,
|
|
2356
3008
|
}
|
|
2357
3009
|
}
|
|
2358
3010
|
|