Files
goldenChart/frontend/src/utils/marketStorage.ts
T
2026-05-28 14:44:19 +09:00

92 lines
2.6 KiB
TypeScript

/**
* 관심종목(즐겨찾기) / 보유종목 관리
* - DB(gc_watchlist / gc_holdings)가 기준 저장소
* - 메모리 캐시만 사용 (localStorage 미사용)
*/
import { addWatchlistItem, removeWatchlistItem } from './backendApi';
/** 관심종목 변경 시 MarketSearchPanel·App 등이 동기화하도록 발행 */
export const FAVORITES_CHANGED_EVENT = 'gc-favorites-changed';
let favoritesCache: string[] | null = null;
let holdingsCache: string[] | null = null;
/** DB 로드 후 App·워크스페이스 훅에서 호출 */
export function initFavoritesFromDb(symbols: string[]): void {
favoritesCache = [...symbols];
window.dispatchEvent(new CustomEvent(FAVORITES_CHANGED_EVENT, { detail: favoritesCache }));
}
export function initHoldingsFromDb(symbols: string[]): void {
holdingsCache = [...symbols];
}
export function getFavorites(): string[] {
return favoritesCache ?? [];
}
export function saveFavorites(markets: string[], notify = true): void {
favoritesCache = [...markets];
if (notify) {
window.dispatchEvent(new CustomEvent(FAVORITES_CHANGED_EVENT, { detail: markets }));
}
}
/**
* 관심종목 토글 — DB 저장 + 실시간 전략 체크 대상 자동 연동(백엔드).
* @returns 변경 후 관심종목 코드 목록
*/
export async function toggleFavorite(
market: string,
meta?: { koreanName?: string; englishName?: string },
): Promise<string[]> {
const list = getFavorites();
let next: string[];
if (list.includes(market)) {
await removeWatchlistItem(market);
next = list.filter(m => m !== market);
} else {
await addWatchlistItem({
symbol: market,
koreanName: meta?.koreanName,
englishName: meta?.englishName,
});
next = [...list, market];
}
saveFavorites(next);
return next;
}
export function isFavorite(market: string): boolean {
return getFavorites().includes(market);
}
export function getHoldings(): string[] {
return holdingsCache ?? [];
}
export function saveHoldings(markets: string[]): void {
holdingsCache = [...markets];
}
/** 추가 → 변경 후 전체 목록 반환 (중복 무시) */
export function addHolding(market: string): string[] {
const list = getHoldings();
if (list.includes(market)) return list;
const next = [...list, market];
saveHoldings(next);
return next;
}
/** 제거 → 변경 후 전체 목록 반환 */
export function removeHolding(market: string): string[] {
const next = getHoldings().filter(m => m !== market);
saveHoldings(next);
return next;
}
export function isHolding(market: string): boolean {
return getHoldings().includes(market);
}