/** * The built frontend's `index.html`, with its runtime placeholders filled: the * site name, emoji, icon version and Bandcamp player mode. * * @module */ import { BANDCAMP_PLAYER, OG_SITE_NAME, SITE_EMOJI } from "../config.ts"; import { emojiToCodepoint } from "./site-icons.ts"; /** The cache-busting version of the icon URLs. */ const ICON_VERSION = emojiToCodepoint(SITE_EMOJI); /** * `index.html` with its placeholders filled, by root. Kept until the file * changes (a rebuild under a running server): a stat per navigation instead of * a read and four replaceAll. */ const indexHtml = new Map(); /** * Returns `${root}/index.html` with its placeholders filled. * * @throws {Error} When the file can't be read. */ export async function loadIndexHtml(root: string): Promise { const path = `${root}/index.html`; const mtime = (await Deno.stat(path)).mtime?.getTime() ?? 0; const cached = indexHtml.get(root); if (cached && cached.mtime === mtime) return cached.html; const html = (await Deno.readTextFile(path)) .replaceAll("__SITE_NAME__", OG_SITE_NAME) .replaceAll("__SITE_EMOJI__", SITE_EMOJI) .replaceAll("__ICON_VERSION__", ICON_VERSION) .replaceAll("__BANDCAMP_PLAYER__", BANDCAMP_PLAYER); indexHtml.set(root, { mtime, html }); return html; }