diff --git a/src/fetch/announcement.ts b/src/fetch/announcement.ts index 14680d3..46b1e83 100644 --- a/src/fetch/announcement.ts +++ b/src/fetch/announcement.ts @@ -1,7 +1,10 @@ import { getPayload } from 'payload' +import { unstable_cache } from 'next/cache' import config from '@/payload.config' import { Announcement, Parish } from '@/payload-types' +const CACHE_TTL = 300 // 5 minutes + /** * Fetch last announcement for a parish */ @@ -45,20 +48,22 @@ export const fetchLastAnnouncement = async ( /** * Fetch the last announcement for each parish */ -export const fetchLastAnnouncements = async (): Promise< - Array<{ parish: Parish; doc: Announcement }> -> => { - const payload = await getPayload({ config }) - const parishes = await payload.find({ collection: 'parish', limit: 100 }) +export const fetchLastAnnouncements = unstable_cache( + async (): Promise> => { + const payload = await getPayload({ config }) + const parishes = await payload.find({ collection: 'parish', limit: 100 }) - const results = await Promise.all( - parishes.docs.map(async (parish) => { - const doc = await fetchLastAnnouncement(parish.id) - return doc ? { parish, doc } : null - }), - ) + const results = await Promise.all( + parishes.docs.map(async (parish) => { + const doc = await fetchLastAnnouncement(parish.id) + return doc ? { parish, doc } : null + }), + ) - return results.filter( - (r): r is { parish: Parish; doc: Announcement } => !!r, - ) -} + return results.filter( + (r): r is { parish: Parish; doc: Announcement } => !!r, + ) + }, + ['fetchLastAnnouncements'], + { revalidate: CACHE_TTL }, +) diff --git a/src/fetch/calendar.ts b/src/fetch/calendar.ts index 7686415..c923438 100644 --- a/src/fetch/calendar.ts +++ b/src/fetch/calendar.ts @@ -1,7 +1,10 @@ import { getPayload } from 'payload' +import { unstable_cache } from 'next/cache' import config from '@/payload.config' import { Calendar, Parish } from '@/payload-types' +const CACHE_TTL = 300 // 5 minutes + /** * Fetch last calendar for a parish */ @@ -45,20 +48,22 @@ export const fetchLastCalendar = async ( /** * Fetch the last calendar for each parish */ -export const fetchLastCalendars = async (): Promise< - Array<{ parish: Parish; doc: Calendar }> -> => { - const payload = await getPayload({ config }) - const parishes = await payload.find({ collection: 'parish', limit: 100 }) +export const fetchLastCalendars = unstable_cache( + async (): Promise> => { + const payload = await getPayload({ config }) + const parishes = await payload.find({ collection: 'parish', limit: 100 }) - const results = await Promise.all( - parishes.docs.map(async (parish) => { - const doc = await fetchLastCalendar(parish.id) - return doc ? { parish, doc } : null - }), - ) + const results = await Promise.all( + parishes.docs.map(async (parish) => { + const doc = await fetchLastCalendar(parish.id) + return doc ? { parish, doc } : null + }), + ) - return results.filter( - (r): r is { parish: Parish; doc: Calendar } => !!r, - ) -} + return results.filter( + (r): r is { parish: Parish; doc: Calendar } => !!r, + ) + }, + ['fetchLastCalendars'], + { revalidate: CACHE_TTL }, +) diff --git a/src/fetch/worship.ts b/src/fetch/worship.ts index 26e2271..be01aa9 100644 --- a/src/fetch/worship.ts +++ b/src/fetch/worship.ts @@ -1,13 +1,79 @@ import { getPayload, PaginatedDocs } from 'payload' +import { unstable_cache } from 'next/cache' import config from '@/payload.config' import { Worship } from '@/payload-types' +const CACHE_TTL = 300 // 5 minutes + type FetchWorshipArgs = { fromDate?: Date tillDate?: Date locations?: string[] } +// Resolved args use ISO strings so they serialize into a stable cache key. +type ResolvedWorshipArgs = { + fromDate: string + tillDate?: string + locations?: string[] +} + +// Round down to the cache window so millisecond-precision dates produce a +// stable key for the duration of the TTL. +function roundDownToTtl(date: Date): Date { + const ms = CACHE_TTL * 1000 + return new Date(Math.floor(date.getTime() / ms) * ms) +} + +const getWorship = unstable_cache( + async (args: ResolvedWorshipArgs): Promise> => { + const { fromDate, tillDate, locations } = args + + const query: any = { + and: [ + { + date: { + greater_than_equal: fromDate, + }, + }, + ], + } + + if (tillDate) { + query.and.push({ + date: { + less_than: tillDate, + }, + }) + } + + if (locations) { + query.and.push({ + location: { + in: locations, + }, + }) + } + + const payload = await getPayload({ config }) + return payload.find({ + collection: 'worship', + sort: 'date', + where: query, + select: { + type: true, + date: true, + cancelled: true, + location: true, + title: true, + }, + limit: 100, + }) as Promise> + }, + ['fetchWorship'], + { revalidate: CACHE_TTL }, +) + export const fetchWorship = async ( args?: FetchWorshipArgs, ): Promise> => { @@ -19,46 +85,11 @@ export const fetchWorship = async ( date.setHours(0, 0, 0, 0) } - const query: any = { - and: [ - { - date: { - greater_than_equal: date.toISOString(), - }, - }, - ], - } - - if (tillDate) { - query.and.push({ - date: { - less_than: tillDate.toISOString(), - }, - }) - } - - if (locations) { - query.and.push({ - location: { - in: locations, - }, - }) - } - - const payload = await getPayload({ config }) - return payload.find({ - collection: 'worship', - sort: 'date', - where: query, - select: { - type: true, - date: true, - cancelled: true, - location: true, - title: true, - }, - limit: 100, - }) as Promise> + return getWorship({ + fromDate: roundDownToTtl(date).toISOString(), + tillDate: tillDate ? roundDownToTtl(tillDate).toISOString() : undefined, + locations, + }) } /**