Skip to content

Commit 9713e5b

Browse files
authored
feat: Add fetching for exact match for faster results (#12)
* fix: search input not clearing when pressing "X" button * feat: add use-fetch-key-type * feat: add fetching for exact match on search for quicker results * fix: send exact match request before other requests
1 parent c8c93b5 commit 9713e5b

File tree

5 files changed

+47
-3
lines changed

5 files changed

+47
-3
lines changed

src/components/databrowser/components/sidebar/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button"
55
import { Spinner } from "@/components/ui/spinner"
66

77
import { FETCH_LIST_ITEMS_QUERY_KEY, FETCH_SIMPLE_KEY_QUERY_KEY } from "../../hooks"
8+
import { FETCH_KEY_TYPE_QUERY_KEY } from "../../hooks/use-fetch-key-type"
89
import { useKeys } from "../../hooks/use-keys"
910
import { AddKeyModal } from "../add-key-modal"
1011
import { DisplayDbSize, FETCH_DB_SIZE_QUERY_KEY } from "./db-size"
@@ -38,6 +39,9 @@ export function Sidebar() {
3839
queryClient.invalidateQueries({
3940
queryKey: [FETCH_DB_SIZE_QUERY_KEY],
4041
})
42+
queryClient.invalidateQueries({
43+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY],
44+
})
4145
}}
4246
>
4347
<Spinner isLoading={query.isFetching}>
@@ -58,9 +62,10 @@ export function Sidebar() {
5862
</div>
5963
</div>
6064

61-
{query.isLoading ? (
65+
{query.isLoading && keys.length === 0 ? (
6266
<LoadingSkeleton />
6367
) : keys.length > 0 ? (
68+
// Infinite scroll already has a loader at the bottom
6469
<InfiniteScroll query={query}>
6570
<KeysList />
6671
</InfiniteScroll>

src/components/databrowser/components/sidebar/search-input.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ export const SearchInput = () => {
2929
}}
3030
value={state}
3131
/>
32-
{search.key && (
32+
{state && (
3333
<Button
3434
type="button"
3535
variant="link"
3636
size="icon"
3737
className="absolute right-1 top-1/2 h-5 w-5 -translate-y-1/2 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100"
3838
onClick={() => {
3939
setSearchKey("")
40+
setState("")
4041
}}
4142
>
4243
<IconX size={16} />

src/components/databrowser/hooks/use-delete-key-cache.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { useDatabrowserStore } from "@/store"
33

44
import { queryClient } from "@/lib/clients"
55

6+
import { FETCH_KEY_TYPE_QUERY_KEY } from "./use-fetch-key-type"
7+
import { FETCH_LIST_ITEMS_QUERY_KEY } from "./use-fetch-list-items"
68
import { FETCH_SIMPLE_KEY_QUERY_KEY } from "./use-fetch-simple-key"
79
import { FETCH_KEYS_QUERY_KEY, useKeys } from "./use-keys"
810

@@ -19,6 +21,12 @@ export const useDeleteKeyCache = () => {
1921
queryClient.invalidateQueries({
2022
queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, key],
2123
})
24+
queryClient.invalidateQueries({
25+
queryKey: [FETCH_LIST_ITEMS_QUERY_KEY, key],
26+
})
27+
queryClient.invalidateQueries({
28+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key],
29+
})
2230
refetch()
2331
},
2432
[setSelectedKey, refetch]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { useDatabrowser } from "@/store"
2+
import { useQuery } from "@tanstack/react-query"
3+
4+
export const FETCH_KEY_TYPE_QUERY_KEY = "fetch-key-type"
5+
6+
export const useFetchKeyType = (key: string | undefined) => {
7+
const { redisNoPipeline: redis } = useDatabrowser()
8+
9+
return useQuery({
10+
queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key],
11+
queryFn: async () => {
12+
if (!key) return "none"
13+
14+
return await redis.type(key)
15+
},
16+
})
17+
}

src/components/databrowser/hooks/use-keys.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { useDatabrowserStore } from "@/store"
1010
import { useInfiniteQuery, type UseInfiniteQueryResult } from "@tanstack/react-query"
1111

12+
import { useFetchKeyType } from "./use-fetch-key-type"
1213
import { useFetchKeys, type RedisKey } from "./use-fetch-keys"
1314

1415
const KeysContext = createContext<
@@ -24,6 +25,9 @@ export const FETCH_KEYS_QUERY_KEY = "use-fetch-keys"
2425

2526
export const KeysProvider = ({ children }: PropsWithChildren) => {
2627
const { search } = useDatabrowserStore()
28+
const cleanSearchKey = search.key.replace("*", "")
29+
30+
const { data: exactMatchType } = useFetchKeyType(cleanSearchKey)
2731

2832
const { fetchKeys, resetCache } = useFetchKeys(search)
2933
const pageRef = useRef(0)
@@ -54,6 +58,15 @@ export const KeysProvider = ({ children }: PropsWithChildren) => {
5458
const keys = useMemo(() => {
5559
const keys = query.data?.pages.flatMap((page) => page.keys) ?? []
5660

61+
// Include the exact match if it exists before SCAN returns
62+
if (
63+
exactMatchType &&
64+
exactMatchType !== "none" &&
65+
(search.type === undefined || search.type === exactMatchType)
66+
) {
67+
keys.push([cleanSearchKey, exactMatchType])
68+
}
69+
5770
// deduplication
5871
const keysSet = new Set<string>()
5972
const dedupedKeys: RedisKey[] = []
@@ -65,7 +78,7 @@ export const KeysProvider = ({ children }: PropsWithChildren) => {
6578
dedupedKeys.push(key)
6679
}
6780
return dedupedKeys
68-
}, [query.data])
81+
}, [query.data, cleanSearchKey, exactMatchType])
6982

7083
return (
7184
<KeysContext.Provider

0 commit comments

Comments
 (0)