30 lines
904 B
TypeScript
30 lines
904 B
TypeScript
|
|
export const SEARCH_QUERY_CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
||
|
|
|
||
|
|
export function normalizeSearchQuery(value: string | null | undefined) {
|
||
|
|
const normalized = value?.trim().toLowerCase() ?? "";
|
||
|
|
return normalized || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export function hasReusableSearchPayload(candidate: { resultCount: number; answerText?: string | null }) {
|
||
|
|
return candidate.resultCount > 0 || Boolean(candidate.answerText?.trim());
|
||
|
|
}
|
||
|
|
|
||
|
|
export function isFreshSearchCacheHit(
|
||
|
|
candidate: {
|
||
|
|
updatedAt: Date | string;
|
||
|
|
resultCount: number;
|
||
|
|
answerText?: string | null;
|
||
|
|
isActive?: boolean;
|
||
|
|
},
|
||
|
|
now = new Date(),
|
||
|
|
ttlMs = SEARCH_QUERY_CACHE_TTL_MS
|
||
|
|
) {
|
||
|
|
if (candidate.isActive) return false;
|
||
|
|
if (!hasReusableSearchPayload(candidate)) return false;
|
||
|
|
|
||
|
|
const updatedAtMs = new Date(candidate.updatedAt).getTime();
|
||
|
|
if (!Number.isFinite(updatedAtMs)) return false;
|
||
|
|
|
||
|
|
return now.getTime() - updatedAtMs <= ttlMs;
|
||
|
|
}
|