UNPKG

@cf-wasm/og

Version:

Generate Open Graph Images dynamically from HTML/CSS without a browser.

121 lines (120 loc) 4.16 kB
const require_maps = require("./maps.cjs"); //#region src/core/cache.ts /** Cache instance map */ const CACHE_INSTANCE_MAP = /* @__PURE__ */ new Map(); /** A Cache like no-op object */ const CACHE_INTERFACE = { add: () => Promise.resolve(), addAll: () => Promise.resolve(), delete: () => Promise.resolve(false), keys: () => Promise.resolve([]), match: () => Promise.resolve(void 0), matchAll: () => Promise.resolve([]), put: () => Promise.resolve() }; /** Cache utils */ var CacheUtils = class { constructor() { this._enabled = true; this.store = "cf-wasm-og-cache"; this.cacheControlHeader = "public, max-age=604800, s-maxage=43200"; } /** * Indicates whether {@link Cache} api is supported * in current environment or not */ get supported() { return typeof caches !== "undefined"; } /** Enables cache */ enable() { this._enabled = true; } /** Disables cache */ disable() { this._enabled = false; } /** * Sets execution context * * Example for Cloudflare workers: * * ```ts * import { cache } from "@cf-wasm/og"; * * export interface Env {} * * export default { * fetch(req: Request, env: Env, ctx: ExecutionContext) { * cache.setExecutionContext(ctx); * * // ... * } * } * ``` */ setExecutionContext(ctx) { if (typeof ctx?.waitUntil !== "function") throw new TypeError("Provided object is not an execution context object."); this._waitUntil = (promise) => ctx.waitUntil(promise); } /** * Opens a cache * * @param cacheName If provided, the name of cache to be opened * * @returns A promise which resolves to {@link Cache} */ async open(cacheName) { if (typeof this.store === "object") return this.store; const name = typeof cacheName === "string" ? cacheName : this.store; const store = this.supported ? CACHE_INSTANCE_MAP.get(name) ?? await caches.open(name) : CACHE_INTERFACE; CACHE_INSTANCE_MAP.set(name, store); return store; } /** * Serve cached assets * * @param key The cache key * @param fallback The fallback function which provides the {@link Response} when cache key is not matched * @param param2 Options * * @returns A promise which resolves to {@link Response} */ async serve(key, fallback, { cache: cacheStore, preserveHeaders, overwriteCacheControl = true } = {}) { const store = cacheStore ?? await this.open(); let response; if (!this._enabled || !this.supported || !this._waitUntil) { const fallbackResponse = await fallback(key, store); if (fallbackResponse instanceof Response) response = new Response(fallbackResponse.body, fallbackResponse); } else { response = await store.match(key).then((res) => res?.ok ? res : void 0); if (!response) { const fallbackResponse = await fallback(key, store); if (fallbackResponse instanceof Response) { response = new Response(fallbackResponse.body, fallbackResponse); if (preserveHeaders !== true) response.headers.forEach((value, _key) => { if (preserveHeaders === false) response?.headers.delete(_key); else if (typeof preserveHeaders === "function" && !preserveHeaders(_key, value, response, store, key)) response?.headers.delete(_key); else if (!(Array.isArray(preserveHeaders) ? preserveHeaders : ["content-type", "cache-control"]).map((e) => e.toLowerCase()).includes(_key.toLowerCase())) response?.headers.delete(_key); }); if (overwriteCacheControl === true || typeof overwriteCacheControl === "string" || !response.headers.has("Cache-Control")) response.headers.set("Cache-Control", typeof overwriteCacheControl === "string" ? overwriteCacheControl : this.cacheControlHeader); const promise = store.put(key, response.clone()); this._waitUntil(promise); } } else response = new Response(response.body, response); } return response; } clearMaps() { require_maps.ASSET_CACHE_MAP.clear(); CACHE_INSTANCE_MAP.clear(); require_maps.EMOJI_CACHE_MAP.clear(); require_maps.FONT_CACHE_MAP.clear(); } }; const cache = new CacheUtils(); //#endregion exports.CACHE_INSTANCE_MAP = CACHE_INSTANCE_MAP; exports.CACHE_INTERFACE = CACHE_INTERFACE; exports.cache = cache; //# sourceMappingURL=cache.cjs.map