65 lines
1.4 KiB
TypeScript
65 lines
1.4 KiB
TypeScript
import { hash } from "@lib/hash.ts";
|
|
import * as cache from "@lib/cache/cache.ts";
|
|
|
|
type ImageCacheOptions = {
|
|
url: string;
|
|
width: number;
|
|
height: number;
|
|
mediaType?: string;
|
|
};
|
|
|
|
const CACHE_KEY = "images";
|
|
|
|
function getCacheKey({ url: _url, width, height }: ImageCacheOptions) {
|
|
const url = new URL(_url);
|
|
return `${CACHE_KEY}/${url.hostname}/${url.pathname}/${width}/${height}`
|
|
.replace(
|
|
"//",
|
|
"/",
|
|
);
|
|
}
|
|
|
|
export async function getImage({ url, width, height }: ImageCacheOptions) {
|
|
const cacheKey = getCacheKey({ url, width, height });
|
|
|
|
const pointerCacheRaw = await cache.get<string>(cacheKey);
|
|
if (!pointerCacheRaw) return;
|
|
|
|
const pointerCache = typeof pointerCacheRaw === "string"
|
|
? JSON.parse(pointerCacheRaw)
|
|
: pointerCacheRaw;
|
|
|
|
const imageContent = await cache.get(pointerCache.id, true);
|
|
if (!imageContent) return;
|
|
|
|
return {
|
|
...pointerCache,
|
|
buffer: imageContent,
|
|
};
|
|
}
|
|
|
|
export async function setImage(
|
|
buffer: Uint8Array,
|
|
{ url, width, height, mediaType }: ImageCacheOptions,
|
|
) {
|
|
const clone = new Uint8Array(buffer);
|
|
|
|
const cacheKey = getCacheKey({ url, width, height });
|
|
const pointerId = await hash(cacheKey);
|
|
|
|
await cache.set(pointerId, clone);
|
|
cache.expire(pointerId, 60 * 10);
|
|
cache.expire(cacheKey, 60 * 10);
|
|
|
|
await cache.set(
|
|
cacheKey,
|
|
JSON.stringify({
|
|
id: pointerId,
|
|
url,
|
|
width,
|
|
height,
|
|
mediaType,
|
|
}),
|
|
);
|
|
}
|