UNPKG

@truefrontier/puppeteer-laravel-mcp-server

Version:

A Model Context Protocol server for Laravel Herd browser automation using Puppeteer

118 lines 4.14 kB
import puppeteer from 'puppeteer'; import { createPool } from 'generic-pool'; import { serverConfig, browserPoolConfig } from '../core/config.js'; import { v4 as uuidv4 } from 'uuid'; export class BrowserPool { pool; instances = new Map(); constructor(config = browserPoolConfig) { this.pool = createPool({ create: async () => { const launchConfig = { headless: serverConfig.headless, args: [ '--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu', '--no-first-run', '--no-zygote', '--single-process', '--disable-background-timer-throttling', '--disable-backgrounding-occluded-windows', '--disable-renderer-backgrounding', ], }; // Only set executablePath if configured if (serverConfig.chromePath) { launchConfig.executablePath = serverConfig.chromePath; } const browser = await puppeteer.launch(launchConfig); const instance = { browser, id: uuidv4(), created: new Date(), lastUsed: new Date(), activePages: 0, }; this.instances.set(instance.id, instance); return instance; }, destroy: async (instance) => { try { await instance.browser.close(); this.instances.delete(instance.id); } catch (error) { console.error('Error closing browser instance:', error); } }, validate: async (instance) => { try { const pages = await instance.browser.pages(); return instance.browser.isConnected() && pages.length >= 0; } catch { return false; } }, }, config); } async acquire() { const instance = await this.pool.acquire(); instance.lastUsed = new Date(); return instance; } async release(instance) { instance.lastUsed = new Date(); await this.pool.release(instance); } async createPage(instance) { const page = await instance.browser.newPage(); instance.activePages++; // Set default viewport await page.setViewport({ width: 1280, height: 720, deviceScaleFactor: 1, }); // Enable console logging if debug mode is on if (serverConfig.debugConsoleLogs) { page.on('console', (msg) => { console.log(`[Browser Console ${instance.id}]:`, msg.text()); }); page.on('pageerror', (error) => { console.error(`[Browser Error ${instance.id}]:`, error.message); }); } return page; } async closePage(instance, page) { try { await page.close(); instance.activePages = Math.max(0, instance.activePages - 1); } catch (error) { console.error('Error closing page:', error); } } getStats() { return { size: this.pool.size, available: this.pool.available, borrowed: this.pool.borrowed, pending: this.pool.pending, instances: Array.from(this.instances.values()).map(instance => ({ id: instance.id, created: instance.created, lastUsed: instance.lastUsed, activePages: instance.activePages, })), }; } async drain() { await this.pool.drain(); await this.pool.clear(); } } //# sourceMappingURL=pool.js.map