185 lines
5.0 KiB
TypeScript
185 lines
5.0 KiB
TypeScript
import { revalidateTag, unstable_cache } from 'next/cache';
|
|
import {
|
|
GetPhotosOptions,
|
|
getPhoto,
|
|
getPhotos,
|
|
getPhotosCount,
|
|
getPhotosCountCamera,
|
|
getPhotosCountIncludingHidden,
|
|
getPhotosCountTag,
|
|
getUniqueCameras,
|
|
getUniqueTags,
|
|
} from '@/services/postgres';
|
|
import { parseCachedPhotosDates, parseCachedPhotoDates } from '@/photo';
|
|
import { getBlobPhotoUrls, getBlobUploadUrls } from '@/services/blob';
|
|
import { AuthSession } from 'next-auth';
|
|
import { Camera, createCameraKey } from '@/camera';
|
|
|
|
const TAG_PHOTOS = 'photos';
|
|
const TAG_PHOTOS_COUNT = 'photos-count';
|
|
const TAG_TAGS = 'tags';
|
|
const TAG_CAMERAS = 'cameras';
|
|
const TAG_BLOB = 'blob';
|
|
|
|
// eslint-disable-next-line max-len
|
|
const getPhotosCacheTagForKey = (
|
|
options: GetPhotosOptions,
|
|
key: keyof GetPhotosOptions,
|
|
): string | null => {
|
|
switch (key) {
|
|
// Primitive keys
|
|
case 'sortBy':
|
|
case 'limit':
|
|
case 'offset':
|
|
case 'tag':
|
|
case 'includeHidden': {
|
|
const value = options[key];
|
|
return value ? `${key}-${value}` : null;
|
|
}
|
|
// Date keys
|
|
case 'takenBefore':
|
|
case 'takenAfterInclusive': {
|
|
const value = options[key];
|
|
return value ? `${key}-${value.toISOString()}` : null;
|
|
}
|
|
// Complex keys
|
|
case 'camera': {
|
|
const value = options[key];
|
|
return value ? `${key}-${value.make}-${value.model}` : null;
|
|
}
|
|
}
|
|
};
|
|
|
|
const getPhotosCacheTags = (options: GetPhotosOptions = {}) => {
|
|
const tags: string[] = [];
|
|
|
|
Object.keys(options).forEach(key => {
|
|
const tag = getPhotosCacheTagForKey(options, key as keyof GetPhotosOptions);
|
|
if (tag) { tags.push(tag); }
|
|
});
|
|
|
|
return tags;
|
|
};
|
|
|
|
const getPhotoCacheTag = (photoId: string) => `photo-${photoId}`;
|
|
|
|
const getPhotoTagCountTag = (tag: string) =>
|
|
`${TAG_PHOTOS_COUNT}-${TAG_TAGS}-${tag}`;
|
|
|
|
const getPhotoCameraCountTag = ({ make, model }: Camera) =>
|
|
`${TAG_PHOTOS_COUNT}-${TAG_CAMERAS}-${createCameraKey(make, model)}`;
|
|
|
|
export const revalidatePhotosTag = () =>
|
|
revalidateTag(TAG_PHOTOS);
|
|
|
|
export const revalidateTagsTag = () =>
|
|
revalidateTag(TAG_TAGS);
|
|
|
|
export const revalidateCamerasTag = () =>
|
|
revalidateTag(TAG_CAMERAS);
|
|
|
|
export const revalidateBlobTag = () =>
|
|
revalidateTag(TAG_BLOB);
|
|
|
|
export const revalidatePhotosAndBlobTag = () => {
|
|
revalidateTag(TAG_PHOTOS);
|
|
revalidateTag(TAG_BLOB);
|
|
};
|
|
|
|
export const revalidateAllTags = () => {
|
|
revalidatePhotosTag();
|
|
revalidateTagsTag();
|
|
revalidateCamerasTag();
|
|
revalidateBlobTag();
|
|
};
|
|
|
|
export const getPhotosCached: typeof getPhotos = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotos(...args),
|
|
[TAG_PHOTOS, ...getPhotosCacheTags(...args)], {
|
|
tags: [TAG_PHOTOS, ...getPhotosCacheTags(...args)],
|
|
}
|
|
)().then(parseCachedPhotosDates);
|
|
|
|
export const getPhotosCountCached: typeof getPhotosCount = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCount(...args),
|
|
[TAG_PHOTOS, TAG_PHOTOS_COUNT], {
|
|
tags: [TAG_PHOTOS, TAG_PHOTOS_COUNT],
|
|
}
|
|
)();
|
|
|
|
export const getPhotosCountTagCached: typeof getPhotosCountTag = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCountTag(...args),
|
|
[TAG_PHOTOS, getPhotoTagCountTag(...args)], {
|
|
tags: [TAG_PHOTOS, getPhotoTagCountTag(...args)],
|
|
}
|
|
)();
|
|
|
|
// eslint-disable-next-line max-len
|
|
export const getPhotosCountCameraCached: typeof getPhotosCountCamera = (...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCountCamera(...args),
|
|
[TAG_PHOTOS, getPhotoCameraCountTag(...args)], {
|
|
tags: [TAG_PHOTOS, getPhotoCameraCountTag(...args)],
|
|
}
|
|
)();
|
|
|
|
export const getPhotosCountIncludingHiddenCached: typeof getPhotosCount =
|
|
(...args) =>
|
|
unstable_cache(
|
|
() => getPhotosCountIncludingHidden(...args),
|
|
[TAG_PHOTOS, TAG_PHOTOS_COUNT], {
|
|
tags: [TAG_PHOTOS, TAG_PHOTOS_COUNT],
|
|
}
|
|
)();
|
|
|
|
export const getPhotoCached: typeof getPhoto = (...args) =>
|
|
unstable_cache(
|
|
() => getPhoto(...args),
|
|
[TAG_PHOTOS, getPhotoCacheTag(...args)], {
|
|
tags: [TAG_PHOTOS, getPhotoCacheTag(...args)],
|
|
}
|
|
)().then(photo => photo ? parseCachedPhotoDates(photo) : undefined);
|
|
|
|
export const getUniqueTagsCached: typeof getUniqueTags = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueTags(...args),
|
|
[TAG_PHOTOS, TAG_TAGS], {
|
|
tags: [TAG_PHOTOS, TAG_TAGS],
|
|
}
|
|
)();
|
|
|
|
export const getUniqueCamerasCached: typeof getUniqueCameras = (...args) =>
|
|
unstable_cache(
|
|
() => getUniqueCameras(...args),
|
|
[TAG_PHOTOS, TAG_CAMERAS], {
|
|
tags: [TAG_PHOTOS, TAG_CAMERAS],
|
|
}
|
|
)();
|
|
|
|
export const getBlobUploadUrlsCached: typeof getBlobUploadUrls = (...args) =>
|
|
unstable_cache(
|
|
() => getBlobUploadUrls(...args),
|
|
[TAG_BLOB], {
|
|
tags: [TAG_BLOB],
|
|
}
|
|
)();
|
|
|
|
export const getBlobPhotoUrlsCached: typeof getBlobPhotoUrls = (...args) =>
|
|
unstable_cache(
|
|
() => getBlobPhotoUrls(...args),
|
|
[TAG_BLOB], {
|
|
tags: [TAG_BLOB],
|
|
}
|
|
)();
|
|
|
|
export const getImageCacheHeadersForAuth = (session: AuthSession | null) => {
|
|
return {
|
|
'Cache-Control': !session?.user
|
|
? 's-maxage=3600, stale-while-revalidate=59'
|
|
: 's-maxage=1, stale-while-revalidate=59',
|
|
};
|
|
};
|