UNPKG

pagespeed-quest

Version:

A framework for efficient web front-end speed improvement

99 lines 9.84 kB
import { Proxy } from './proxy.js'; export class RecordingProxy extends Proxy { startedAt; transactions = []; async setup() { this.startedAt = new Date(); let requestNumber = 1; this.proxy.onRequest((ctx, onRequestComplete) => { const number = requestNumber++; // Skip websocket if (ctx.clientToProxyRequest.headers?.upgrade === 'websocket') { this.dependency.logger?.warn({ number }, `Request #${number} ${ctx.clientToProxyRequest.url} skipped (websocket)`); return; } // Throttling const filter = this.createThrottlingTransform(); if (filter) ctx.addResponseFilter(filter); const identifier = Proxy.contextRequest(ctx); const transaction = { startedAt: new Date(), ...identifier, contentChunks: [], }; this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} started`); ctx.onError((_, err, errKind) => { transaction.responseStartedAt = new Date(); transaction.err = err; transaction.errKind = errKind; this.dependency.logger?.warn({ number, identifier, err }, `Request #${number} ${transaction.url} failed: ${err.message}`); }); ctx.onResponse((_, onResponseComplete) => { transaction.responseStartedAt = new Date(); transaction.statusCode = ctx.serverToProxyResponse.statusCode; transaction.incomingHttpHeaders = ctx.serverToProxyResponse.headers; this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} responded`); onResponseComplete(); }); ctx.onResponseData((_, chunk, onResponseDataComplete) => { transaction.contentChunks.push(chunk); onResponseDataComplete(null, chunk); }); ctx.onResponseEnd((_, onResponseEndComplete) => { transaction.responseEndedAt = new Date(); this.transactions.push(transaction); this.dependency.logger?.debug({ number, identifier }, `Request #${number} ${transaction.url} completed`); onResponseEndComplete(); }); onRequestComplete(); }); } async saveInventory() { const transactions = []; for (const requestTransaction of this.transactions) { const transaction = { method: requestTransaction.method, url: requestTransaction.url, ttfbMs: 0, content: Buffer.concat(requestTransaction.contentChunks), }; // ttfb and duration if (requestTransaction.responseStartedAt) { transaction.ttfbMs = +requestTransaction.responseStartedAt - +requestTransaction.startedAt; if (requestTransaction.responseEndedAt) { transaction.durationMs = +requestTransaction.responseEndedAt - +requestTransaction.responseStartedAt; } } // error if (requestTransaction.err) { transaction.errorMessage = requestTransaction.err.message; } // status code if (requestTransaction.statusCode) { transaction.statusCode = requestTransaction.statusCode; } // headers if (requestTransaction.incomingHttpHeaders) { transaction.rawHeaders = {}; for (const [key, value] of Object.entries(requestTransaction.incomingHttpHeaders)) { transaction.rawHeaders[key.toLowerCase()] = value.toString(); } } transactions.push(transaction); } const resources = await this.inventoryRepository.saveTransactions(transactions); const inventory = { entryUrl: this.entryUrl, deviceType: this.deviceType, resources }; await this.inventoryRepository.saveInventory(inventory); } async shutdown() { await this.saveInventory(); } } export async function withRecordingProxy(options, dependency, cb) { const proxy = new RecordingProxy(options, dependency); await proxy.start(); await cb(proxy); await proxy.stop(); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkaW5nLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlY29yZGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsS0FBSyxFQUFpQyxNQUFNLFlBQVksQ0FBQTtBQW9CakUsTUFBTSxPQUFPLGNBQWUsU0FBUSxLQUFLO0lBQ3ZDLFNBQVMsQ0FBTztJQUNoQixZQUFZLEdBQTJCLEVBQUUsQ0FBQTtJQUV6QyxLQUFLLENBQUMsS0FBSztRQUNULElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQTtRQUUzQixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUE7UUFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsRUFBRTtZQUM5QyxNQUFNLE1BQU0sR0FBRyxhQUFhLEVBQUUsQ0FBQTtZQUU5QixpQkFBaUI7WUFDakIsSUFBSSxHQUFHLENBQUMsb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sS0FBSyxXQUFXLEVBQUU7Z0JBQzdELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FDMUIsRUFBRSxNQUFNLEVBQUUsRUFDVixZQUFZLE1BQU0sSUFBSSxHQUFHLENBQUMsb0JBQW9CLENBQUMsR0FBRyxzQkFBc0IsQ0FDekUsQ0FBQTtnQkFDRCxPQUFNO2FBQ1A7WUFFRCxhQUFhO1lBQ2IsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixFQUFFLENBQUE7WUFDL0MsSUFBSSxNQUFNO2dCQUFFLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUV6QyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQzVDLE1BQU0sV0FBVyxHQUF5QjtnQkFDeEMsU0FBUyxFQUFFLElBQUksSUFBSSxFQUFFO2dCQUNyQixHQUFHLFVBQVU7Z0JBQ2IsYUFBYSxF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