UNPKG

@nuxthub/core

Version:

Build full-stack Nuxt applications on Cloudflare, with zero configuration.

96 lines (95 loc) 2.87 kB
import cfPuppeteer, { PuppeteerWorkers } from "@cloudflare/puppeteer"; import { createError } from "h3"; import { useNitroApp, useEvent } from "#imports"; function getBrowserBinding(name = "BROWSER") { return process.env[name] || globalThis.__env__?.[name] || globalThis[name]; } let _browserPromise = null; let _browser = null; export async function hubBrowser(options = {}) { const puppeteer = await getPuppeteer(); const nitroApp = useNitroApp(); const event = useEvent(); if (puppeteer instanceof PuppeteerWorkers) { const binding = getBrowserBinding(); if (!binding) { throw createError("Missing Cloudflare Browser binding (BROWSER)"); } let browser = null; const sessionId = await getRandomSession(puppeteer, binding); if (sessionId) { try { browser = await puppeteer.connect(binding, sessionId); } catch (e) { } } if (!browser) { browser = await puppeteer.launch(binding, { // keep_alive is in milliseconds // https://developers.cloudflare.com/browser-rendering/platform/puppeteer/#keep-alive keep_alive: (options.keepAlive || 60) * 1e3 }); } const page2 = await browser.newPage(); const unregister2 = nitroApp.hooks.hook("afterResponse", async (closingEvent) => { if (event !== closingEvent) return; unregister2(); await page2?.close().catch(() => { }); browser?.disconnect(); }); return { browser, page: page2 }; } if (!_browserPromise) { _browserPromise = puppeteer.launch(); nitroApp.hooks.hook("close", async () => { const browser = _browser || await _browserPromise; browser?.close(); _browserPromise = null; _browser = null; }); } if (!_browser) { _browser = await _browserPromise; _browser.disconnect = () => Promise.resolve(); } const page = await _browser.newPage(); const unregister = nitroApp.hooks.hook("afterResponse", async (closingEvent) => { if (event !== closingEvent) return; unregister(); await page?.close().catch(() => { }); }); return { browser: _browser, page }; } async function getRandomSession(puppeteer, binding) { const sessions = await puppeteer.sessions(binding); const sessionsIds = sessions.filter((v) => !v.connectionId).map((v) => v.sessionId); if (!sessionsIds.length) { return null; } return sessionsIds[Math.floor(Math.random() * sessionsIds.length)]; } let _puppeteer; async function getPuppeteer() { if (_puppeteer) { return _puppeteer; } if (import.meta.dev) { const _pkg = "puppeteer"; _puppeteer = await import(_pkg).catch(() => { throw new Error( "Package `puppeteer` not found, please install it with: `npx nypm i puppeteer`" ); }); } else { _puppeteer = cfPuppeteer; } return _puppeteer; }