@cf-wasm/og
Version:
Generate Open Graph Images dynamically from HTML/CSS without a browser.
120 lines (119 loc) • 4.47 kB
JavaScript
import { ASSET_CACHE_MAP, EMOJI_CACHE_MAP, FONT_CACHE_MAP } from "./maps.js";
//#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 === null || ctx === void 0 ? void 0 : 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) {
var _CACHE_INSTANCE_MAP$g;
if (typeof this.store === "object") return this.store;
const name = typeof cacheName === "string" ? cacheName : this.store;
const store = this.supported ? (_CACHE_INSTANCE_MAP$g = CACHE_INSTANCE_MAP.get(name)) !== null && _CACHE_INSTANCE_MAP$g !== void 0 ? _CACHE_INSTANCE_MAP$g : 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 !== null && cacheStore !== void 0 ? 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 === null || res === void 0 ? void 0 : 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 === null || response === void 0 || response.headers.delete(_key);
else if (typeof preserveHeaders === "function" && !preserveHeaders(_key, value, response, store, key)) response === null || response === void 0 || response.headers.delete(_key);
else if (!(Array.isArray(preserveHeaders) ? preserveHeaders : ["content-type", "cache-control"]).map((e) => e.toLowerCase()).includes(_key.toLowerCase())) response === null || response === void 0 || 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() {
ASSET_CACHE_MAP.clear();
CACHE_INSTANCE_MAP.clear();
EMOJI_CACHE_MAP.clear();
FONT_CACHE_MAP.clear();
}
};
const cache = new CacheUtils();
//#endregion
export { CACHE_INSTANCE_MAP, CACHE_INTERFACE, cache };
//# sourceMappingURL=cache.js.map