From ab0ddeee94e4d3f8374a1f6f6c99770263842631 Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Wed, 19 Nov 2025 09:16:23 -0600 Subject: [PATCH] Create top-level cache module --- app/api/storage/vercel-blob/route.ts | 2 +- src/album/actions.ts | 2 +- src/album/cache.ts | 2 +- src/cache/actions.ts | 7 +++ src/cache/index.ts | 66 +++++++++++++++++++++ src/category/cache.ts | 2 +- src/photo/actions.ts | 5 +- src/photo/cache.ts | 87 +++++++--------------------- 8 files changed, 100 insertions(+), 73 deletions(-) create mode 100644 src/cache/actions.ts create mode 100644 src/cache/index.ts diff --git a/app/api/storage/vercel-blob/route.ts b/app/api/storage/vercel-blob/route.ts index e1180ffc..edc3cb7a 100644 --- a/app/api/storage/vercel-blob/route.ts +++ b/app/api/storage/vercel-blob/route.ts @@ -1,5 +1,5 @@ import { auth } from '@/auth/server'; -import { revalidateAdminPaths, revalidatePhotosKey } from '@/photo/cache'; +import { revalidateAdminPaths, revalidatePhotosKey } from '@/cache'; import { ACCEPTED_PHOTO_FILE_TYPES, MAX_PHOTO_UPLOAD_SIZE_IN_BYTES, diff --git a/src/album/actions.ts b/src/album/actions.ts index 79d3336f..607b15d0 100644 --- a/src/album/actions.ts +++ b/src/album/actions.ts @@ -2,7 +2,7 @@ import { runAuthenticatedAdminServerAction } from '@/auth/server'; import { addPhotoAlbumIds, deleteAlbum, updateAlbum } from './query'; -import { revalidateAllKeysAndPaths } from '@/photo/cache'; +import { revalidateAllKeysAndPaths } from '@/cache'; import { redirect } from 'next/navigation'; import { PATH_ADMIN_ALBUMS, PATH_ROOT, pathForAlbum } from '@/app/path'; import { convertFormDataToAlbum } from './form'; diff --git a/src/album/cache.ts b/src/album/cache.ts index 61af20d8..23fe285a 100644 --- a/src/album/cache.ts +++ b/src/album/cache.ts @@ -4,7 +4,7 @@ import { getAlbumTitlesForPhoto, getTagsForAlbum, } from '@/album/query'; -import { KEY_ALBUMS, KEY_PHOTOS } from '@/photo/cache'; +import { KEY_ALBUMS, KEY_PHOTOS } from '@/cache'; import { unstable_cache } from 'next/cache'; export const getAlbumFromSlugCached = diff --git a/src/cache/actions.ts b/src/cache/actions.ts new file mode 100644 index 00000000..6374f23d --- /dev/null +++ b/src/cache/actions.ts @@ -0,0 +1,7 @@ +'use server'; + +import { runAuthenticatedAdminServerAction } from '@/auth/server'; +import { revalidateAllKeysAndPaths } from '.'; + +export const revalidateAllKeysAndPathsAction = async () => + runAuthenticatedAdminServerAction(revalidateAllKeysAndPaths); diff --git a/src/cache/index.ts b/src/cache/index.ts new file mode 100644 index 00000000..98e70c4e --- /dev/null +++ b/src/cache/index.ts @@ -0,0 +1,66 @@ +import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/app/path'; +import { revalidatePath, revalidateTag } from 'next/cache'; + +// Table key +export const KEY_PHOTOS = 'photos'; +export const KEY_PHOTO = 'photo'; +// Field keys +export const KEY_CAMERAS = 'cameras'; +export const KEY_LENSES = 'lenses'; +export const KEY_ALBUMS = 'albums'; +export const KEY_TAGS = 'tags'; +export const KEY_FILMS = 'films'; +export const KEY_RECIPES = 'recipes'; +export const KEY_FOCAL_LENGTHS = 'focal-lengths'; +export const KEY_YEARS = 'years'; +// Type keys +export const KEY_COUNT = 'count'; +export const KEY_DATE_RANGE = 'date-range'; + +export const revalidatePhotosKey = () => + revalidateTag(KEY_PHOTOS, 'max'); + +export const revalidateAlbumsKey = () => + revalidateTag(KEY_ALBUMS, 'max'); + +export const revalidateTagsKey = () => + revalidateTag(KEY_TAGS, 'max'); + +export const revalidateRecipesKey = () => + revalidateTag(KEY_RECIPES, 'max'); + +export const revalidateCamerasKey = () => + revalidateTag(KEY_CAMERAS, 'max'); + +export const revalidateLensesKey = () => + revalidateTag(KEY_LENSES, 'max'); + +export const revalidateFilmsKey = () => + revalidateTag(KEY_FILMS, 'max'); + +export const revalidateFocalLengthsKey = () => + revalidateTag(KEY_FOCAL_LENGTHS, 'max'); + +export const revalidateYearsKey = () => + revalidateTag(KEY_YEARS, 'max'); + +export const revalidateAllKeys = () => { + revalidatePhotosKey(); + revalidateAlbumsKey(); + revalidateTagsKey(); + revalidateCamerasKey(); + revalidateLensesKey(); + revalidateFilmsKey(); + revalidateRecipesKey(); + revalidateFocalLengthsKey(); + revalidateYearsKey(); +}; + +export const revalidateAdminPaths = () => { + PATHS_ADMIN.forEach(path => revalidatePath(path)); +}; + +export const revalidateAllKeysAndPaths = () => { + revalidateAllKeys(); + PATHS_TO_CACHE.forEach(path => revalidatePath(path, 'layout')); +}; diff --git a/src/category/cache.ts b/src/category/cache.ts index 867849f5..e31cb006 100644 --- a/src/category/cache.ts +++ b/src/category/cache.ts @@ -1,6 +1,6 @@ import { unstable_cache } from 'next/cache'; import { getCountsForCategories, getDataForCategories } from './data'; -import { KEY_PHOTOS } from '@/photo/cache'; +import { KEY_PHOTOS } from '@/cache'; export const getDataForCategoriesCached = unstable_cache( getDataForCategories, diff --git a/src/photo/actions.ts b/src/photo/actions.ts index 7542abcd..17e627e9 100644 --- a/src/photo/actions.ts +++ b/src/photo/actions.ts @@ -24,14 +24,13 @@ import { import { redirect } from 'next/navigation'; import { deleteFile } from '@/platforms/storage'; import { - getPhotosCached, revalidateAdminPaths, revalidateAllKeysAndPaths, - revalidatePhoto, revalidatePhotosKey, revalidateRecipesKey, revalidateTagsKey, -} from '@/photo/cache'; +} from '@/cache'; +import { revalidatePhoto, getPhotosCached } from './cache'; import { PATH_ADMIN_PHOTOS, PATH_ADMIN_RECIPES, diff --git a/src/photo/cache.ts b/src/photo/cache.ts index 6d6e4684..ffea2359 100644 --- a/src/photo/cache.ts +++ b/src/photo/cache.ts @@ -23,8 +23,6 @@ import { PhotoQueryOptions } from '@/db'; import { parseCachedPhotoDates, parseCachedPhotosDates } from '@/photo'; import { createCameraKey } from '@/camera'; import { - PATHS_ADMIN, - PATHS_TO_CACHE, PATH_ADMIN, PATH_FULL, PATH_GRID, @@ -40,22 +38,27 @@ import { PREFIX_ALBUM, } from '@/app/path'; import { createLensKey } from '@/lens'; - -// Table key -export const KEY_PHOTOS = 'photos'; -export const KEY_PHOTO = 'photo'; -// Field keys -export const KEY_CAMERAS = 'cameras'; -export const KEY_LENSES = 'lenses'; -export const KEY_ALBUMS = 'albums'; -export const KEY_TAGS = 'tags'; -export const KEY_FILMS = 'films'; -export const KEY_RECIPES = 'recipes'; -export const KEY_FOCAL_LENGTHS = 'focal-lengths'; -export const KEY_YEARS = 'years'; -// Type keys -export const KEY_COUNT = 'count'; -export const KEY_DATE_RANGE = 'date-range'; +import { + KEY_PHOTOS, + KEY_PHOTO, + KEY_CAMERAS, + KEY_LENSES, + KEY_TAGS, + KEY_FILMS, + KEY_RECIPES, + KEY_FOCAL_LENGTHS, + KEY_YEARS, + KEY_COUNT, + KEY_DATE_RANGE, + revalidateYearsKey, + revalidateCamerasKey, + revalidateLensesKey, + revalidateAlbumsKey, + revalidateTagsKey, + revalidateFilmsKey, + revalidateRecipesKey, + revalidateFocalLengthsKey, +} from '@/cache'; const getCacheKeyForPhotoQueryOptions = ( options: PhotoQueryOptions, @@ -102,54 +105,6 @@ const getPhotosCacheKeys = (options: PhotoQueryOptions = {}) => { return tags; }; -export const revalidatePhotosKey = () => - revalidateTag(KEY_PHOTOS, 'max'); - -export const revalidateAlbumsKey = () => - revalidateTag(KEY_ALBUMS, 'max'); - -export const revalidateTagsKey = () => - revalidateTag(KEY_TAGS, 'max'); - -export const revalidateRecipesKey = () => - revalidateTag(KEY_RECIPES, 'max'); - -export const revalidateCamerasKey = () => - revalidateTag(KEY_CAMERAS, 'max'); - -export const revalidateLensesKey = () => - revalidateTag(KEY_LENSES, 'max'); - -export const revalidateFilmsKey = () => - revalidateTag(KEY_FILMS, 'max'); - -export const revalidateFocalLengthsKey = () => - revalidateTag(KEY_FOCAL_LENGTHS, 'max'); - -export const revalidateYearsKey = () => - revalidateTag(KEY_YEARS, 'max'); - -export const revalidateAllKeys = () => { - revalidatePhotosKey(); - revalidateAlbumsKey(); - revalidateTagsKey(); - revalidateCamerasKey(); - revalidateLensesKey(); - revalidateFilmsKey(); - revalidateRecipesKey(); - revalidateFocalLengthsKey(); - revalidateYearsKey(); -}; - -export const revalidateAdminPaths = () => { - PATHS_ADMIN.forEach(path => revalidatePath(path)); -}; - -export const revalidateAllKeysAndPaths = () => { - revalidateAllKeys(); - PATHS_TO_CACHE.forEach(path => revalidatePath(path, 'layout')); -}; - export const revalidatePhoto = (photoId: string) => { // Tags revalidateTag(photoId, 'max');