diff --git a/src/category/actions.ts b/src/category/actions.ts index 0d18584c..30858ba8 100644 --- a/src/category/actions.ts +++ b/src/category/actions.ts @@ -1,42 +1,6 @@ 'use server'; -import { createLensKey } from '@/lens'; -import { getDataForCategories } from './data'; +import { getCountsForCategoriesCached } from './cache'; -export const getCountsForCategoriesAction = async () => { - const [ - cameras, - lenses, - tags, - recipes, - filmSimulations, - focalLengths, - ] = await Promise.all(getDataForCategories()); - - return { - cameras: cameras.reduce((acc, camera) => { - acc[camera.cameraKey] = camera.count; - return acc; - }, {} as Record), - lenses: lenses.reduce((acc, lens) => { - acc[createLensKey(lens.lens)] = lens.count; - return acc; - }, {} as Record), - tags: tags.reduce((acc, tag) => { - acc[tag.tag] = tag.count; - return acc; - }, {} as Record), - recipes: recipes.reduce((acc, recipe) => { - acc[recipe.recipe] = recipe.count; - return acc; - }, {} as Record), - filmSimulations: filmSimulations.reduce((acc, filmSimulation) => { - acc[filmSimulation.simulation] = filmSimulation.count; - return acc; - }, {} as Record), - focalLengths: focalLengths.reduce((acc, focalLength) => { - acc[focalLength.focal] = focalLength.count; - return acc; - }, {} as Record), - }; -}; +export const getCountsForCategoriesCachedAction = async () => + getCountsForCategoriesCached(); diff --git a/src/category/cache.ts b/src/category/cache.ts new file mode 100644 index 00000000..426f8c2f --- /dev/null +++ b/src/category/cache.ts @@ -0,0 +1,9 @@ +import { unstable_cache } from 'next/cache'; +import { getCountsForCategories } from './data'; +import { KEY_PHOTOS } from '@/photo/cache'; + +export const getCountsForCategoriesCached = () => + unstable_cache( + getCountsForCategories, + [KEY_PHOTOS], + )(); diff --git a/src/category/data.ts b/src/category/data.ts index c7087bee..7485033c 100644 --- a/src/category/data.ts +++ b/src/category/data.ts @@ -14,6 +14,7 @@ import { SHOW_CAMERAS, SHOW_TAGS, } from '@/app/config'; +import { createLensKey } from '@/lens'; import { sortTagsByCount } from '@/tag'; import { sortCategoriesByCount } from '@/category'; import { sortFocalLengths } from '@/focal'; @@ -50,3 +51,41 @@ export const getDataForCategories = () => [ .catch(() => []) : [], ] as const; + +export const getCountsForCategories = async () => { + const [ + cameras, + lenses, + tags, + recipes, + filmSimulations, + focalLengths, + ] = await Promise.all(getDataForCategories()); + + return { + cameras: cameras.reduce((acc, camera) => { + acc[camera.cameraKey] = camera.count; + return acc; + }, {} as Record), + lenses: lenses.reduce((acc, lens) => { + acc[createLensKey(lens.lens)] = lens.count; + return acc; + }, {} as Record), + tags: tags.reduce((acc, tag) => { + acc[tag.tag] = tag.count; + return acc; + }, {} as Record), + recipes: recipes.reduce((acc, recipe) => { + acc[recipe.recipe] = recipe.count; + return acc; + }, {} as Record), + filmSimulations: filmSimulations.reduce((acc, filmSimulation) => { + acc[filmSimulation.simulation] = filmSimulation.count; + return acc; + }, {} as Record), + focalLengths: focalLengths.reduce((acc, focalLength) => { + acc[focalLength.focal] = focalLength.count; + return acc; + }, {} as Record), + }; +}; diff --git a/src/photo/cache.ts b/src/photo/cache.ts index 153fe441..e46ee873 100644 --- a/src/photo/cache.ts +++ b/src/photo/cache.ts @@ -39,7 +39,7 @@ import { import { createLensKey } from '@/lens'; // Table key -const KEY_PHOTOS = 'photos'; +export const KEY_PHOTOS = 'photos'; const KEY_PHOTO = 'photo'; // Field keys const KEY_CAMERAS = 'cameras'; diff --git a/src/state/AppState.ts b/src/state/AppState.ts index bad3c776..d80ec517 100644 --- a/src/state/AppState.ts +++ b/src/state/AppState.ts @@ -11,7 +11,7 @@ import { InsightsIndicatorStatus } from '@/admin/insights'; import { INITIAL_UPLOAD_STATE, UploadState } from '@/admin/upload'; import { AdminData } from '@/admin/actions'; import { RecipeProps } from '@/recipe'; -import { getCountsForCategoriesAction } from '@/category/actions'; +import { getCountsForCategoriesCachedAction } from '@/category/actions'; export type AppStateContext = { // CORE previousPathname?: string @@ -25,7 +25,7 @@ export type AppStateContext = { shouldRespondToKeyboardCommands?: boolean setShouldRespondToKeyboardCommands?: Dispatch> categoriesWithCounts?: - Awaited> + Awaited> // MODAL isCommandKOpen?: boolean setIsCommandKOpen?: Dispatch> diff --git a/src/state/AppStateProvider.tsx b/src/state/AppStateProvider.tsx index 1200d945..60fca69e 100644 --- a/src/state/AppStateProvider.tsx +++ b/src/state/AppStateProvider.tsx @@ -24,7 +24,7 @@ import { useRouter, usePathname } from 'next/navigation'; import { isPathAdmin, PATH_SIGN_IN } from '@/app/paths'; import { INITIAL_UPLOAD_STATE, UploadState } from '@/admin/upload'; import { RecipeProps } from '@/recipe'; -import { getCountsForCategoriesAction } from '@/category/actions'; +import { getCountsForCategoriesCachedAction } from '@/category/actions'; export default function AppStateProvider({ children, @@ -93,7 +93,7 @@ export default function AppStateProvider({ const { data: categoriesWithCounts } = useSWR( 'getDataForCategories', - getCountsForCategoriesAction, + getCountsForCategoriesCachedAction, ); const {