import { EsiTransformStream } from "@fastly/esi";
const sinceRegex = /^\/__since\/(\d+)$/;
addEventListener("fetch", (event) => event.respondWith(handleRequest(event)));
async function handleRequest(event) {
const req = event.request;
const headers = new Headers(req.headers);
headers.delete('accept-encoding');
const beresp = await fetch(req.url, {
headers,
backend: 'origin_0'
});
if (!beresp.headers.get('Content-Type')?.startsWith('text/html')) {
return beresp;
}
const esiTransformStream = new EsiTransformStream(req.url, headers, {
fetch(input, init) {
const url = new URL(input instanceof Request ? input.url : String(input));
const sinceMatch = sinceRegex.exec(url.pathname);
if (sinceMatch != null) {
const timestampString = sinceMatch[1];
const timestamp = parseInt(timestampString, 10);
return new Response(
toRelativeTimeSince(timestamp),
{
headers: {
'Content-Type': 'text/plain',
},
status: 200,
}
);
}
return fetch(input, { ...init, backend: 'origin_0' });
}
});
return new Response(
beresp.body.pipeThrough(esiTransformStream),
{
status: beresp.status,
headers: beresp.headers,
},
);
}
function toRelativeTimeSince(timestamp) {
const now = Date.now() / 1000;
const diff = now - timestamp;
if (diff < 60) {
const seconds = Math.floor(diff);
return `${seconds}s ago`;
}
if (diff < 60 * 60) {
const minutes = Math.floor(diff / 60);
return `${minutes}m ago`;
}
if (diff < 60 * 60 * 24) {
const hours = Math.floor(diff / (60 * 60));
return `${hours}h ago`;
}
const days = Math.floor(diff / (60 * 60 * 24));
return `${days}d ago`;
}