UNPKG

1.27 kBPlain TextView Raw
1// deno-lint-ignore-file no-explicit-any
2import type { Temporal } from 'temporal-spec';
3import type { Awaitable } from "./utils/common-types.js";
4import type { Context } from "./index.js";
5
6import { format, CacheControl } from '@tusbar/cache-control'
7
8/**
9 * The Cache-Control HTTP header field holds directives (instructions)
10 * — in both requests and responses — that control caching in browsers
11 * and shared caches (e.g. Proxies, CDNs).
12 *
13 * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
14 */
15export type CacheOptions = {
16 [K in keyof CacheControl]: CacheControl[K] extends (number | null | undefined)
17 ? number | Temporal.Duration | null
18 : CacheControl[K]
19}
20
21const SECOND = { unit: 'second', relativeTo: '1970-01-01' } as Temporal.DurationTotalOf;
22const isDuration = (x?: unknown): x is Temporal.Duration => (<any>x)?.[Symbol.toStringTag] === 'Temporal.Duration'
23
24export const caching = (options: CacheOptions = {}) => async <X extends Context>(ax: Awaitable<X>) => {
25 const x = await ax;
26 const opts: CacheControl = Object.fromEntries(
27 Object.entries(options).map(([k, v]) => [k, isDuration(v) ? v.total(SECOND) : v])
28 );
29 x.effects.push(res => res.headers.set('Cache-Control', format(opts)));
30 return x;
31}