Files
sofa/lib/atoms/stats.ts
T
jakeandClaude Opus 4.6 f36ca0cbf8 Optimize performance: batch DB ops, N+1 fixes, Suspense streaming, and Jotai best practices
- Add composite indexes on userEpisodeWatches and userMovieWatches for hot queries
- Batch episode tracking: wrap season/batch watches in single transaction (~8 queries vs 8*N)
- Fix N+1 patterns in credits, recommendations, and filmography with batch prefetch+insert
- Stream TV season hydration via Suspense instead of blocking page render
- Optimize webhook logs (per-connection LIMIT 10) and system health queries
- Merge genre filter waterfalls into single Promise.all fetch
- Migrate deprecated Jotai loadable() to unwrap()
- Replace isolated createStore()+Provider with useHydrateAtoms on root store
- Remove unnecessary atomWithStorage SSR guards (handled by Jotai internally)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 17:33:27 -05:00

30 lines
921 B
TypeScript

import { atom } from "jotai";
import { unwrap } from "jotai/utils";
import type { HistoryBucket, TimePeriod } from "@/lib/services/discovery";
export const moviePeriodAtom = atom<TimePeriod>("this_month");
export const episodePeriodAtom = atom<TimePeriod>("this_week");
async function fetchStats(
type: "movies" | "episodes",
period: TimePeriod,
): Promise<{ count: number; history: HistoryBucket[] }> {
const res = await fetch(
`/api/stats?type=${type}&period=${period}&history=true`,
);
return res.json();
}
const movieStatsAsyncAtom = atom(async (get) => {
const period = get(moviePeriodAtom);
return fetchStats("movies", period);
});
const episodeStatsAsyncAtom = atom(async (get) => {
const period = get(episodePeriodAtom);
return fetchStats("episodes", period);
});
export const movieStatsAtom = unwrap(movieStatsAsyncAtom);
export const episodeStatsAtom = unwrap(episodeStatsAsyncAtom);