UNPKG

webshot-factory

Version:

screenshots at scale based on headless chrome

135 lines 5.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); const puppeteer = require("puppeteer"); const Logger = require("log4js"); const P = require("bluebird"); let _logger = Logger.getLogger("shot-worker"); const DEBUG_PORT_OFFSET = 9201; class ShotWorker { constructor(id) { this.id = id; this.timeout = 60000; this.shotCallback = _.noop; this.isBusy = true; } static create(idx, config) { return __awaiter(this, void 0, void 0, function* () { let worker = new ShotWorker(idx); worker.config = config; yield worker.init(idx, config.callbackName, config.warmerUrl, config.width, config.height, config.timeout); return worker; }); } takeShot(url) { if (this.isBusy) { _logger.error('Worker is busy doing work'); return P.reject('Worker is already busy'); } let start = (new Date()).valueOf(); this.isBusy = true; _logger.debug(`screenshot url #${this.id}: ${url}`); return new P((resolve, reject) => __awaiter(this, void 0, void 0, function* () { this.shotCallback = (err, buffer) => __awaiter(this, void 0, void 0, function* () { if (err) { return reject(err); } resolve(buffer); }); this.page.goto(url, { waitUntil: 'networkidle2' }).then(() => __awaiter(this, void 0, void 0, function* () { if (!this.config.callbackName) { let buffer = yield this.page.screenshot({ fullPage: true }); this.shotCallback(null, buffer); } })).then(null, (err) => { this.shotCallback(err, null); }); })) .timeout(this.timeout) .finally(() => { _logger.debug(`Worker #${this.id}: Screenshot Complete.`); this.isBusy = false; }); } reload() { return this.page.reload(); } exit() { this.browser && this.browser.close(); } getStatus() { return { id: this.id, browser: this.browser, debugPort: this.debugPort, isBusy: this.isBusy }; } init(idx = 0, callbackName = '', warmerUrl = '', width = 800, height = 600, timeout = 60000, chromeExecutablePath = '') { return __awaiter(this, void 0, void 0, function* () { this.debugPort = DEBUG_PORT_OFFSET + idx; this.timeout = timeout; let start = (new Date()).valueOf(); let options = { ignoreHTTPSErrors: true, headless: true, args: [ '--ignore-certificate-errors', '--enable-precise-memory-info', `--remote-debugging-port=${this.debugPort}` ], userDataDir: '/tmp/chrome' }; if (chromeExecutablePath) { options.executablePath = chromeExecutablePath; } try { this.browser = yield puppeteer.launch(options); _logger.debug('puppeteer launched'); } catch (error) { _logger.error("error launching chrome from puppeteer", error); } this.page = yield this.browser.newPage(); this.page.on('console', (...args) => _logger.debug(`PAGE LOG Worker #${idx}:`, ...args)); this.page.on('response', r => _logger.debug(`Worker #${idx}: ${r.status} ${r.url}`)); this.page.setViewport({ width: width, height: height }); // Define a window.onCustomEvent function on the page. if (callbackName) { yield this.page.exposeFunction(callbackName, e => { _logger.debug('Callback called from browser with', e); return this.page.screenshot({ fullPage: true }).then((buffer) => { this.shotCallback(null, buffer); }, (err) => { this.shotCallback(err, null); }); }); } if (warmerUrl) { yield this.page.goto(warmerUrl, { waitUntil: 'networkidle2' }); } _logger.info(`Worker ${idx} ready`); this.creationTime = (new Date()).valueOf() - start; this.isBusy = false; }); } } exports.ShotWorker = ShotWorker; //# sourceMappingURL=shot-worker.js.map