feat: Initial prototype

This commit is contained in:
abdus committed 2026-10-10 12:51:33 +02:00
commit 819f6a61cd
327 files changed
+252446

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
import figlet from './vendor/figlet.js';
import {fonts} from './font-catalog.js';
import {render as renderBitmap} from './bitmap.js';
export const styles = [...fonts, 'compact'];
export const FONT_CACHE = `ascii-pwa-fonts-${encodeURIComponent(new URL('./', import.meta.url).href)}-figlet-1.8.2`;
const pendingFonts = new Map();
// Keep existing lowercase font links working with the library's font names.
export function resolveFont(name) {
if (name === 'compact') return name;
return fonts.find(font => font.toLowerCase() === String(name).toLowerCase()) || 'Standard';
}
export function registerFont(name, data) {
if (!fonts.includes(name)) throw new Error('Unknown lettering style');
figlet.parseFont(name, data);
}
export function renderLoaded(text, font = 'Standard') {
if (text.length > 500) throw new Error('Text is too long');
if (font === 'compact') return renderBitmap(text, font);
if (!fonts.includes(font)) throw new Error('Unknown lettering style');
return figlet.textSync(text, {
font, width: 80, whitespaceBreak: true,
}).split('\n').filter(line => line.trim()).join('\n');
}
export async function render(text, font = 'Standard') {
if (text.length > 500) throw new Error('Text is too long');
if (font === 'compact') return renderBitmap(text, font);
if (!fonts.includes(font)) throw new Error('Unknown lettering style');
if (!figlet.figFonts[font]) {
if (!pendingFonts.has(font)) {
pendingFonts.set(font, (async () => {
const url = new URL(`./fonts/figlet/${font}.flf`, import.meta.url).href;
let cache;
let cached;
try {
if ('caches' in globalThis) {
cache = await caches.open(FONT_CACHE);
cached = await cache.match(url);
}
} catch { /* Rendering still works if browser storage is unavailable. */ }
const response = cached || await fetch(url);
if (!response.ok) throw new Error('Cannot load font');
registerFont(font, await response.clone().text());
if (cache && !cached) {
try { await cache.put(url, response); } catch { /* Storage may be full. */ }
}
})().finally(() => pendingFonts.delete(font)));
}
await pendingFonts.get(font);
}
return renderLoaded(text, font);
}