feature: caching
Some checks are pending
Deploy / deploy (push) Waiting to run

This commit is contained in:
Benno Tielen 2026-06-24 14:32:38 +02:00
parent bff425c3bd
commit afc6816451
3 changed files with 111 additions and 70 deletions

View file

@ -1,7 +1,10 @@
import { getPayload } from 'payload' import { getPayload } from 'payload'
import { unstable_cache } from 'next/cache'
import config from '@/payload.config' import config from '@/payload.config'
import { Announcement, Parish } from '@/payload-types' import { Announcement, Parish } from '@/payload-types'
const CACHE_TTL = 300 // 5 minutes
/** /**
* Fetch last announcement for a parish * Fetch last announcement for a parish
*/ */
@ -45,20 +48,22 @@ export const fetchLastAnnouncement = async (
/** /**
* Fetch the last announcement for each parish * Fetch the last announcement for each parish
*/ */
export const fetchLastAnnouncements = async (): Promise< export const fetchLastAnnouncements = unstable_cache(
Array<{ parish: Parish; doc: Announcement }> async (): Promise<Array<{ parish: Parish; doc: Announcement }>> => {
> => { const payload = await getPayload({ config })
const payload = await getPayload({ config }) const parishes = await payload.find({ collection: 'parish', limit: 100 })
const parishes = await payload.find({ collection: 'parish', limit: 100 })
const results = await Promise.all( const results = await Promise.all(
parishes.docs.map(async (parish) => { parishes.docs.map(async (parish) => {
const doc = await fetchLastAnnouncement(parish.id) const doc = await fetchLastAnnouncement(parish.id)
return doc ? { parish, doc } : null return doc ? { parish, doc } : null
}), }),
) )
return results.filter( return results.filter(
(r): r is { parish: Parish; doc: Announcement } => !!r, (r): r is { parish: Parish; doc: Announcement } => !!r,
) )
} },
['fetchLastAnnouncements'],
{ revalidate: CACHE_TTL },
)

View file

@ -1,7 +1,10 @@
import { getPayload } from 'payload' import { getPayload } from 'payload'
import { unstable_cache } from 'next/cache'
import config from '@/payload.config' import config from '@/payload.config'
import { Calendar, Parish } from '@/payload-types' import { Calendar, Parish } from '@/payload-types'
const CACHE_TTL = 300 // 5 minutes
/** /**
* Fetch last calendar for a parish * Fetch last calendar for a parish
*/ */
@ -45,20 +48,22 @@ export const fetchLastCalendar = async (
/** /**
* Fetch the last calendar for each parish * Fetch the last calendar for each parish
*/ */
export const fetchLastCalendars = async (): Promise< export const fetchLastCalendars = unstable_cache(
Array<{ parish: Parish; doc: Calendar }> async (): Promise<Array<{ parish: Parish; doc: Calendar }>> => {
> => { const payload = await getPayload({ config })
const payload = await getPayload({ config }) const parishes = await payload.find({ collection: 'parish', limit: 100 })
const parishes = await payload.find({ collection: 'parish', limit: 100 })
const results = await Promise.all( const results = await Promise.all(
parishes.docs.map(async (parish) => { parishes.docs.map(async (parish) => {
const doc = await fetchLastCalendar(parish.id) const doc = await fetchLastCalendar(parish.id)
return doc ? { parish, doc } : null return doc ? { parish, doc } : null
}), }),
) )
return results.filter( return results.filter(
(r): r is { parish: Parish; doc: Calendar } => !!r, (r): r is { parish: Parish; doc: Calendar } => !!r,
) )
} },
['fetchLastCalendars'],
{ revalidate: CACHE_TTL },
)

View file

@ -1,13 +1,79 @@
import { getPayload, PaginatedDocs } from 'payload' import { getPayload, PaginatedDocs } from 'payload'
import { unstable_cache } from 'next/cache'
import config from '@/payload.config' import config from '@/payload.config'
import { Worship } from '@/payload-types' import { Worship } from '@/payload-types'
const CACHE_TTL = 300 // 5 minutes
type FetchWorshipArgs = { type FetchWorshipArgs = {
fromDate?: Date fromDate?: Date
tillDate?: Date tillDate?: Date
locations?: string[] 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<PaginatedDocs<Worship>> => {
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<PaginatedDocs<Worship>>
},
['fetchWorship'],
{ revalidate: CACHE_TTL },
)
export const fetchWorship = async ( export const fetchWorship = async (
args?: FetchWorshipArgs, args?: FetchWorshipArgs,
): Promise<PaginatedDocs<Worship>> => { ): Promise<PaginatedDocs<Worship>> => {
@ -19,46 +85,11 @@ export const fetchWorship = async (
date.setHours(0, 0, 0, 0) date.setHours(0, 0, 0, 0)
} }
const query: any = { return getWorship({
and: [ fromDate: roundDownToTtl(date).toISOString(),
{ tillDate: tillDate ? roundDownToTtl(tillDate).toISOString() : undefined,
date: { locations,
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<PaginatedDocs<Worship>>
} }
/** /**