276 lines
8.1 KiB
TypeScript
276 lines
8.1 KiB
TypeScript
import { revalidatePath, revalidateTag, unstable_cache } from 'next/cache';
|
|
import {
|
|
GetPhotosOptions,
|
|
getPhoto,
|
|
getPhotos,
|
|
getPhotosCount,
|
|
getPhotosCameraCount,
|
|
getPhotosCountIncludingHidden,
|
|
getPhotosTagCount,
|
|
getUniqueCameras,
|
|
getUniqueTags,
|
|
getPhotosTagDateRange,
|
|
getPhotosCameraDateRange,
|
|
getUniqueTagsHidden,
|
|
getUniqueFilmSimulations,
|
|
getPhotosFilmSimulationDateRange,
|
|
getPhotosFilmSimulationCount,
|
|
} from '@/services/postgres';
|
|
import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo';
|
|
import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
|
|
import type { Session } from 'next-auth';
|
|
import { Camera, createCameraKey } from '@/camera';
|
|
import { PATHS_ADMIN, PATHS_TO_CACHE } from '@/site/paths';
|
|
import { FilmSimulation } from '@/simulation';
|
|
|
|
const KEY_PHOTOS = 'photos';
|
|
const KEY_PHOTOS_COUNT = `${KEY_PHOTOS}-count`;
|
|
const KEY_PHOTOS_DATE_RANGE = `${KEY_PHOTOS}-date-range`;
|
|
const KEY_TAGS = 'tags';
|
|
const KEY_CAMERAS = 'cameras';
|
|
const KEY_FILM_SIMULATIONS = 'film-simulations';
|
|
const KEY_BLOB = 'blob';
|
|
|
|
// eslint-disable-next-line max-len
|
|
const getPhotosCacheKeyForOption = (
|
|
options: GetPhotosOptions,
|
|
option: keyof GetPhotosOptions,
|
|
): string | null => {
|
|
switch (option) {
|
|
// Primitive keys
|
|
case 'sortBy':
|
|
case 'limit':
|
|
case 'tag':
|
|
case 'simulation':
|
|
case 'includeHidden': {
|
|
const value = options[option];
|
|
return value ? `${option}-${value}` : null;
|
|
}
|
|
// Date keys
|
|
case 'takenBefore':
|
|
case 'takenAfterInclusive': {
|
|
const value = options[option];
|
|
return value ? `${option}-${value.toISOString()}` : null;
|
|
}
|
|
// Complex keys
|
|
case 'camera': {
|
|
const value = options[option];
|
|
return value ? `${option}-${value.make}-${value.model}` : null;
|
|
}
|
|
}
|
|
};
|
|
|
|
const getPhotosCacheKeys = (options: GetPhotosOptions = {}) => {
|
|
const tags: string[] = [];
|
|
|
|
Object.keys(options).forEach(key => {
|
|
const tag = getPhotosCacheKeyForOption(
|
|
options,
|
|
key as keyof GetPhotosOptions
|
|
);
|
|
if (tag) { tags.push(tag); }
|
|
});
|
|
|
|
return tags;
|
|
};
|
|
|
|
const getPhotoCacheKey = (photoId: string) => `photo-${photoId}`;
|
|
|
|
const getPhotoTagCountKey = (tag: string) =>
|
|
`${KEY_PHOTOS_COUNT}-${KEY_TAGS}-${tag}`;
|
|
|
|
const getPhotoCameraCountKey = (camera: Camera) =>
|
|
`${KEY_PHOTOS_COUNT}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
|
|
|
const getPhotoFilmSimulationCountKey = (simulation: FilmSimulation) =>
|
|
`${KEY_PHOTOS_COUNT}-${KEY_FILM_SIMULATIONS}-${simulation}`;
|
|
|
|
const getPhotoTagDateRangeKey = (tag: string) =>
|
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_TAGS}-${tag}`;
|
|
|
|
const getPhotoCameraDateRangeKey = (camera: Camera) =>
|
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_CAMERAS}-${createCameraKey(camera)}`;
|
|
|
|
const getPhotoFilmSimulationDateRangeKey = (simulation: FilmSimulation) =>
|
|
`${KEY_PHOTOS_DATE_RANGE}-${KEY_FILM_SIMULATIONS}-${simulation}`;
|
|
|
|
export const revalidatePhotosKey = () =>
|
|
revalidateTag(KEY_PHOTOS);
|
|
|
|
export const revalidateTagsKey = () =>
|
|
revalidateTag(KEY_TAGS);
|
|
|
|
export const revalidateCamerasKey = () =>
|
|
revalidateTag(KEY_CAMERAS);
|
|
|
|
export const revalidateFilmSimulationsKey = () =>
|
|
revalidateTag(KEY_FILM_SIMULATIONS);
|
|
|
|
export const revalidateBlobKey = () =>
|
|
revalidateTag(KEY_BLOB);
|
|
|
|
export const revalidatePhotosAndBlobKeys = () => {
|
|
revalidatePhotosKey();
|
|
revalidateBlobKey();
|
|
};
|
|
|
|
export const revalidateAllKeys = () => {
|
|
revalidatePhotosAndBlobKeys();
|
|
revalidateTagsKey();
|
|
revalidateCamerasKey();
|
|
revalidateFilmSimulationsKey();
|
|
};
|
|
|
|
export const revalidateAllKeysAndPaths = () => {
|
|
revalidateAllKeys();
|
|
PATHS_TO_CACHE.forEach(path => revalidatePath(path));
|
|
};
|
|
|
|
export const revalidateAdminPaths = () => {
|
|
PATHS_ADMIN.forEach(path => revalidatePath(path));
|
|
};
|
|
|
|
export const getPhotosCached: typeof getPhotos = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotos(...args),
|
|
[KEY_PHOTOS, ...getPhotosCacheKeys(...args)], {
|
|
tags: [KEY_PHOTOS, ...getPhotosCacheKeys(...args)],
|
|
}
|
|
)().then(parseCachedPhotosDates);
|
|
|
|
export const getPhotosCountCached: typeof getPhotosCount = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCount(...args),
|
|
[KEY_PHOTOS, KEY_PHOTOS_COUNT], {
|
|
tags: [KEY_PHOTOS, KEY_PHOTOS_COUNT],
|
|
}
|
|
)();
|
|
|
|
export const getPhotosCountIncludingHiddenCached: typeof getPhotosCount =
|
|
(...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCountIncludingHidden(...args),
|
|
[KEY_PHOTOS, KEY_PHOTOS_COUNT], {
|
|
tags: [KEY_PHOTOS, KEY_PHOTOS_COUNT],
|
|
}
|
|
)();
|
|
|
|
export const getPhotosTagCountCached: typeof getPhotosTagCount = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosTagCount(...args),
|
|
[KEY_PHOTOS, getPhotoTagCountKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoTagCountKey(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosCameraCountCached: typeof getPhotosCameraCount = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCameraCount(...args),
|
|
[KEY_PHOTOS, getPhotoCameraCountKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoCameraCountKey(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosFilmSimulationCountCached: typeof getPhotosFilmSimulationCount = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosFilmSimulationCount(...args),
|
|
[KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoFilmSimulationCountKey(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosTagDateRangeCached: typeof getPhotosTagDateRange = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosTagDateRange(...args),
|
|
[KEY_PHOTOS, getPhotoTagDateRangeKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoTagDateRangeKey(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosCameraDateRangeCached: typeof getPhotosCameraDateRange = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCameraDateRange(...args),
|
|
[KEY_PHOTOS, getPhotoCameraDateRangeKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoCameraDateRangeKey(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosFilmSimulationDateRangeCached: typeof getPhotosFilmSimulationDateRange = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosFilmSimulationDateRange(...args),
|
|
[KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoFilmSimulationDateRangeKey(...args)],
|
|
}
|
|
)();
|
|
|
|
export const getPhotoCached: typeof getPhoto = (...args) =>
|
|
unstable_cache(
|
|
() => getPhoto(...args),
|
|
[KEY_PHOTOS, getPhotoCacheKey(...args)], {
|
|
tags: [KEY_PHOTOS, getPhotoCacheKey(...args)],
|
|
}
|
|
)().then(photo => photo ? parseCachedPhotoDates(photo) : undefined);
|
|
|
|
export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueTags(...args),
|
|
[KEY_PHOTOS, KEY_TAGS], {
|
|
tags: [KEY_PHOTOS, KEY_TAGS],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getUniqueTagsHiddenCached: typeof getUniqueTagsHidden = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueTagsHidden(...args),
|
|
[KEY_PHOTOS, KEY_TAGS], {
|
|
tags: [KEY_PHOTOS, KEY_TAGS],
|
|
}
|
|
)();
|
|
|
|
export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueCameras(...args),
|
|
[KEY_PHOTOS, KEY_CAMERAS], {
|
|
tags: [KEY_PHOTOS, KEY_CAMERAS],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getUniqueFilmSimulationsCached: typeof getUniqueFilmSimulations = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueFilmSimulations(...args),
|
|
[KEY_PHOTOS, KEY_FILM_SIMULATIONS], {
|
|
tags: [KEY_PHOTOS, KEY_FILM_SIMULATIONS],
|
|
}
|
|
)();
|
|
|
|
export const getBlobUploadUrlsCached: typeof getBlobUploadUrls = (...args) =>
|
|
unstable_cache(
|
|
() => getBlobUploadUrls(...args),
|
|
[KEY_BLOB], {
|
|
tags: [KEY_BLOB],
|
|
}
|
|
)();
|
|
|
|
export const getBlobPhotoUrlsCached: typeof getBlobPhotoUrls = (...args) =>
|
|
unstable_cache(
|
|
() => getBlobPhotoUrls(...args),
|
|
[KEY_BLOB], {
|
|
tags: [KEY_BLOB],
|
|
}
|
|
)();
|
|
|
|
export const getImageCacheHeadersForAuth = (session: Session | null) => {
|
|
return {
|
|
'Cache-Control': !session?.user
|
|
? 's-maxage=3600, stale-while-revalidate=59'
|
|
: 's-maxage=1, stale-while-revalidate=59',
|
|
};
|
|
};
|