Files
ditto/src/middleware/cache.ts

46 lines
1.2 KiB
TypeScript

import { Debug, type MiddlewareHandler } from '@/deps.ts';
const debug = Debug('ditto:middleware:cache');
interface CacheOpts {
expires: number;
}
/** In-memory cache middleware. */
export const cache = (opts: CacheOpts): MiddlewareHandler => {
let response: Response | undefined;
let expires = Date.now() + opts.expires;
return async (c, next) => {
const now = Date.now();
const expired = now > expires;
async function updateCache() {
await next();
const res = c.res.clone();
if (res.status < 500) {
const old = response;
response = res;
old?.text(); // Prevent memory leaks.
}
return res;
}
if (response && !expired) {
debug('Serving page from cache', c.req.url);
return response.clone();
} else {
expires = Date.now() + opts.expires;
if (response && expired) {
debug('Serving stale cache, rebuilding', c.req.url);
const stale = response.clone();
updateCache();
await new Promise((resolve) => setTimeout(resolve, 0));
return stale;
}
debug('Building cache for page', c.req.url);
return await updateCache();
}
};
};