Pulse/frontend-modern/src/utils/searchHistory.ts
2025-10-11 23:29:47 +00:00

87 lines
2.3 KiB
TypeScript

const DEFAULT_MAX_HISTORY = 10;
type HistoryEntry = string;
function isBrowser(): boolean {
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
}
function readHistory(key: string): HistoryEntry[] {
if (!isBrowser()) {
return [];
}
try {
const raw = window.localStorage.getItem(key);
if (!raw) {
return [];
}
const parsed = JSON.parse(raw);
if (!Array.isArray(parsed)) {
return [];
}
return parsed.filter((value): value is string => typeof value === 'string');
} catch (error) {
console.warn(`[searchHistory] Failed to parse history for key "${key}":`, error);
return [];
}
}
function writeHistory(key: string, history: HistoryEntry[]): void {
if (!isBrowser()) {
return;
}
try {
window.localStorage.setItem(key, JSON.stringify(history));
} catch (error) {
console.warn(`[searchHistory] Failed to persist history for key "${key}":`, error);
}
}
export function getSearchHistory(key: string): HistoryEntry[] {
return readHistory(key);
}
export function addSearchHistory(
key: string,
term: string,
maxEntries: number = DEFAULT_MAX_HISTORY,
): HistoryEntry[] {
const trimmed = term.trim();
if (!trimmed) {
return readHistory(key);
}
const history = readHistory(key);
const lowerTerm = trimmed.toLowerCase();
const filtered = history.filter((entry) => entry.toLowerCase() !== lowerTerm);
const nextHistory = [trimmed, ...filtered].slice(0, Math.max(1, maxEntries));
writeHistory(key, nextHistory);
return nextHistory;
}
export function removeSearchHistory(key: string, term: string): HistoryEntry[] {
const history = readHistory(key);
const nextHistory = history.filter((entry) => entry !== term);
writeHistory(key, nextHistory);
return nextHistory;
}
export function clearSearchHistory(key: string): HistoryEntry[] {
writeHistory(key, []);
return [];
}
export function createSearchHistoryManager(
key: string,
options?: { maxEntries?: number },
) {
const maxEntries = options?.maxEntries ?? DEFAULT_MAX_HISTORY;
const read = () => getSearchHistory(key);
const add = (term: string) => addSearchHistory(key, term, maxEntries);
const remove = (term: string) => removeSearchHistory(key, term);
const clear = () => clearSearchHistory(key);
return { read, add, remove, clear };
}