@grafana/faro-web-sdk
Version:
Faro instrumentations, metas, transports for web.
84 lines • 2.73 kB
JavaScript
import { isFunction, isString, Observable } from '@grafana/faro-core';
import { isUrlIgnored } from '../../utils/url';
import { MESSAGE_TYPE_HTTP_REQUEST_END, MESSAGE_TYPE_HTTP_REQUEST_START } from './const';
/**
* Monitors if any http requests are in progress.
*/
export function monitorHttpRequests() {
const observable = new Observable();
let pendingXhrRequests = 0;
let pendingFetchRequests = 0;
function emitStartMessage() {
observable.notify({ type: MESSAGE_TYPE_HTTP_REQUEST_START, pending: pendingXhrRequests + pendingFetchRequests });
}
function emitEndMessage() {
observable.notify({ type: MESSAGE_TYPE_HTTP_REQUEST_END, pending: pendingXhrRequests + pendingFetchRequests });
}
monitorFetch(() => {
pendingFetchRequests++;
emitStartMessage();
}, () => {
pendingFetchRequests--;
emitEndMessage();
});
monitorXhr(() => {
pendingXhrRequests++;
emitStartMessage();
}, () => {
pendingXhrRequests--;
emitEndMessage();
});
return observable;
}
function monitorXhr(onRequestStart, onRequestEnd) {
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function () {
const url = arguments[1];
const isIgnoredUrl = isUrlIgnored(url);
this.addEventListener('loadstart', () => {
if (!isIgnoredUrl) {
onRequestStart();
}
});
this.addEventListener('loadend', () => {
if (!isIgnoredUrl) {
onRequestEnd();
}
});
originalOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function () {
originalSend.apply(this, arguments);
};
}
function monitorFetch(onRequestsStart, onRequestEnd) {
const originalFetch = window.fetch;
window.fetch = function () {
const url = getUrlFromResource(arguments[0]);
const isIgnoredUrl = isUrlIgnored(url);
// fetch started
if (!isIgnoredUrl) {
onRequestsStart();
}
return originalFetch.apply(this, arguments).finally(() => {
// fetch ended
if (!isIgnoredUrl) {
onRequestEnd();
}
});
};
}
function getUrlFromResource(resource) {
if (isString(resource)) {
return resource;
}
else if (resource instanceof URL) {
return resource.href;
}
else if (isFunction(resource === null || resource === void 0 ? void 0 : resource.toString)) {
return resource.toString();
}
return undefined;
}
//# sourceMappingURL=httpRequestMonitor.js.map