/** * Fetches Twemoji glyphs from the jsDelivr CDN, for `lib/site-icons.ts` to * render the favicons from. * * @module */ /** Pinned, so a new Twemoji release can't change the icons unasked. */ const TWEMOJI_VERSION = "16.0.1"; /** * Glyphs by codepoint. It only lives as long as the process, and the `icons` * task renders one emoji per process. */ const glyphCache = new Map(); /** * Returns Twemoji's SVG for `emoji`, whose file name `cp` comes from * `emojiToCodepoint`. `emoji` only serves the error message. It fetches with * plain `fetch`, since the host is fixed. * * @throws {Error} When the glyph can't be fetched. */ export async function fetchTwemojiSvg( emoji: string, cp: string, ): Promise { const cached = glyphCache.get(cp); if (cached) return cached; const url = `https://cdn.jsdelivr.net/gh/jdecked/twemoji@${TWEMOJI_VERSION}/assets/svg/${cp}.svg`; let res: Response; try { res = await fetch(url); } catch (cause) { throw new Error( `Failed to fetch Twemoji glyph for "${emoji}" (${cp}) from ${url}`, { cause }, ); } if (!res.ok) { throw new Error( `Failed to fetch Twemoji glyph for "${emoji}" (${cp}) from ${url}: ${res.status} ${res.statusText}`, ); } const svg = await res.text(); glyphCache.set(cp, svg); return svg; }