UNPKG

@grafana/faro-web-sdk

Version:

Faro instrumentations, metas, transports for web.

123 lines 4.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.monitorHttpRequests = monitorHttpRequests; exports.__resetHttpRequestMonitorForTests = __resetHttpRequestMonitorForTests; const faro_core_1 = require("@grafana/faro-core"); const url_1 = require("../../../utils/url"); const const_1 = require("./const"); const apiTypeFetch = 'fetch'; const apiTypeXhr = 'xhr'; /** * Monitors if any http requests are in progress. */ let httpRequestObservable; let isInstrumented = false; let originalXhrOpen; let originalFetchFn; function monitorHttpRequests() { if (httpRequestObservable) { return httpRequestObservable; } httpRequestObservable = new faro_core_1.Observable(); function emitStartMessage(requestProps) { httpRequestObservable.notify({ type: const_1.MESSAGE_TYPE_HTTP_REQUEST_START, request: requestProps, }); } function emitEndMessage(requestProps) { httpRequestObservable.notify({ type: const_1.MESSAGE_TYPE_HTTP_REQUEST_END, request: requestProps, }); } if (!isInstrumented) { monitorFetch({ onRequestStart: emitStartMessage, onRequestEnd: emitEndMessage, }); monitorXhr({ onRequestStart: emitStartMessage, onRequestEnd: emitEndMessage, }); isInstrumented = true; } return httpRequestObservable; } function monitorXhr({ onRequestStart, onRequestEnd, }) { if (!originalXhrOpen) { originalXhrOpen = XMLHttpRequest.prototype.open; } XMLHttpRequest.prototype.open = function () { const url = arguments[1]; const isIgnoredUrl = (0, url_1.isUrlIgnored)(url); const method = arguments[0]; const requestId = (0, faro_core_1.genShortID)(); // request has started to load data. this.addEventListener('loadstart', function () { if (!isIgnoredUrl) { onRequestStart({ url, method, requestId, apiType: apiTypeXhr }); } }); // transaction completes successfully. this.addEventListener('load', function () { if (!isIgnoredUrl) { onRequestEnd({ url, method, requestId, apiType: apiTypeXhr }); } }); this.addEventListener('error', function () { if (!isIgnoredUrl) { onRequestEnd({ url, method, requestId, apiType: apiTypeXhr }); } }); this.addEventListener('abort', function () { if (!isIgnoredUrl) { onRequestEnd({ url, method, requestId, apiType: apiTypeXhr }); } }); originalXhrOpen.apply(this, arguments); }; } function monitorFetch({ onRequestEnd, onRequestStart, }) { if (!originalFetchFn) { originalFetchFn = window.fetch; } window.fetch = function () { var _a, _b; const url = (_a = (0, url_1.getUrlFromResource)(arguments[0])) !== null && _a !== void 0 ? _a : ''; const isIgnoredUrl = (0, url_1.isUrlIgnored)(url); const method = ((_b = arguments[1]) !== null && _b !== void 0 ? _b : {}).method; const requestId = (0, faro_core_1.genShortID)(); if (!isIgnoredUrl) { onRequestStart({ url, method, requestId, apiType: apiTypeFetch }); } return originalFetchFn .apply(this, arguments) .then((response) => { if (!isIgnoredUrl) { onRequestEnd({ url, method, requestId, apiType: apiTypeFetch }); } return response; }) .catch((error) => { if (!isIgnoredUrl) { onRequestEnd({ url, method, requestId, apiType: apiTypeFetch }); } throw error; }); }; } // Test-only utility to reset instrumentation and singleton between tests function __resetHttpRequestMonitorForTests() { if (originalXhrOpen) { XMLHttpRequest.prototype.open = originalXhrOpen; } if (originalFetchFn) { window.fetch = originalFetchFn; } httpRequestObservable = undefined; isInstrumented = false; originalXhrOpen = undefined; originalFetchFn = undefined; } //# sourceMappingURL=httpRequestMonitor.js.map