UNPKG

@grafana/faro-web-sdk

Version:

Faro instrumentations, metas, transports for web.

125 lines 5.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UserActionController = void 0; // packages/web-sdk/src/instrumentations/userActions/userActionController.ts var faro_core_1 = require("@grafana/faro-core"); var domMutationMonitor_1 = require("../_internal/monitors/domMutationMonitor"); var httpRequestMonitor_1 = require("../_internal/monitors/httpRequestMonitor"); var performanceEntriesMonitor_1 = require("../_internal/monitors/performanceEntriesMonitor"); var util_1 = require("./util"); var defaultFollowUpActionTimeRange = 100; var defaultHaltTimeout = 10 * 1000; var UserActionController = /** @class */ (function () { function UserActionController(userAction) { this.userAction = userAction; this.http = (0, httpRequestMonitor_1.monitorHttpRequests)(); this.dom = (0, domMutationMonitor_1.monitorDomMutations)(); this.perf = (0, performanceEntriesMonitor_1.monitorPerformanceEntries)(); this.isValid = false; this.runningRequests = new Map(); } UserActionController.prototype.attach = function () { var _this = this; // Subscribe to monitors while action is active/halting this.allMonitorsSub = new faro_core_1.Observable() .merge(this.http, this.dom, this.perf) .takeWhile(function () { return [faro_core_1.UserActionState.Started, faro_core_1.UserActionState.Halted].includes(_this.userAction.getState()); }) .filter(function (msg) { // If the user action is in halt state, we only keep listening to ended http requests if (_this.userAction.getState() === faro_core_1.UserActionState.Halted && !((0, util_1.isRequestEndMessage)(msg) && _this.runningRequests.has(msg.request.requestId))) { return false; } return true; }) .subscribe(function (msg) { if ((0, util_1.isRequestStartMessage)(msg)) { // An action is on halt if it has pending items, like pending HTTP requests. // In this case we start a separate timeout to wait for the requests to finish // If in the halt state, we stop adding Faro signals to the action's buffer (see userActionLifecycleHandler.ts) // But we are still subscribed to _this.runningRequests.set(msg.request.requestId, msg.request); } if ((0, util_1.isRequestEndMessage)(msg)) { _this.runningRequests.delete(msg.request.requestId); } if (!(0, util_1.isRequestEndMessage)(msg)) { if (!_this.isValid) { _this.isValid = true; } _this.scheduleFollowUp(); } else if (_this.userAction.getState() === faro_core_1.UserActionState.Halted && _this.runningRequests.size === 0) { _this.endAction(); } }); // When UA ends or cancels, cleanup timers/subscriptions this.stateSub = this.userAction .filter(function (s) { return [faro_core_1.UserActionState.Ended, faro_core_1.UserActionState.Cancelled].includes(s); }) .first() .subscribe(function () { return _this.cleanup(); }); // initial follow-up window in case nothing else happens this.scheduleFollowUp(); }; UserActionController.prototype.scheduleFollowUp = function () { var _this = this; this.clearTimer(this.followUpTid); this.followUpTid = setTimeout(function () { // If action just started and there's pending work, go to halted if (_this.userAction.getState() === faro_core_1.UserActionState.Started && _this.runningRequests.size > 0) { _this.haltAction(); return; } // If we saw any relevant activity in the window, finish as ended if (_this.isValid) { _this.endAction(); return; } // Otherwise, no signals => cancel _this.cancelAction(); }, defaultFollowUpActionTimeRange); }; UserActionController.prototype.haltAction = function () { if (this.userAction.getState() !== faro_core_1.UserActionState.Started) { return; } this.userAction.halt(); this.startHaltTimeout(); }; UserActionController.prototype.startHaltTimeout = function () { var _this = this; this.clearTimer(this.haltTid); this.haltTid = (0, util_1.startTimeout)(this.haltTid, function () { // If still halted after timeout, end if (_this.userAction.getState() === faro_core_1.UserActionState.Halted) { _this.endAction(); } }, defaultHaltTimeout); }; UserActionController.prototype.endAction = function () { this.userAction.end(); this.cleanup(); }; UserActionController.prototype.cancelAction = function () { this.userAction.cancel(); this.cleanup(); }; UserActionController.prototype.cleanup = function () { var _a, _b; this.clearTimer(this.followUpTid); this.clearTimer(this.haltTid); (_a = this.allMonitorsSub) === null || _a === void 0 ? void 0 : _a.unsubscribe(); (_b = this.stateSub) === null || _b === void 0 ? void 0 : _b.unsubscribe(); this.allMonitorsSub = undefined; this.stateSub = undefined; this.runningRequests.clear(); }; UserActionController.prototype.clearTimer = function (id) { if (id) { clearTimeout(id); } }; return UserActionController; }()); exports.UserActionController = UserActionController; //# sourceMappingURL=userActionController.js.map