Core: remove hook-level cache from useDocsSearch()

This commit is contained in:
Fuma Nama
2025-03-03 18:52:08 +08:00
parent 00c386dbf1
commit 2035cb18df
4 changed files with 31 additions and 24 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-core': patch
---
remove hook-level cache from `useDocsSearch()`
+4 -20
View File
@@ -1,4 +1,4 @@
import { useMemo, useRef, useState } from 'react';
import { useRef, useState } from 'react';
import { useDebounce } from '@/utils/use-debounce';
import type { SortedResult } from '@/server/types';
import { type FetchOptions } from '@/search/client/fetch';
@@ -17,8 +17,6 @@ interface UseDocsSearch {
};
}
const cache = new Map<string, SortedResult[] | 'empty'>();
export type Client =
| ({
type: 'fetch';
@@ -58,25 +56,12 @@ export function useDocsSearch(
const debouncedValue = useDebounce(search, delayMs);
const onStart = useRef<() => void>(undefined);
const cacheKey = useMemo(() => {
return key ?? JSON.stringify([client.type, debouncedValue, locale, tag]);
}, [client.type, debouncedValue, locale, tag, key]);
useOnChange(cacheKey, () => {
const cached = cache.get(cacheKey);
useOnChange(key ?? [client, debouncedValue, locale, tag], () => {
if (onStart.current) {
onStart.current();
onStart.current = undefined;
}
if (cached) {
setIsLoading(false);
setError(undefined);
setResults(cached);
return;
}
setIsLoading(true);
let interrupt = false;
onStart.current = () => {
@@ -112,14 +97,13 @@ export function useDocsSearch(
void run()
.then((res) => {
cache.set(cacheKey, res);
if (interrupt) return;
setError(undefined);
setResults(res);
})
.catch((err: unknown) => {
setError(err as Error);
.catch((err: Error) => {
setError(err);
})
.finally(() => {
setIsLoading(false);
+10 -4
View File
@@ -7,6 +7,8 @@ export interface FetchOptions {
api?: string;
}
const cache = new Map<string, SortedResult[]>();
export async function fetchDocs(
query: string,
locale: string | undefined,
@@ -18,10 +20,14 @@ export async function fetchDocs(
if (locale) params.set('locale', locale);
if (tag) params.set('tag', tag);
const res = await fetch(
`${options.api ?? '/api/search'}?${params.toString()}`,
);
const key = `${options.api ?? '/api/search'}?${params}`;
const cached = cache.get(key);
if (cached) return cached;
const res = await fetch(key);
if (!res.ok) throw new Error(await res.text());
return (await res.json()) as SortedResult[];
const result = (await res.json()) as SortedResult[];
cache.set(key, result);
return result;
}
+12
View File
@@ -5,6 +5,18 @@ function isDifferent(a: unknown, b: unknown): boolean {
return b.length !== a.length || a.some((v, i) => isDifferent(v, b[i]));
}
if (typeof a === 'object' && a && typeof b === 'object' && b) {
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
return (
aKeys.length !== bKeys.length ||
aKeys.some((key) =>
isDifferent(a[key as keyof object], b[key as keyof object]),
)
);
}
return a !== b;
}