UNPKG

posthog-js

Version:

Posthog-js allows you to automatically capture usage and send events to PostHog.

602 lines • 30.9 kB
"use strict"; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.V2TriggerGroupStrategy = exports.V1RecordingStrategy = void 0; exports.encodeSamplingDecision = encodeSamplingDecision; exports.decodeSamplingDecision = decodeSamplingDecision; var constants_1 = require("../../../constants"); var triggerMatching_1 = require("./triggerMatching"); var sampling_1 = require("../../sampling"); var core_1 = require("@posthog/core"); var logger_1 = require("@posthog/browser-common/utils/logger"); var property_utils_1 = require("@posthog/browser-common/utils/property-utils"); var logger = (0, logger_1.createLogger)('[SessionRecording]'); /** * Decisions are stored as `sessionId` (sampled in) or `'!' + sessionId` (sampled out), so another * session can never inherit them. Anything else (legacy `true`/`false`, another session's decision) * decodes to null and is re-decided — safe, since `sampleOnProperty` is deterministic per session id. */ var NOT_SAMPLED_PREFIX = '!'; function encodeSamplingDecision(sessionId, isSampled) { return isSampled ? sessionId : NOT_SAMPLED_PREFIX + sessionId; } function decodeSamplingDecision(storedValue, sessionId) { if (storedValue === sessionId) { return true; } if (storedValue === NOT_SAMPLED_PREFIX + sessionId) { return false; } return null; } /** * V1 Strategy: Legacy trigger matching with global URL/Event/Flag triggers */ var V1RecordingStrategy = /** @class */ (function () { function V1RecordingStrategy(_instance, _urlTriggerMatching, _eventTriggerMatching, _linkedFlagMatching, _reportStarted, _tryTakeFullSnapshot, _onTriggerActivated) { this._instance = _instance; this._urlTriggerMatching = _urlTriggerMatching; this._eventTriggerMatching = _eventTriggerMatching; this._linkedFlagMatching = _linkedFlagMatching; this._reportStarted = _reportStarted; this._tryTakeFullSnapshot = _tryTakeFullSnapshot; this._onTriggerActivated = _onTriggerActivated; this._sampleRate = null; this._recordingStatusFunction = triggerMatching_1.allMatchSessionRecordingStatus; } V1RecordingStrategy.prototype.onRemoteConfig = function (config) { var _a; var _this = this; this._sampleRate = (0, core_1.isNumber)(config.sampleRate) ? config.sampleRate : null; // Setup trigger matching strategy (AND vs OR) if (config.triggerMatchType === 'any') { this._triggerStatusMatcher = new triggerMatching_1.OrTriggerMatching([this._eventTriggerMatching, this._urlTriggerMatching]); this._recordingStatusFunction = triggerMatching_1.anyMatchSessionRecordingStatus; } else { // either the setting is "ALL" or we default to the most restrictive this._triggerStatusMatcher = new triggerMatching_1.AndTriggerMatching([this._eventTriggerMatching, this._urlTriggerMatching]); this._recordingStatusFunction = triggerMatching_1.allMatchSessionRecordingStatus; } this._instance.register_for_session((_a = {}, _a[constants_1.SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG] = config.triggerMatchType, _a)); this._urlTriggerMatching.onConfig(config); this._eventTriggerMatching.onConfig(config); this._linkedFlagMatching.onConfig(config, function (flag, variant) { _this._reportStarted('linked_flag_matched', { flag: flag, variant: variant }); _this._onTriggerActivated(); }); }; V1RecordingStrategy.prototype.getStatus = function (context) { return this._recordingStatusFunction({ receivedFlags: true, isRecordingEnabled: true, isSampled: context.isSampled, rrwebError: context.rrwebError, urlTriggerMatching: context.urlTriggerMatching, eventTriggerMatching: context.eventTriggerMatching, linkedFlagMatching: context.linkedFlagMatching, sessionId: context.sessionId, }); }; V1RecordingStrategy.prototype.getMinimumDuration = function (sessionId) { // V1: Minimum duration is global from config, doesn't need sessionId void sessionId; var config = this._instance.get_property('$session_recording_remote_config'); var duration = config === null || config === void 0 ? void 0 : config.minimumDurationMilliseconds; return (0, core_1.isNumber)(duration) ? duration : null; }; V1RecordingStrategy.prototype.checkUrlTriggers = function (sessionId, onPause, onResume, onActivate) { this._urlTriggerMatching.checkUrlTriggerConditions(onPause, onResume, onActivate, sessionId); }; V1RecordingStrategy.prototype.setupEventTriggerListeners = function (onEvent, sessionId, onActivate) { var _this = this; if (this._eventTriggerMatching._eventTriggers.length === 0 || !(0, core_1.isNullish)(this._removeEventTriggerCaptureHook)) { return undefined; } this._removeEventTriggerCaptureHook = onEvent(function (event) { try { _this._eventTriggerMatching.checkEventTriggerConditions(event.event, onActivate, sessionId); } catch (e) { logger.error('Could not activate event trigger', e); } }); return this._removeEventTriggerCaptureHook; }; V1RecordingStrategy.prototype.makeSamplingDecisions = function (sessionId) { var _a; var _b, _c, _d; var currentSampleRate = this._sampleRate; if (!(0, core_1.isNumber)(currentSampleRate)) { (_b = this._instance.persistence) === null || _b === void 0 ? void 0 : _b.unregister(constants_1.SESSION_RECORDING_IS_SAMPLED); (_c = this._instance.persistence) === null || _c === void 0 ? void 0 : _c.unregister(constants_1.SESSION_RECORDING_SAMPLE_RATE); return; } var storedValue = this._instance.get_property(constants_1.SESSION_RECORDING_IS_SAMPLED); var storedSampleRate = this._instance.get_property(constants_1.SESSION_RECORDING_SAMPLE_RATE); var storedIsSampled = decodeSamplingDecision(storedValue, sessionId); // Re-decide when the rate changed, or a legacy sampled-in decision predates rate storage. // An explicit override stores null as the rate, so only undefined means legacy missing-rate. var sampleRateChanged = (0, core_1.isNumber)(storedSampleRate) && storedSampleRate !== currentSampleRate; var sampledInWithoutStoredRate = (0, core_1.isUndefined)(storedSampleRate) && storedValue === sessionId; var makeDecision = sampleRateChanged || sampledInWithoutStoredRate || !(0, core_1.isBoolean)(storedIsSampled); var shouldSample = makeDecision ? (0, sampling_1.sampleOnProperty)(sessionId, currentSampleRate) : storedIsSampled; if (makeDecision) { if (shouldSample) { this._reportStarted('sampled'); } else { logger.warn("Sample rate (".concat(currentSampleRate, ") has determined that this sessionId (").concat(sessionId, ") will not be sent to the server.")); } } (_d = this._instance.persistence) === null || _d === void 0 ? void 0 : _d.register((_a = {}, _a[constants_1.SESSION_RECORDING_IS_SAMPLED] = encodeSamplingDecision(sessionId, shouldSample), _a[constants_1.SESSION_RECORDING_SAMPLE_RATE] = (0, core_1.isNull)(storedSampleRate) && storedValue === sessionId ? null : currentSampleRate, _a)); }; V1RecordingStrategy.prototype.ensureSamplingDecision = function (sessionId) { if (!(0, core_1.isNumber)(this._sampleRate)) { return; } var storedValue = this._instance.get_property(constants_1.SESSION_RECORDING_IS_SAMPLED); if (!(0, core_1.isBoolean)(decodeSamplingDecision(storedValue, sessionId))) { this.makeSamplingDecisions(sessionId); } }; V1RecordingStrategy.prototype.onFlushComplete = function () { // V1 doesn't use this optimization }; V1RecordingStrategy.prototype.clearConditionalRecordingPersistence = function () { var _a, _b, _c, _d, _e; (_a = this._instance.persistence) === null || _a === void 0 ? void 0 : _a.unregister(constants_1.SESSION_RECORDING_EVENT_TRIGGER_ACTIVATED_SESSION); (_b = this._instance.persistence) === null || _b === void 0 ? void 0 : _b.unregister(constants_1.SESSION_RECORDING_URL_TRIGGER_ACTIVATED_SESSION); (_c = this._instance.persistence) === null || _c === void 0 ? void 0 : _c.unregister(constants_1.SESSION_RECORDING_IS_SAMPLED); (_d = this._instance.persistence) === null || _d === void 0 ? void 0 : _d.unregister(constants_1.SESSION_RECORDING_SAMPLE_RATE); (_e = this._instance.persistence) === null || _e === void 0 ? void 0 : _e.unregister(constants_1.SESSION_RECORDING_PAST_MINIMUM_DURATION); }; V1RecordingStrategy.prototype.updateActiveTriggers = function (sessionId) { void sessionId; // V1 doesn't track active triggers in session properties }; V1RecordingStrategy.prototype.hasPendingTriggers = function (sessionId) { var _a; return ((_a = this._triggerStatusMatcher) === null || _a === void 0 ? void 0 : _a.triggerStatus(sessionId)) === triggerMatching_1.TRIGGER_PENDING; }; V1RecordingStrategy.prototype.getPendingTriggerConditions = function (sessionId) { var legs = [ { label: 'URL condition not matched', status: this._urlTriggerMatching.triggerStatusNoSideEffects(sessionId), }, { label: 'event condition not matched', status: this._eventTriggerMatching.triggerStatusNoSideEffects(sessionId), }, { label: 'linked flag condition not matched', status: this._linkedFlagMatching.triggerStatusNoSideEffects(), }, ]; return legs.filter(function (_a) { var status = _a.status; return status === triggerMatching_1.TRIGGER_PENDING; }).map(function (_a) { var label = _a.label; return label; }); }; V1RecordingStrategy.prototype.stop = function () { var _a; (_a = this._removeEventTriggerCaptureHook) === null || _a === void 0 ? void 0 : _a.call(this); this._removeEventTriggerCaptureHook = undefined; this._eventTriggerMatching.stop(); this._urlTriggerMatching.stop(); this._linkedFlagMatching.stop(); }; return V1RecordingStrategy; }()); exports.V1RecordingStrategy = V1RecordingStrategy; /** * V2 Strategy: Trigger groups with per-group sampling and union behavior */ var V2TriggerGroupStrategy = /** @class */ (function () { function V2TriggerGroupStrategy(_instance, _urlTriggerMatching, _reportStarted, _tryAddCustomEvent, _onTriggerActivated) { this._instance = _instance; this._urlTriggerMatching = _urlTriggerMatching; this._reportStarted = _reportStarted; this._tryAddCustomEvent = _tryAddCustomEvent; this._onTriggerActivated = _onTriggerActivated; this._triggerGroupMatchers = []; this._triggerGroupSamplingResults = new Map(); this._hasCompletedInitialFlush = false; } V2TriggerGroupStrategy.prototype.onRemoteConfig = function (config) { var _a; if (!config.triggerGroups || config.triggerGroups.length === 0) { logger.warn('[V2Strategy] No trigger groups configured'); return; } // Setup trigger group matchers this._setupTriggerGroups(config.triggerGroups); this._instance.register_for_session((_a = {}, _a[constants_1.SDK_DEBUG_REPLAY_REMOTE_TRIGGER_MATCHING_CONFIG] = 'v2_trigger_groups', _a[constants_1.SDK_DEBUG_REPLAY_TRIGGER_GROUPS_COUNT] = config.triggerGroups.length, _a)); // V2 needs URL blocklist (but not URL triggers) this._urlTriggerMatching.onConfig(config); }; V2TriggerGroupStrategy.prototype.getStatus = function (context) { return (0, triggerMatching_1.triggerGroupsMatchSessionRecordingStatus)({ receivedFlags: true, isRecordingEnabled: true, isSampled: context.isSampled, rrwebError: context.rrwebError, urlTriggerMatching: context.urlTriggerMatching, eventTriggerMatching: context.eventTriggerMatching, linkedFlagMatching: context.linkedFlagMatching, sessionId: context.sessionId, triggerGroupMatchers: this._triggerGroupMatchers, triggerGroupSamplingResults: this._triggerGroupSamplingResults, minimumDuration: this.getMinimumDuration(context.sessionId), }); }; V2TriggerGroupStrategy.prototype.getMinimumDuration = function (sessionId) { var e_1, _a; var lowestDuration = null; try { for (var _b = __values(this._triggerGroupMatchers), _c = _b.next(); !_c.done; _c = _b.next()) { var matcher = _c.value; var groupStatus = matcher.triggerStatus(sessionId); // Only consider activated groups - pending groups haven't triggered yet if (groupStatus === 'trigger_activated') { var groupDuration = matcher.group.minDurationMs; if ((0, core_1.isNumber)(groupDuration)) { if ((0, core_1.isNull)(lowestDuration) || groupDuration < lowestDuration) { lowestDuration = groupDuration; } } } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return lowestDuration; }; V2TriggerGroupStrategy.prototype.checkUrlTriggers = function (sessionId, onPause, onResume, onActivate) { var e_2, _a; var _this = this; // V2 doesn't use the global onActivate callback - each group activates itself void onActivate; // Check URL blocklist (global, not per-group) this._urlTriggerMatching.checkUrlBlocklist(onPause, onResume); var _loop_1 = function (matcher) { matcher.checkUrlTriggerConditions(onPause, onResume, function (triggerType) { // Check group-level property filters before activating if (!_this._checkGroupLevelProperties(matcher, undefined)) { return; } matcher.activateTrigger(triggerType, sessionId); _this.updateActiveTriggers(sessionId); _this._onTriggerActivated(triggerType); }, sessionId); }; try { // Check URL triggers for each group for (var _b = __values(this._triggerGroupMatchers), _c = _b.next(); !_c.done; _c = _b.next()) { var matcher = _c.value; _loop_1(matcher); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } }; V2TriggerGroupStrategy.prototype.setupEventTriggerListeners = function (onEvent, sessionId, onActivate) { var _this = this; // V2 doesn't use the global onActivate callback - each group activates itself void onActivate; this._removeEventTriggerCaptureHook = onEvent(function (event) { var e_3, _a; var _b; // Performance optimization: Stop checking triggers after initial buffer flush if (_this._hasCompletedInitialFlush) { logger.info('[SessionRecorder] Stopping trigger checks - initial buffer flushed'); (_b = _this._removeEventTriggerCaptureHook) === null || _b === void 0 ? void 0 : _b.call(_this); _this._removeEventTriggerCaptureHook = undefined; return; } try { var _loop_2 = function (matcher) { matcher.checkEventTriggerConditions(event.event, function (triggerType) { // Check group-level property filters if (!_this._checkGroupLevelProperties(matcher, event.properties)) { return; } // Check per-event property filters. // A group may contain multiple entries for the same event name with // different property filters — e.g. "purchase amount > 100" OR // "purchase by a VIP". Treat same-name entries as a disjunction: // activate if *any* matching clause's filters pass. An entry with no // properties is treated as an unconditional match (matching V1). var matchedTriggers = (matcher.group.conditions.events || []).filter(function (t) { return t.name === event.event; }); var personProperties = _this._instance.get_property(constants_1.STORED_PERSON_PROPERTIES_KEY); var anyMatched = matchedTriggers.some(function (t) { return !t.properties || t.properties.length === 0 || (0, property_utils_1.matchTriggerPropertyFilters)(t.properties, event.properties, personProperties); }); if (!anyMatched) { return; } matcher.activateTrigger(triggerType, sessionId); _this.updateActiveTriggers(sessionId); _this._onTriggerActivated(triggerType); }, sessionId); }; try { // V2: Each group activates its own trigger with per-group persistence for (var _c = __values(_this._triggerGroupMatchers), _d = _c.next(); !_d.done; _d = _c.next()) { var matcher = _d.value; _loop_2(matcher); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_3) throw e_3.error; } } } catch (e) { logger.error('Could not activate event trigger for trigger groups', e); } }); return this._removeEventTriggerCaptureHook; }; V2TriggerGroupStrategy.prototype.makeSamplingDecisions = function (sessionId) { var e_4, _a, _b; var _c; try { for (var _d = __values(this._triggerGroupMatchers), _e = _d.next(); !_e.done; _e = _d.next()) { var matcher = _e.value; var group = matcher.group; var groupId = group.id; var sampleRate = group.sampleRate; // Check if we have a stored decision for this group var storageKey = constants_1.SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX + groupId; var storedValue = this._instance.get_property(storageKey); // Parse stored decision: // - object = current format with session ID, sample rate, and decision // - sessionId string = legacy sampled-in decision for that session // - false = legacy sampled-out decision without session/rate context (re-decide) // - undefined/null = no decision yet var storedDecision = null; var sessionChanged = false; var sampleRateChanged = false; var sampledInWithoutStoredRate = false; if ((0, core_1.isObject)(storedValue)) { var storedSessionId = storedValue.sessionId; var storedSampleRate = storedValue.sampleRate; var storedSampled = storedValue.sampled; sessionChanged = typeof storedSessionId === 'string' && storedSessionId !== sessionId; sampleRateChanged = (0, core_1.isNumber)(storedSampleRate) && storedSampleRate !== sampleRate; storedDecision = storedSessionId === sessionId && (0, core_1.isNumber)(storedSampleRate) && storedSampleRate === sampleRate && (0, core_1.isBoolean)(storedSampled) ? storedSampled : null; } else { storedDecision = storedValue === sessionId ? true : null; sessionChanged = typeof storedValue === 'string' && storedValue !== sessionId; sampledInWithoutStoredRate = storedValue === sessionId; } // Make new decision only if: // 1. No stored decision exists (storedDecision is null/undefined), OR // 2. Session changed (stored sessionId doesn't match current), OR // 3. Sample rate changed since the stored decision was made var makeDecision = sessionChanged || sampleRateChanged || sampledInWithoutStoredRate || !(0, core_1.isBoolean)(storedDecision); var shouldSample = makeDecision ? (0, sampling_1.sampleOnProperty)(sessionId + groupId, sampleRate) : storedDecision; if (makeDecision) { this._tryAddCustomEvent('triggerGroupSamplingDecisionMade', { group_id: groupId, group_name: group.name, sampleRate: sampleRate, isSampled: shouldSample, }); } // Store the decision this._triggerGroupSamplingResults.set(groupId, shouldSample); (_c = this._instance.persistence) === null || _c === void 0 ? void 0 : _c.register((_b = {}, _b[storageKey] = { sessionId: sessionId, sampleRate: sampleRate, sampled: shouldSample, }, _b)); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_e && !_e.done && (_a = _d.return)) _a.call(_d); } finally { if (e_4) throw e_4.error; } } // After all sampling decisions, register which groups are actively recording this.updateActiveTriggers(sessionId); }; V2TriggerGroupStrategy.prototype.ensureSamplingDecision = function (sessionId) { // V2 sampling is per trigger group and safe by default — a missing group // decision reads as not sampled, so it can never leak an undecided flush void sessionId; }; V2TriggerGroupStrategy.prototype.onFlushComplete = function () { this._hasCompletedInitialFlush = true; }; V2TriggerGroupStrategy.prototype.clearConditionalRecordingPersistence = function () { var e_5, _a; var _b, _c, _d, _e, _f, _g; (_b = this._instance.persistence) === null || _b === void 0 ? void 0 : _b.unregister(constants_1.SESSION_RECORDING_IS_SAMPLED); (_c = this._instance.persistence) === null || _c === void 0 ? void 0 : _c.unregister(constants_1.SESSION_RECORDING_SAMPLE_RATE); (_d = this._instance.persistence) === null || _d === void 0 ? void 0 : _d.unregister(constants_1.SESSION_RECORDING_PAST_MINIMUM_DURATION); try { // V2: Clear per-group trigger keys for (var _h = __values(this._triggerGroupMatchers), _j = _h.next(); !_j.done; _j = _h.next()) { var matcher = _j.value; var groupId = matcher.group.id; (_e = this._instance.persistence) === null || _e === void 0 ? void 0 : _e.unregister(constants_1.SESSION_RECORDING_TRIGGER_V2_GROUP_EVENT_PREFIX + groupId); (_f = this._instance.persistence) === null || _f === void 0 ? void 0 : _f.unregister(constants_1.SESSION_RECORDING_TRIGGER_V2_GROUP_URL_PREFIX + groupId); (_g = this._instance.persistence) === null || _g === void 0 ? void 0 : _g.unregister(constants_1.SESSION_RECORDING_TRIGGER_V2_GROUP_SAMPLING_PREFIX + groupId); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (_j && !_j.done && (_a = _h.return)) _a.call(_h); } finally { if (e_5) throw e_5.error; } } }; V2TriggerGroupStrategy.prototype.updateActiveTriggers = function (sessionId) { var e_6, _a, _b; var recordingGroups = []; try { for (var _c = __values(this._triggerGroupMatchers), _d = _c.next(); !_d.done; _d = _c.next()) { var matcher = _d.value; var group = matcher.group; var groupId = group.id; var triggerStatus = matcher.triggerStatus(sessionId); var isMatched = triggerStatus === 'trigger_activated'; var isSampled = this._triggerGroupSamplingResults.get(groupId) === true; if (isMatched) { recordingGroups.push({ id: groupId, name: group.name, matched: true, sampled: isSampled, }); } } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_6) throw e_6.error; } } this._instance.register_for_session((_b = {}, _b[constants_1.SDK_DEBUG_REPLAY_MATCHED_RECORDING_TRIGGER_GROUPS] = recordingGroups, _b)); }; V2TriggerGroupStrategy.prototype.hasPendingTriggers = function (sessionId) { var e_7, _a; try { // V2: Check if any group has pending triggers for (var _b = __values(this._triggerGroupMatchers), _c = _b.next(); !_c.done; _c = _b.next()) { var matcher = _c.value; if (matcher.triggerStatus(sessionId) === triggerMatching_1.TRIGGER_PENDING) { return true; } } } catch (e_7_1) { e_7 = { error: e_7_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_7) throw e_7.error; } } return false; }; V2TriggerGroupStrategy.prototype.getPendingTriggerConditions = function (sessionId) { return this._triggerGroupMatchers.flatMap(function (matcher) { if (matcher.triggerStatusNoSideEffects(sessionId) !== triggerMatching_1.TRIGGER_PENDING) { return []; } return matcher .getPendingTriggerConditions(sessionId) .map(function (condition) { return "trigger group \"".concat(matcher.group.name, "\": ").concat(condition); }); }); }; V2TriggerGroupStrategy.prototype.stop = function () { var _a; (_a = this._removeEventTriggerCaptureHook) === null || _a === void 0 ? void 0 : _a.call(this); this._removeEventTriggerCaptureHook = undefined; this._triggerGroupMatchers.forEach(function (matcher) { return matcher.stop(); }); this._triggerGroupMatchers = []; this._triggerGroupSamplingResults.clear(); this._urlTriggerMatching.stop(); }; V2TriggerGroupStrategy.prototype._checkGroupLevelProperties = function (matcher, eventProperties) { var groupProperties = matcher.group.conditions.properties; if (!groupProperties || groupProperties.length === 0) { return true; } var personProperties = this._instance.get_property(constants_1.STORED_PERSON_PROPERTIES_KEY); return (0, property_utils_1.matchTriggerPropertyFilters)(groupProperties, eventProperties, personProperties); }; V2TriggerGroupStrategy.prototype._setupTriggerGroups = function (groups) { var e_8, _a; var _this = this; // Clean up existing matchers this._triggerGroupMatchers.forEach(function (matcher) { return matcher.stop(); }); this._triggerGroupMatchers = []; this._triggerGroupSamplingResults.clear(); var _loop_3 = function (group) { var matcher = new triggerMatching_1.TriggerGroupMatching(this_1._instance, group, function (flag, variant) { _this._reportStarted('linked_flag_matched', { flag: flag, variant: variant, group_id: group.id, group_name: group.name, }); _this._onTriggerActivated(); }); this_1._triggerGroupMatchers.push(matcher); }; var this_1 = this; try { // Create a matcher for each group for (var groups_1 = __values(groups), groups_1_1 = groups_1.next(); !groups_1_1.done; groups_1_1 = groups_1.next()) { var group = groups_1_1.value; _loop_3(group); } } catch (e_8_1) { e_8 = { error: e_8_1 }; } finally { try { if (groups_1_1 && !groups_1_1.done && (_a = groups_1.return)) _a.call(groups_1); } finally { if (e_8) throw e_8.error; } } }; return V2TriggerGroupStrategy; }()); exports.V2TriggerGroupStrategy = V2TriggerGroupStrategy; //# sourceMappingURL=recording-strategies.js.map