import puppeteer from 'puppeteer' import fs from 'node:fs' const style = fs.readFileSync('./assets/style.css', 'utf8') const browser = await puppeteer.launch({ defaultViewport: { width: 1200, height: 600 }, headless: 'new', // slowMo: 250, args: [ // TODO: fix this '--disable-gpu', '--disable-dev-shm-usage', '--disable-setuid-sandbox', '--no-sandbox' ] }) async function wait() { const selectors = [...document.querySelectorAll('img')] await Promise.all([ document.fonts.ready, ...selectors.map(img => { // Image has already finished loading, let’s see if it worked if (img.complete) { // Image loaded and has presence if (img.naturalHeight !== 0) return // Image failed, so it has no height throw new Error('Image failed to load') } // Image hasn’t loaded yet, added an event listener to know when it does return new Promise((resolve, reject) => { img.addEventListener('load', resolve) img.addEventListener('error', reject) }) }) ]) } export async function renderPage(html) { const page = await browser.newPage() try { await page.setContent(html, { waitUntil: 'domcontentloaded' }) await page.evaluate(wait) const buffer = await page.screenshot({ type: 'png', encoding: 'binary' }) await page.close() return buffer } catch { await page.close() throw new Error('Failed to render page') } } export default async function (html, options = {}) { if (options.format == 'html') { return await renderHtml(html) } return renderPage(`${html}`) } export async function renderHtml(html) { const styleNow = await fs.promises.readFile('./assets/style.css', 'utf8') return `${html}` }