mirror of
https://github.com/aljazceru/ditto.git
synced 2025-12-25 01:04:25 +01:00
46 lines
1.2 KiB
TypeScript
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();
|
|
}
|
|
};
|
|
};
|