← back to Patternbank Archive
src/browser.js
52 lines
require('dotenv').config({ path: require('path').join(__dirname, '..', '.env') });
const { chromium } = require('playwright-core');
const Browserbase = require('@browserbasehq/sdk').default;
const UA = process.env.USER_AGENT
|| 'patternbank-archive-internal/0.1 (research; contact: steve@designerwallcoverings.com)';
let _bb;
function bb() {
if (_bb) return _bb;
_bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
return _bb;
}
async function newSession() {
const s = await bb().sessions.create({
projectId: process.env.BROWSERBASE_PROJECT_ID,
browserSettings: {
solveCaptchas: true,
blockAds: true,
},
});
return s; // { id, connectUrl, ... }
}
async function withPage(fn) {
const session = await newSession();
const browser = await chromium.connectOverCDP(session.connectUrl);
let ctx, page;
try {
ctx = browser.contexts()[0] || await browser.newContext();
await ctx.setExtraHTTPHeaders({ 'User-Agent': UA });
page = ctx.pages()[0] || await ctx.newPage();
return await fn(page, session);
} finally {
try { await browser.close(); } catch {}
}
}
async function fetchHtml(url, { waitFor='networkidle', timeout=45000 }={}) {
return withPage(async (page) => {
const resp = await page.goto(url, { waitUntil: waitFor, timeout });
const status = resp ? resp.status() : 0;
const html = await page.content();
return { status, html, finalUrl: page.url() };
});
}
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
module.exports = { newSession, withPage, fetchHtml, sleep, UA };