import { CODE_FONT_OPTION_MAP, UI_FONT_OPTION_MAP, type FontFaceSource, type MonoFontOption, type UiFontOption } from '@/lib/fontOptions'; const loadedFaces = new Set(); const pendingFaces = new Map>(); const buildFontUrl = (source: FontFaceSource, weight: number) => { if ('urls' in source) { return source.urls[weight]; } const packageName = encodeURIComponent(source.packageName).replace('%40', '@').replace('%2F', '/'); return `https://cdn.jsdelivr.net/npm/${packageName}/files/${source.filePrefix}-latin-${weight}-normal.woff2`; }; const loadFace = (source: FontFaceSource, weight: number) => { const key = `${source.family}:${weight}`; if (loadedFaces.has(key)) { return Promise.resolve(); } const pending = pendingFaces.get(key); if (pending) { return pending; } if (typeof document === 'undefined' || typeof FontFace === 'undefined' || !document.fonts) { return Promise.resolve(); } const face = new FontFace(source.family, `url(${buildFontUrl(source, weight)}) format('woff2')`, { style: 'normal', weight: String(weight), display: 'swap', }); document.fonts.add(face); const promise = face.load() .then(() => { loadedFaces.add(key); }) .catch((error) => { document.fonts.delete(face); console.warn(`Failed to load font: ${source.family} ${weight}`, error); }) .finally(() => { pendingFaces.delete(key); }); pendingFaces.set(key, promise); return promise; }; const loadSource = (source: FontFaceSource | undefined) => { if (!source) { return Promise.resolve(); } return Promise.all(source.weights.map((weight) => loadFace(source, weight))).then(() => undefined); }; export const loadUiFont = (font: UiFontOption) => loadSource(UI_FONT_OPTION_MAP[font]?.source); export const loadMonoFont = (font: MonoFontOption) => loadSource(CODE_FONT_OPTION_MAP[font]?.source);