import * as plugins from './smartssr.plugins.js'; import * as paths from './smartssr.paths.js'; import { serializeFunction } from './smartssr.function.serialize.js'; export interface ISmartSSROptions { debug: boolean; } /** * */ export class SmartSSR { public options: ISmartSSROptions; constructor(optionsArg?: ISmartSSROptions) { this.options = { ...{ debug: false, }, ...optionsArg, }; } public async renderPage(urlArg: string) { const overallTimeMeasurement = new plugins.smarttime.HrtMeasurement(); overallTimeMeasurement.start(); const resultDeferred = plugins.smartpromise.defer(); const browser = new plugins.smartpuppeteer.IncognitoBrowser(); const renderTimeMeasurement = new plugins.smarttime.HrtMeasurement(); let renderedPageString: string; let screenshotBuffer: Buffer; await browser.start(); try { const context = await browser.getNewIncognitoContext(); const page = await context.newPage(); // lets protect against left open tabs plugins.smartdelay.delayFor(30000).then(async () => { try { await browser.stop(); } catch {} }); page.on('console', (msg) => { console.log(`${urlArg}: ${msg.text()}`); }); renderTimeMeasurement.start(); await page.goto(urlArg, { waitUntil: 'networkidle2', timeout: 30000, }); if (this.options.debug) { screenshotBuffer = (await page.screenshot({ encoding: 'binary', })) as Buffer; } await page.$eval('body', serializeFunction); const pageContent = await page.content(); renderedPageString = pageContent; resultDeferred.resolve(renderedPageString); renderTimeMeasurement.stop(); // lets clean up async await page.close(); await context.close(); } catch (e) { console.log(e); await browser.stop(); return; } await browser.stop(); overallTimeMeasurement.stop(); console.log( `Overall it took ${overallTimeMeasurement.milliSeconds} milliseconds to render ${urlArg}` ); console.log( `The rendering alone took ${renderTimeMeasurement.milliSeconds} milliseconds for ${urlArg}` ); // debug if (this.options.debug) { plugins.smartfile.memory.toFsSync( renderedPageString, plugins.path.join(paths.noGitDir, 'test.html') ); const fs = await import('fs'); fs.writeFileSync(plugins.path.join(paths.noGitDir, 'test.png'), screenshotBuffer); } return resultDeferred.promise; } }