From f0d9ea28b686920b7b7e3c7995c67d4820629cfe Mon Sep 17 00:00:00 2001 From: Sam Becker Date: Tue, 18 Mar 2025 18:30:19 -0500 Subject: [PATCH] Add new static generation routine to cameras with logging --- app/film/[simulation]/image/route.tsx | 2 +- app/film/[simulation]/page.tsx | 2 +- app/focal/[focal]/image/route.tsx | 2 +- app/focal/[focal]/page.tsx | 2 +- app/lens/[make]/[model]/image/route.tsx | 2 +- app/lens/[make]/[model]/page.tsx | 2 +- app/recipe/[recipe]/image/route.tsx | 2 +- app/recipe/[recipe]/page.tsx | 2 +- app/shot-on/[make]/[model]/image/route.tsx | 21 +++++++----- app/shot-on/[make]/[model]/page.tsx | 19 ++++++----- app/tag/[tag]/image/route.tsx | 2 +- app/tag/[tag]/page.tsx | 2 +- src/app/config.ts | 18 +++------- src/category/server.ts | 39 ++++++++++++++++++++++ 14 files changed, 77 insertions(+), 40 deletions(-) create mode 100644 src/category/server.ts diff --git a/app/film/[simulation]/image/route.tsx b/app/film/[simulation]/image/route.tsx index 243b6043..42d427c9 100644 --- a/app/film/[simulation]/image/route.tsx +++ b/app/film/[simulation]/image/route.tsx @@ -11,7 +11,7 @@ import { ImageResponse } from 'next/og'; import { getImageResponseCacheControlHeaders } from '@/image-response/cache'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { getUniqueFilmSimulations } from '@/photo/db/query'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; export let generateStaticParams: (() => Promise<{ simulation: FilmSimulation }[]>) | undefined = undefined; diff --git a/app/film/[simulation]/page.tsx b/app/film/[simulation]/page.tsx index b2d4962b..c9ffb235 100644 --- a/app/film/[simulation]/page.tsx +++ b/app/film/[simulation]/page.tsx @@ -7,7 +7,7 @@ import { Metadata } from 'next/types'; import { cache } from 'react'; import { PATH_ROOT } from '@/app/paths'; import { redirect } from 'next/navigation'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; const getPhotosFilmSimulationDataCachedCached = diff --git a/app/focal/[focal]/image/route.tsx b/app/focal/[focal]/image/route.tsx index 5cfcbe70..0427f2eb 100644 --- a/app/focal/[focal]/image/route.tsx +++ b/app/focal/[focal]/image/route.tsx @@ -11,7 +11,7 @@ import FocalLengthImageResponse from import { formatFocalLength, getFocalLengthFromString } from '@/focal'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { getUniqueFocalLengths } from '@/photo/db/query'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; export let generateStaticParams: (() => Promise<{ focal: string }[]>) | undefined = undefined; diff --git a/app/focal/[focal]/page.tsx b/app/focal/[focal]/page.tsx index 1ed3942c..c63ada11 100644 --- a/app/focal/[focal]/page.tsx +++ b/app/focal/[focal]/page.tsx @@ -7,7 +7,7 @@ import { PATH_ROOT } from '@/app/paths'; import type { Metadata } from 'next'; import { redirect } from 'next/navigation'; import { cache } from 'react'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; const getPhotosFocalDataCachedCached = cache((focal: number) => diff --git a/app/lens/[make]/[model]/image/route.tsx b/app/lens/[make]/[model]/image/route.tsx index 99e0fd28..14605013 100644 --- a/app/lens/[make]/[model]/image/route.tsx +++ b/app/lens/[make]/[model]/image/route.tsx @@ -15,7 +15,7 @@ import { safelyGenerateLensStaticParams, } from '@/lens'; import LensImageResponse from '@/image-response/LensImageResponse'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; export let generateStaticParams: (() => Promise) | undefined = undefined; diff --git a/app/lens/[make]/[model]/page.tsx b/app/lens/[make]/[model]/page.tsx index b80d1d0d..638a6db5 100644 --- a/app/lens/[make]/[model]/page.tsx +++ b/app/lens/[make]/[model]/page.tsx @@ -12,7 +12,7 @@ import { safelyGenerateLensStaticParams, } from '@/lens'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; const getPhotosLensDataCachedCached = cache(( make: string | undefined, diff --git a/app/recipe/[recipe]/image/route.tsx b/app/recipe/[recipe]/image/route.tsx index 7777a247..e6771065 100644 --- a/app/recipe/[recipe]/image/route.tsx +++ b/app/recipe/[recipe]/image/route.tsx @@ -9,7 +9,7 @@ import { getImageResponseCacheControlHeaders } from '@/image-response/cache'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { getUniqueRecipes } from '@/photo/db/query'; import RecipeImageResponse from '@/image-response/RecipeImageResponse'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; export let generateStaticParams: (() => Promise<{ recipe: string }[]>) | undefined = undefined; diff --git a/app/recipe/[recipe]/page.tsx b/app/recipe/[recipe]/page.tsx index 783fb1c2..fe66b424 100644 --- a/app/recipe/[recipe]/page.tsx +++ b/app/recipe/[recipe]/page.tsx @@ -7,7 +7,7 @@ import { cache } from 'react'; import { generateMetaForRecipe } from '@/recipe'; import RecipeOverview from '@/recipe/RecipeOverview'; import { getPhotosRecipeDataCached } from '@/recipe/data'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; const getPhotosRecipeDataCachedCached = cache(getPhotosRecipeDataCached); diff --git a/app/shot-on/[make]/[model]/image/route.tsx b/app/shot-on/[make]/[model]/image/route.tsx index cf178f8b..a28b7cb9 100644 --- a/app/shot-on/[make]/[model]/image/route.tsx +++ b/app/shot-on/[make]/[model]/image/route.tsx @@ -8,20 +8,23 @@ import CameraImageResponse from '@/image-response/CameraImageResponse'; import { getIBMPlexMono } from '@/app/font'; import { ImageResponse } from 'next/og'; import { getImageResponseCacheControlHeaders } from '@/image-response/cache'; -import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { getUniqueCameras } from '@/photo/db/query'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { + shouldGenerateStaticParamsForCategory, + staticallyGenerateCategory, +} from '@/category/server'; export let generateStaticParams: - (() => Promise<{ camera: Camera }[]>) | undefined = undefined; + (() => Promise) | undefined = undefined; if (shouldGenerateStaticParamsForCategory('cameras', 'image')) { - generateStaticParams = async () => { - const cameras = await getUniqueCameras(); - return cameras - .map(({ camera }) => ({ camera })) - .slice(0, GENERATE_STATIC_PARAMS_LIMIT); - }; + generateStaticParams = () => + staticallyGenerateCategory( + 'cameras', + 'image', + getUniqueCameras, + cameras => cameras.map(({ camera }) => camera), + ); } export async function GET( diff --git a/app/shot-on/[make]/[model]/page.tsx b/app/shot-on/[make]/[model]/page.tsx index 79b3e971..c0e3a20c 100644 --- a/app/shot-on/[make]/[model]/page.tsx +++ b/app/shot-on/[make]/[model]/page.tsx @@ -6,8 +6,10 @@ import { getPhotosCameraDataCached } from '@/camera/data'; import CameraOverview from '@/camera/CameraOverview'; import { cache } from 'react'; import { getUniqueCameras } from '@/photo/db/query'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; -import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; +import { + shouldGenerateStaticParamsForCategory, + staticallyGenerateCategory, +} from '@/category/server'; const getPhotosCameraDataCachedCached = cache(( make: string, @@ -22,12 +24,13 @@ export let generateStaticParams: (() => Promise) | undefined = undefined; if (shouldGenerateStaticParamsForCategory('cameras', 'page')) { - generateStaticParams = async () => { - const cameras = await getUniqueCameras(); - return cameras - .map(({ camera: { make, model } }) => ({ make, model })) - .slice(0, GENERATE_STATIC_PARAMS_LIMIT); - }; + generateStaticParams = () => + staticallyGenerateCategory( + 'cameras', + 'page', + getUniqueCameras, + cameras => cameras.map(({ camera }) => camera), + ); } export async function generateMetadata({ diff --git a/app/tag/[tag]/image/route.tsx b/app/tag/[tag]/image/route.tsx index 43c9dd74..0fdf0e8d 100644 --- a/app/tag/[tag]/image/route.tsx +++ b/app/tag/[tag]/image/route.tsx @@ -9,7 +9,7 @@ import { ImageResponse } from 'next/og'; import { getImageResponseCacheControlHeaders } from '@/image-response/cache'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; import { getUniqueTags } from '@/photo/db/query'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; export let generateStaticParams: (() => Promise<{ tag: string }[]>) | undefined = undefined; diff --git a/app/tag/[tag]/page.tsx b/app/tag/[tag]/page.tsx index e06b2b8e..05daa1ec 100644 --- a/app/tag/[tag]/page.tsx +++ b/app/tag/[tag]/page.tsx @@ -7,7 +7,7 @@ import { getPhotosTagDataCached } from '@/tag/data'; import type { Metadata } from 'next'; import { redirect } from 'next/navigation'; import { cache } from 'react'; -import { shouldGenerateStaticParamsForCategory } from '@/app/config'; +import { shouldGenerateStaticParamsForCategory } from '@/category/server'; import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; const getPhotosTagDataCachedCached = cache((tag: string) => diff --git a/src/app/config.ts b/src/app/config.ts index eca9b5ef..e3bfbf5e 100644 --- a/src/app/config.ts +++ b/src/app/config.ts @@ -2,7 +2,7 @@ import { AI_AUTO_GENERATED_FIELDS_DEFAULT, parseAiAutoGeneratedFieldsString, } from '@/photo/ai'; -import { CategoryKey, getOrderedCategoriesFromString } from '@/category'; +import { getOrderedCategoriesFromString } from '@/category'; import type { StorageType } from '@/platforms/storage'; import { makeUrlAbsolute, shortenUrl } from '@/utility/url'; @@ -60,9 +60,9 @@ export const IS_PRODUCTION = process.env.NODE_ENV === 'production' && ( VERCEL_ENV === 'production' || !VERCEL_ENV ); - export const IS_DEVELOPMENT = process.env.NODE_ENV === 'development'; export const IS_PREVIEW = VERCEL_ENV === 'preview'; +export const IS_BUILDING = process.env.NEXT_PHASE === 'phase-production-build'; export const VERCEL_BYPASS_KEY = 'x-vercel-protection-bypass'; export const VERCEL_BYPASS_SECRET = process.env.VERCEL_AUTOMATION_BYPASS_SECRET; @@ -185,16 +185,6 @@ export const HAS_STATIC_OPTIMIZATION = STATICALLY_OPTIMIZED_PHOTO_CATEGORIES || STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES; -export const shouldGenerateStaticParamsForCategory = ( - key: CategoryKey, - type: 'page' | 'image', -): boolean => - CATEGORY_VISIBILITY.includes(key) && - IS_PRODUCTION && ( - (type === 'page' && STATICALLY_OPTIMIZED_PHOTO_CATEGORIES) || - (type === 'image' && STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES) - ); - export const PRESERVE_ORIGINAL_UPLOADS = process.env.NEXT_PUBLIC_PRESERVE_ORIGINAL_UPLOADS === '1' || // Legacy environment variable name @@ -270,7 +260,9 @@ export const OG_TEXT_BOTTOM_ALIGNMENT = export const ADMIN_DEBUG_TOOLS_ENABLED = process.env.ADMIN_DEBUG_TOOLS === '1'; export const ADMIN_DB_OPTIMIZE_ENABLED = process.env.ADMIN_DB_OPTIMIZE === '1'; -export const ADMIN_SQL_DEBUG_ENABLED = process.env.ADMIN_SQL_DEBUG === '1'; +export const ADMIN_SQL_DEBUG_ENABLED = + process.env.ADMIN_SQL_DEBUG === '1' && + !IS_BUILDING; export const APP_CONFIGURATION = { // Storage diff --git a/src/category/server.ts b/src/category/server.ts new file mode 100644 index 00000000..bd22dac2 --- /dev/null +++ b/src/category/server.ts @@ -0,0 +1,39 @@ +import { CategoryKey } from '.'; +import { + CATEGORY_VISIBILITY, + IS_BUILDING, + IS_PRODUCTION, + STATICALLY_OPTIMIZED_PHOTO_CATEGORIES, + STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES, +} from '@/app/config'; +import { GENERATE_STATIC_PARAMS_LIMIT } from '@/photo/db'; +import { pluralize } from '@/utility/string'; + +type StaticOutput = 'page' | 'image'; + +export const shouldGenerateStaticParamsForCategory = ( + key: CategoryKey, + type: StaticOutput, +): boolean => + CATEGORY_VISIBILITY.includes(key) && + IS_PRODUCTION && ( + (type === 'page' && STATICALLY_OPTIMIZED_PHOTO_CATEGORIES) || + (type === 'image' && STATICALLY_OPTIMIZED_PHOTO_CATEGORY_OG_IMAGES) + ); + +export const staticallyGenerateCategory = async ( + key: CategoryKey, + type: StaticOutput, + getData: () => Promise, + formatData: (data: T[]) => K[], +): Promise => { + const data = (await getData()).slice(0, GENERATE_STATIC_PARAMS_LIMIT); + + if (IS_BUILDING) { + console.log( + `Statically generating ${key} (${pluralize(data.length, type)})`, + ); + } + + return formatData(data); +};