@cf-wasm/og
Version:
Generate Open Graph Images dynamically from HTML/CSS without a browser.
1 lines • 8.78 kB
Source Map (JSON)
{"version":3,"file":"cache.cjs","names":[],"sources":["../../src/core/cache.ts"],"sourcesContent":["import { ASSET_CACHE_MAP, EMOJI_CACHE_MAP, FONT_CACHE_MAP } from './maps';\nimport type { MayBePromise } from './types';\n\n/** The execution context interface */\nexport interface ExecutionContext {\n\twaitUntil(promise: Promise<unknown>): void;\n}\n\n/** Cache instance map */\nexport const CACHE_INSTANCE_MAP = new Map<string, Cache>();\n\n/** A Cache like no-op object */\nexport const CACHE_INTERFACE: Cache = {\n\tadd: () => Promise.resolve(),\n\taddAll: () => Promise.resolve(),\n\tdelete: () => Promise.resolve(false),\n\tkeys: () => Promise.resolve([]),\n\tmatch: () => Promise.resolve(undefined),\n\tmatchAll: () => Promise.resolve([]),\n\tput: () => Promise.resolve(),\n};\n\n/**\n * An interface representing options for `cache.serve` method\n */\nexport interface ServeCacheOptions<K extends RequestInfo | URL> {\n\t/**\n\t * The {@link Cache} to use if provided, otherwise uses default\n\t */\n\tcache?: Cache;\n\n\t/**\n\t * Preserve headers from response headers being removed\n\t */\n\tpreserveHeaders?:\n\t\t| string[]\n\t\t| ((\n\t\t\t\theaderKey: string,\n\t\t\t\theaderValue: string,\n\t\t\t\tresponse: Response,\n\t\t\t\tcacheStore: Cache,\n\t\t\t\tcacheKey: K,\n\t\t ) => boolean)\n\t\t| boolean;\n\n\t/**\n\t * Indicates whether `Cache-Control should be overwritten`.\n\t * It also can be a string representing the header value\n\t *\n\t * @default true\n\t */\n\toverwriteCacheControl?: string | boolean;\n}\n\n/** Cache utils */\nclass CacheUtils {\n\t/** Indicates whether cache is enabled */\n\tprivate _enabled = true;\n\n\t/**\n\t * Indicates whether {@link Cache} api is supported\n\t * in current environment or not\n\t */\n\tget supported() {\n\t\treturn typeof caches !== 'undefined';\n\t}\n\n\t/**\n\t * The {@link Cache} instance or a\n\t * string representing the name of {@link Cache} to be opened\n\t */\n\tstore: string | Cache = 'cf-wasm-og-cache';\n\n\t/**\n\t * The `Cache-Control` header to set for asset responses for caching\n\t *\n\t * @default 'public, max-age=604800, s-maxage=43200'\n\t */\n\tcacheControlHeader = 'public, max-age=604800, s-maxage=43200';\n\n\t/** The waitUntil function */\n\tprivate _waitUntil?: (promise: Promise<unknown>) => void;\n\n\t/** Enables cache */\n\tenable() {\n\t\tthis._enabled = true;\n\t}\n\n\t/** Disables cache */\n\tdisable() {\n\t\tthis._enabled = false;\n\t}\n\n\t/**\n\t * Sets execution context\n\t *\n\t * Example for Cloudflare workers:\n\t *\n\t * ```ts\n\t * import { cache } from \"@cf-wasm/og\";\n\t *\n\t * export interface Env {}\n\t *\n\t * export default {\n\t * fetch(req: Request, env: Env, ctx: ExecutionContext) {\n\t * cache.setExecutionContext(ctx);\n\t *\n\t * // ...\n\t * }\n\t * }\n\t * ```\n\t */\n\tsetExecutionContext(ctx: ExecutionContext) {\n\t\tif (typeof ctx?.waitUntil !== 'function') {\n\t\t\tthrow new TypeError(\n\t\t\t\t'Provided object is not an execution context object.',\n\t\t\t);\n\t\t}\n\t\tthis._waitUntil = (promise) => ctx.waitUntil(promise);\n\t}\n\n\t/**\n\t * Opens a cache\n\t *\n\t * @param cacheName If provided, the name of cache to be opened\n\t *\n\t * @returns A promise which resolves to {@link Cache}\n\t */\n\tasync open(cacheName?: string): Promise<Cache> {\n\t\tif (typeof this.store === 'object') {\n\t\t\treturn this.store;\n\t\t}\n\t\tconst name = typeof cacheName === 'string' ? cacheName : this.store;\n\t\tconst store = this.supported\n\t\t\t? (CACHE_INSTANCE_MAP.get(name) ?? (await caches.open(name)))\n\t\t\t: CACHE_INTERFACE;\n\t\tCACHE_INSTANCE_MAP.set(name, store);\n\t\treturn store;\n\t}\n\n\t/**\n\t * Serve cached assets\n\t *\n\t * @param key The cache key\n\t * @param fallback The fallback function which provides the {@link Response} when cache key is not matched\n\t * @param param2 Options\n\t *\n\t * @returns A promise which resolves to {@link Response}\n\t */\n\tasync serve<\n\t\tK extends RequestInfo | URL,\n\t\tF extends (\n\t\t\tcacheKey: K,\n\t\t\tcacheStore: Cache,\n\t\t) => MayBePromise<Response | undefined>,\n\t>(\n\t\tkey: K,\n\t\tfallback: F,\n\t\t{\n\t\t\tcache: cacheStore,\n\t\t\tpreserveHeaders,\n\t\t\toverwriteCacheControl = true,\n\t\t}: ServeCacheOptions<K> = {},\n\t): Promise<Awaited<ReturnType<F>>> {\n\t\tconst store = cacheStore ?? (await this.open());\n\n\t\tlet response: Response | undefined;\n\n\t\tif (!this._enabled || !this.supported || !this._waitUntil) {\n\t\t\tconst fallbackResponse = await fallback(key, store);\n\n\t\t\tif (fallbackResponse instanceof Response) {\n\t\t\t\tresponse = new Response(fallbackResponse.body, fallbackResponse);\n\t\t\t}\n\t\t} else {\n\t\t\tresponse = await store\n\t\t\t\t.match(key)\n\t\t\t\t.then((res) => (res?.ok ? res : undefined));\n\n\t\t\tif (!response) {\n\t\t\t\tconst fallbackResponse = await fallback(key, store);\n\n\t\t\t\tif (fallbackResponse instanceof Response) {\n\t\t\t\t\tresponse = new Response(fallbackResponse.body, fallbackResponse);\n\n\t\t\t\t\tif (preserveHeaders !== true) {\n\t\t\t\t\t\tresponse.headers.forEach((value, _key) => {\n\t\t\t\t\t\t\tif (preserveHeaders === false) {\n\t\t\t\t\t\t\t\tresponse?.headers.delete(_key);\n\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\ttypeof preserveHeaders === 'function' &&\n\t\t\t\t\t\t\t\t!preserveHeaders(_key, value, response as Response, store, key)\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tresponse?.headers.delete(_key);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst preservedHeaders = (\n\t\t\t\t\t\t\t\t\tArray.isArray(preserveHeaders)\n\t\t\t\t\t\t\t\t\t\t? preserveHeaders\n\t\t\t\t\t\t\t\t\t\t: ['content-type', 'cache-control']\n\t\t\t\t\t\t\t\t).map((e) => e.toLowerCase());\n\t\t\t\t\t\t\t\tif (!preservedHeaders.includes(_key.toLowerCase())) {\n\t\t\t\t\t\t\t\t\tresponse?.headers.delete(_key);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\toverwriteCacheControl === true ||\n\t\t\t\t\t\ttypeof overwriteCacheControl === 'string' ||\n\t\t\t\t\t\t!response.headers.has('Cache-Control')\n\t\t\t\t\t) {\n\t\t\t\t\t\tresponse.headers.set(\n\t\t\t\t\t\t\t'Cache-Control',\n\t\t\t\t\t\t\ttypeof overwriteCacheControl === 'string'\n\t\t\t\t\t\t\t\t? overwriteCacheControl\n\t\t\t\t\t\t\t\t: this.cacheControlHeader,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst promise = store.put(key, response.clone());\n\t\t\t\t\tthis._waitUntil(promise);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tresponse = new Response(response.body, response);\n\t\t\t}\n\t\t}\n\n\t\treturn response as unknown as Promise<Awaited<ReturnType<F>>>;\n\t}\n\n\tclearMaps() {\n\t\tASSET_CACHE_MAP.clear();\n\t\tCACHE_INSTANCE_MAP.clear();\n\t\tEMOJI_CACHE_MAP.clear();\n\t\tFONT_CACHE_MAP.clear();\n\t}\n}\n\nexport const cache = new CacheUtils();\n"],"mappings":";;;AASA,MAAa,qCAAqB,IAAI,IAAmB;;AAGzD,MAAa,kBAAyB;CACrC,WAAW,QAAQ,QAAQ;CAC3B,cAAc,QAAQ,QAAQ;CAC9B,cAAc,QAAQ,QAAQ,KAAK;CACnC,YAAY,QAAQ,QAAQ,CAAC,CAAC;CAC9B,aAAa,QAAQ,QAAQ,KAAA,CAAS;CACtC,gBAAgB,QAAQ,QAAQ,CAAC,CAAC;CAClC,WAAW,QAAQ,QAAQ;AAC5B;;AAmCA,IAAM,aAAN,MAAiB;;kBAEG;eAcK;4BAOH;;;;;;CAfrB,IAAI,YAAY;EACf,OAAO,OAAO,WAAW;CAC1B;;CAmBA,SAAS;EACR,KAAK,WAAW;CACjB;;CAGA,UAAU;EACT,KAAK,WAAW;CACjB;;;;;;;;;;;;;;;;;;;;CAqBA,oBAAoB,KAAuB;EAC1C,IAAI,OAAO,KAAK,cAAc,YAC7B,MAAM,IAAI,UACT,qDACD;EAED,KAAK,cAAc,YAAY,IAAI,UAAU,OAAO;CACrD;;;;;;;;CASA,MAAM,KAAK,WAAoC;EAC9C,IAAI,OAAO,KAAK,UAAU,UACzB,OAAO,KAAK;EAEb,MAAM,OAAO,OAAO,cAAc,WAAW,YAAY,KAAK;EAC9D,MAAM,QAAQ,KAAK,YACf,mBAAmB,IAAI,IAAI,KAAM,MAAM,OAAO,KAAK,IAAI,IACxD;EACH,mBAAmB,IAAI,MAAM,KAAK;EAClC,OAAO;CACR;;;;;;;;;;CAWA,MAAM,MAOL,KACA,UACA,EACC,OAAO,YACP,iBACA,wBAAwB,SACC,CAAC,GACO;EAClC,MAAM,QAAQ,cAAe,MAAM,KAAK,KAAK;EAE7C,IAAI;EAEJ,IAAI,CAAC,KAAK,YAAY,CAAC,KAAK,aAAa,CAAC,KAAK,YAAY;GAC1D,MAAM,mBAAmB,MAAM,SAAS,KAAK,KAAK;GAElD,IAAI,4BAA4B,UAC/B,WAAW,IAAI,SAAS,iBAAiB,MAAM,gBAAgB;EAEjE,OAAO;GACN,WAAW,MAAM,MACf,MAAM,GAAG,CAAC,CACV,MAAM,QAAS,KAAK,KAAK,MAAM,KAAA,CAAU;GAE3C,IAAI,CAAC,UAAU;IACd,MAAM,mBAAmB,MAAM,SAAS,KAAK,KAAK;IAElD,IAAI,4BAA4B,UAAU;KACzC,WAAW,IAAI,SAAS,iBAAiB,MAAM,gBAAgB;KAE/D,IAAI,oBAAoB,MACvB,SAAS,QAAQ,SAAS,OAAO,SAAS;MACzC,IAAI,oBAAoB,OACvB,UAAU,QAAQ,OAAO,IAAI;WACvB,IACN,OAAO,oBAAoB,cAC3B,CAAC,gBAAgB,MAAM,OAAO,UAAsB,OAAO,GAAG,GAE9D,UAAU,QAAQ,OAAO,IAAI;WAO7B,IAAI,EAJH,MAAM,QAAQ,eAAe,IAC1B,kBACA,CAAC,gBAAgB,eAAe,EAAA,CAClC,KAAK,MAAM,EAAE,YAAY,CACP,CAAC,CAAC,SAAS,KAAK,YAAY,CAAC,GAChD,UAAU,QAAQ,OAAO,IAAI;KAGhC,CAAC;KAGF,IACC,0BAA0B,QAC1B,OAAO,0BAA0B,YACjC,CAAC,SAAS,QAAQ,IAAI,eAAe,GAErC,SAAS,QAAQ,IAChB,iBACA,OAAO,0BAA0B,WAC9B,wBACA,KAAK,kBACT;KAGD,MAAM,UAAU,MAAM,IAAI,KAAK,SAAS,MAAM,CAAC;KAC/C,KAAK,WAAW,OAAO;IACxB;GACD,OACC,WAAW,IAAI,SAAS,SAAS,MAAM,QAAQ;EAEjD;EAEA,OAAO;CACR;CAEA,YAAY;EACX,aAAA,gBAAgB,MAAM;EACtB,mBAAmB,MAAM;EACzB,aAAA,gBAAgB,MAAM;EACtB,aAAA,eAAe,MAAM;CACtB;AACD;AAEA,MAAa,QAAQ,IAAI,WAAW"}