UNPKG

@grafana/faro-core

Version:
102 lines 4.55 kB
import { TransportItemType } from '../../transports'; import { dateNow, genShortID, monoNow, Observable, stringifyObjectValues } from '../../utils'; import { ItemBuffer } from '../ItemBuffer'; import {} from '../measurements/types'; import {} from '../types'; import { userActionEventName, UserActionImportance } from './const'; import { UserActionState } from './types'; export default class UserAction extends Observable { constructor({ name, parentId, trigger, transports, attributes, trackUserActionsExcludeItem, importance = UserActionImportance.Normal, pushEvent, }) { super(); this.name = name; this.attributes = attributes; this.id = genShortID(); this.trigger = trigger; this.parentId = parentId !== null && parentId !== void 0 ? parentId : this.id; this.trackUserActionsExcludeItem = trackUserActionsExcludeItem; this.importance = importance; this._pushEvent = pushEvent; this._itemBuffer = new ItemBuffer(); this._transports = transports; this._state = UserActionState.Started; this._start(); } addItem(item) { if (this._state === UserActionState.Started) { this._itemBuffer.addItem(item); return true; } return false; } _start() { this._state = UserActionState.Started; if (this._state === UserActionState.Started) { // `startTime` is wall-clock (Unix-epoch ms) so it can be used as the event's // `timestampOverwriteMs` and emitted as `userActionStartTime` for consumers that // correlate with other systems. `_startTimeMono` is the monotonic anchor used // for the duration calculation in `end()`. this.startTime = dateNow(); this._startTimeMono = monoNow(); } } halt() { if (this._state !== UserActionState.Started) { return; } this._state = UserActionState.Halted; this.notify(this._state); } cancel() { if (this._state === UserActionState.Started) { // Empty the buffer this._itemBuffer.flushBuffer((item) => { this._transports.execute(item); }); } this._state = UserActionState.Cancelled; this.notify(this._state); } end() { if (this._state === UserActionState.Cancelled) { return; } const endTime = dateNow(); // Compute duration from the monotonic clock so it is unaffected by wall-clock // adjustments during the action. Note: `endTime - startTime` (both wall-clock) may // disagree with `duration` if the system clock was adjusted between start and end; // `duration` is authoritative. const duration = monoNow() - this._startTimeMono; this._state = UserActionState.Ended; this._itemBuffer.flushBuffer((item) => { if (isExcludeFromUserAction(item, this.trackUserActionsExcludeItem)) { this._transports.execute(item); return; } const userActionItem = Object.assign(Object.assign({}, item), { payload: Object.assign(Object.assign({}, item.payload), { action: { parentId: this.id, name: this.name, } }) }); this._transports.execute(userActionItem); }); this._state = UserActionState.Ended; this.notify(this._state); this._pushEvent(userActionEventName, Object.assign({ userActionName: this.name, userActionStartTime: this.startTime.toString(), userActionEndTime: endTime.toString(), userActionDuration: duration.toString(), userActionTrigger: this.trigger, userActionImportance: this.importance }, stringifyObjectValues(this.attributes)), undefined, { timestampOverwriteMs: this.startTime, customPayloadTransformer: (payload) => { payload.action = { id: this.id, name: this.name, }; return payload; }, }); } getState() { return this._state; } } function isExcludeFromUserAction(item, trackUserActionsExcludeItem) { return ((trackUserActionsExcludeItem === null || trackUserActionsExcludeItem === void 0 ? void 0 : trackUserActionsExcludeItem(item)) || (item.type === TransportItemType.MEASUREMENT && item.payload.type === 'web-vitals')); } //# sourceMappingURL=userAction.js.map