vwo-fme-node-sdk 1.50.0 → 1.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/VERSION.js +1 -1
  3. package/dist/client/vwo-fme-javascript-sdk.js +200 -55
  4. package/dist/client/vwo-fme-javascript-sdk.js.map +1 -1
  5. package/dist/client/vwo-fme-javascript-sdk.min.js +2 -2
  6. package/dist/client/vwo-fme-javascript-sdk.min.js.map +1 -1
  7. package/dist/esm/api/GetFlag.js +105 -2
  8. package/dist/esm/api/GetFlag.js.map +1 -1
  9. package/dist/esm/enums/EventEnum.js +1 -0
  10. package/dist/esm/enums/EventEnum.js.map +1 -1
  11. package/dist/esm/models/settings/SettingsModel.js +6 -0
  12. package/dist/esm/models/settings/SettingsModel.js.map +1 -1
  13. package/dist/esm/utils/NetworkUtil.js +30 -0
  14. package/dist/esm/utils/NetworkUtil.js.map +1 -1
  15. package/dist/package.json +1 -1
  16. package/dist/server/vwo-fme-node-sdk.js +203 -55
  17. package/dist/server/vwo-fme-node-sdk.js.map +1 -1
  18. package/dist/server/vwo-fme-node-sdk.min.js +2 -2
  19. package/dist/server/vwo-fme-node-sdk.min.js.map +1 -1
  20. package/dist/server-unpacked/api/GetFlag.js +160 -53
  21. package/dist/server-unpacked/api/GetFlag.js.map +1 -1
  22. package/dist/server-unpacked/enums/EventEnum.js +1 -0
  23. package/dist/server-unpacked/enums/EventEnum.js.map +1 -1
  24. package/dist/server-unpacked/models/settings/SettingsModel.js +6 -0
  25. package/dist/server-unpacked/models/settings/SettingsModel.js.map +1 -1
  26. package/dist/server-unpacked/utils/NetworkUtil.js +31 -0
  27. package/dist/server-unpacked/utils/NetworkUtil.js.map +1 -1
  28. package/dist/types/enums/EventEnum.d.ts +1 -0
  29. package/dist/types/models/settings/SettingsModel.d.ts +2 -0
  30. package/dist/types/utils/NetworkUtil.d.ts +17 -0
  31. package/lib/api/GetFlag.ts +128 -2
  32. package/lib/enums/EventEnum.ts +1 -0
  33. package/lib/models/settings/SettingsModel.ts +9 -0
  34. package/lib/utils/NetworkUtil.ts +45 -0
  35. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.55.0] - 2026-06-09
9
+
10
+ ### Added
11
+
12
+ - Added user tracking support: sends a `vwo_feTrackUsage` event when user tracking is enabled for the account and no variation-shown impression was dispatched for the evaluation.
13
+
8
14
  ## [1.50.0] - 2026-05-29
9
15
 
10
16
  This release introduces **Wingify** as the primary SDK branding and a new npm package namespace, while keeping existing **VWO** integrations fully supported on `vwo-fme-node-sdk`.
package/dist/VERSION.js CHANGED
@@ -1 +1 @@
1
- module.exports = { version: "1.50.0" };
1
+ module.exports = { version: "1.55.0" };
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * vwo-fme-javascript-sdk - v1.50.0
2
+ * vwo-fme-javascript-sdk - v1.55.0
3
3
  * URL - https://github.com/wingify/vwo-fme-javascript-sdk
4
4
  *
5
5
  * Copyright 2024-2026 Wingify Software Pvt. Ltd.
@@ -46,7 +46,7 @@ return /******/ (() => { // webpackBootstrap
46
46
  /***/ ((module) => {
47
47
 
48
48
  module.exports = {
49
- version: "1.50.0"
49
+ version: "1.55.0"
50
50
  };
51
51
 
52
52
  /***/ }),
@@ -1729,10 +1729,10 @@ var FlagApi = /** @class */ (function () {
1729
1729
  }
1730
1730
  FlagApi.get = function (featureKey, context, serviceContainer) {
1731
1731
  return __awaiter(this, void 0, void 0, function () {
1732
- var isEnabled, rolloutVariationToReturn, experimentVariationToReturn, shouldCheckForExperimentsRules, passedRulesInformation, deferredObject, evaluatedFeatureMap, notInHoldoutIds, batchPayload, isSettingsDevModeEnabled, isUserDevModeEnabled, isDevModeForUser, feature, decision, debugEventProps, storageService, storedData, storedIsInHoldoutId, storedNotInHoldoutId, applicableHoldouts, _i, applicableHoldouts_1, holdout, _a, matchedHoldouts, notMatchedHoldouts, holdoutPayloads, updatedHoldoutIds, updatedNotInHoldoutIds, _b, holdoutPayloads_1, payload, _c, holdoutPayloads_2, payload, variation, variation, updatedNotInHoldoutIds, featureInfo, _d, matchedHoldouts, notMatchedHoldouts, holdoutPayloads, qualifiedHoldoutNames, _e, holdoutPayloads_3, payload, _f, holdoutPayloads_4, payload, _g, holdoutPayloads_5, payload, _h, holdoutPayloads_6, payload, rollOutRules, rolloutRulesToEvaluate, _j, rollOutRules_1, rule, _k, preSegmentationResult, updatedDecision, payload, passedRolloutCampaign, variation, payload, experimentRulesToEvaluate, experimentRules, megGroupWinnerCampaigns, _l, experimentRules_1, rule, _m, preSegmentationResult, whitelistedObject, updatedDecision, payload, campaign, variation, payload, payload;
1733
- var _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
1734
- return __generator(this, function (_0) {
1735
- switch (_0.label) {
1732
+ var isEnabled, rolloutVariationToReturn, experimentVariationToReturn, shouldCheckForExperimentsRules, passedRulesInformation, deferredObject, evaluatedFeatureMap, notInHoldoutIds, batchPayload, isSettingsDevModeEnabled, isUserDevModeEnabled, isDevModeForUser, isTrackingUsageEnabled, isVariationShownFired, feature, decision, debugEventProps, storageService, storedData, storedIsInHoldoutId, storedNotInHoldoutId, applicableHoldouts, _i, applicableHoldouts_1, holdout, _a, matchedHoldouts, notMatchedHoldouts, holdoutPayloads, updatedHoldoutIds, updatedNotInHoldoutIds, _b, holdoutPayloads_1, payload, _c, holdoutPayloads_2, payload, variation, variation, updatedNotInHoldoutIds, featureInfo, _d, matchedHoldouts, notMatchedHoldouts, holdoutPayloads, qualifiedHoldoutNames, _e, holdoutPayloads_3, payload, _f, holdoutPayloads_4, payload, _g, holdoutPayloads_5, payload, _h, holdoutPayloads_6, payload, rollOutRules, rolloutRulesToEvaluate, _j, rollOutRules_1, rule, _k, preSegmentationResult, updatedDecision, payload, passedRolloutCampaign, variation, payload, experimentRulesToEvaluate, experimentRules, megGroupWinnerCampaigns, _l, experimentRules_1, rule, _m, preSegmentationResult, whitelistedObject, updatedDecision, payload, campaign, variation, payload, payload;
1733
+ var _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1;
1734
+ return __generator(this, function (_2) {
1735
+ switch (_2.label) {
1736
1736
  case 0:
1737
1737
  isEnabled = false;
1738
1738
  rolloutVariationToReturn = null;
@@ -1746,6 +1746,8 @@ var FlagApi = /** @class */ (function () {
1746
1746
  isSettingsDevModeEnabled = ((_p = (_o = serviceContainer.getSettings()) === null || _o === void 0 ? void 0 : _o.getDevMode) === null || _p === void 0 ? void 0 : _p.call(_o)) === true;
1747
1747
  isUserDevModeEnabled = ((_q = context === null || context === void 0 ? void 0 : context.getIsDevMode) === null || _q === void 0 ? void 0 : _q.call(context)) === true;
1748
1748
  isDevModeForUser = isSettingsDevModeEnabled && isUserDevModeEnabled;
1749
+ isTrackingUsageEnabled = ((_s = (_r = serviceContainer.getSettings()) === null || _r === void 0 ? void 0 : _r.getIsTrackingUsageEnabled) === null || _s === void 0 ? void 0 : _s.call(_r)) === true;
1750
+ isVariationShownFired = false;
1749
1751
  feature = (0, FunctionUtil_1.getFeatureFromKey)(serviceContainer.getSettings(), featureKey);
1750
1752
  decision = {
1751
1753
  featureName: feature === null || feature === void 0 ? void 0 : feature.getName(),
@@ -1767,14 +1769,14 @@ var FlagApi = /** @class */ (function () {
1767
1769
  storageService = new StorageService_1.StorageService(serviceContainer);
1768
1770
  return [4 /*yield*/, new StorageDecorator_1.StorageDecorator().getFeatureFromStorage(featureKey, context, storageService, serviceContainer)];
1769
1771
  case 1:
1770
- storedData = _0.sent();
1771
- storedIsInHoldoutId = (_r = storedData === null || storedData === void 0 ? void 0 : storedData.isInHoldoutId) !== null && _r !== void 0 ? _r : storedData === null || storedData === void 0 ? void 0 : storedData.holdoutGroupId;
1772
- storedNotInHoldoutId = (_s = storedData === null || storedData === void 0 ? void 0 : storedData.notInHoldoutId) !== null && _s !== void 0 ? _s : [];
1772
+ storedData = _2.sent();
1773
+ storedIsInHoldoutId = (_t = storedData === null || storedData === void 0 ? void 0 : storedData.isInHoldoutId) !== null && _t !== void 0 ? _t : storedData === null || storedData === void 0 ? void 0 : storedData.holdoutGroupId;
1774
+ storedNotInHoldoutId = (_u = storedData === null || storedData === void 0 ? void 0 : storedData.notInHoldoutId) !== null && _u !== void 0 ? _u : [];
1773
1775
  if (!(storedIsInHoldoutId && ((0, DataTypeUtil_1.isArray)(storedIsInHoldoutId) ? storedIsInHoldoutId.length > 0 : true))) return [3 /*break*/, 10];
1774
1776
  applicableHoldouts = (0, HoldoutUtil_1.getApplicableHoldouts)(serviceContainer.getSettings(), feature.getId());
1775
1777
  if (!(applicableHoldouts.length > 0)) return [3 /*break*/, 10];
1776
1778
  _i = 0, applicableHoldouts_1 = applicableHoldouts;
1777
- _0.label = 2;
1779
+ _2.label = 2;
1778
1780
  case 2:
1779
1781
  if (!(_i < applicableHoldouts_1.length)) return [3 /*break*/, 10];
1780
1782
  holdout = applicableHoldouts_1[_i];
@@ -1786,7 +1788,7 @@ var FlagApi = /** @class */ (function () {
1786
1788
  }));
1787
1789
  return [4 /*yield*/, (0, HoldoutUtil_1.getMatchedHoldouts)(serviceContainer, feature, context, storedData)];
1788
1790
  case 3:
1789
- _a = _0.sent(), matchedHoldouts = _a.matchedHoldouts, notMatchedHoldouts = _a.notMatchedHoldouts, holdoutPayloads = _a.holdoutPayloads;
1791
+ _a = _2.sent(), matchedHoldouts = _a.matchedHoldouts, notMatchedHoldouts = _a.notMatchedHoldouts, holdoutPayloads = _a.holdoutPayloads;
1790
1792
  updatedHoldoutIds = __spreadArray(__spreadArray([], storedIsInHoldoutId, true), matchedHoldouts.map(function (holdout) { return holdout.getId(); }), true);
1791
1793
  updatedNotInHoldoutIds = __spreadArray(__spreadArray([], storedNotInHoldoutId, true), notMatchedHoldouts.map(function (holdout) { return holdout.getId(); }), true);
1792
1794
  // store the updated holdout ids in storage and push the updated not in holdout ids to the notInHoldoutIds array
@@ -1814,12 +1816,16 @@ var FlagApi = /** @class */ (function () {
1814
1816
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 7];
1815
1817
  return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, holdoutPayloads)];
1816
1818
  case 6:
1817
- _0.sent();
1819
+ _2.sent();
1818
1820
  return [3 /*break*/, 8];
1819
1821
  case 7:
1820
1822
  (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, holdoutPayloads);
1821
- _0.label = 8;
1823
+ _2.label = 8;
1822
1824
  case 8:
1825
+ // Decision served from holdout storage cache.
1826
+ // The cached holdout variationShown is NOT re-fired, so server has no usage tracking signal.
1827
+ // Send usage tracking call before returning.
1828
+ sendTrackingUsage(serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey); // fire-and-forget
1823
1829
  deferredObject.resolve(new Flag(false, context.getSessionId(), context.getUuid(), new VariationModel_1.VariationModel()));
1824
1830
  return [2 /*return*/, deferredObject.promise];
1825
1831
  case 9:
@@ -1842,7 +1848,11 @@ var FlagApi = /** @class */ (function () {
1842
1848
  return [4 /*yield*/, (0, HoldoutUtil_1.sendNetworkCallsForNotInHoldouts)(serviceContainer, feature, context, decision, storedData, storageService)];
1843
1849
  case 11:
1844
1850
  // network calls for holdouts that are newly added in settings and are not present in storage
1845
- _0.sent();
1851
+ _2.sent();
1852
+ // Experiment decision served from storage cache.
1853
+ // variationShown is NOT re-fired for cached decisions, so server has no usage tracking signal.
1854
+ // Send usage tracking call before returning.
1855
+ sendTrackingUsage(serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey); // fire-and-forget
1846
1856
  deferredObject.resolve(new Flag(true, context.getSessionId(), context.getUuid(), variation));
1847
1857
  return [2 /*return*/, deferredObject.promise];
1848
1858
  case 12: return [3 /*break*/, 15];
@@ -1862,9 +1872,12 @@ var FlagApi = /** @class */ (function () {
1862
1872
  }));
1863
1873
  return [4 /*yield*/, (0, HoldoutUtil_1.sendNetworkCallsForNotInHoldouts)(serviceContainer, feature, context, decision, storedData, storageService)];
1864
1874
  case 14:
1865
- updatedNotInHoldoutIds = _0.sent();
1875
+ updatedNotInHoldoutIds = _2.sent();
1866
1876
  // push the updated not in holdout ids to the notInHoldoutIds array
1867
1877
  notInHoldoutIds.push.apply(notInHoldoutIds, updatedNotInHoldoutIds);
1878
+ // Rollout decision served from storage cache.
1879
+ // variationShown is NOT re-fired for cached rollout decisions.
1880
+ // Usage tracking call will be dispatched at the end if no other experiment rule matches.
1868
1881
  isEnabled = true;
1869
1882
  shouldCheckForExperimentsRules = true;
1870
1883
  rolloutVariationToReturn = variation;
@@ -1875,22 +1888,25 @@ var FlagApi = /** @class */ (function () {
1875
1888
  };
1876
1889
  evaluatedFeatureMap.set(featureKey, featureInfo);
1877
1890
  Object.assign(passedRulesInformation, featureInfo);
1878
- _0.label = 15;
1891
+ _2.label = 15;
1879
1892
  case 15:
1880
1893
  if (!(0, DataTypeUtil_1.isObject)(feature) || feature === undefined) {
1881
1894
  serviceContainer.getLogManager().errorLog('FEATURE_NOT_FOUND', {
1882
1895
  featureKey: featureKey,
1883
1896
  }, debugEventProps);
1897
+ // Feature key not found in settings (flag is OFF or not yet created).
1898
+ // No variationShown possible. Send usage tracking call before rejecting.
1899
+ sendTrackingUsage(serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey); // fire-and-forget
1884
1900
  deferredObject.reject({});
1885
1901
  return [2 /*return*/, deferredObject.promise];
1886
1902
  }
1887
1903
  return [4 /*yield*/, serviceContainer.getSegmentationManager().setContextualData(serviceContainer, feature, context)];
1888
1904
  case 16:
1889
- _0.sent();
1905
+ _2.sent();
1890
1906
  if (!!isEnabled) return [3 /*break*/, 24];
1891
1907
  return [4 /*yield*/, (0, HoldoutUtil_1.getMatchedHoldouts)(serviceContainer, feature, context, storedData)];
1892
1908
  case 17:
1893
- _d = _0.sent(), matchedHoldouts = _d.matchedHoldouts, notMatchedHoldouts = _d.notMatchedHoldouts, holdoutPayloads = _d.holdoutPayloads;
1909
+ _d = _2.sent(), matchedHoldouts = _d.matchedHoldouts, notMatchedHoldouts = _d.notMatchedHoldouts, holdoutPayloads = _d.holdoutPayloads;
1894
1910
  decision.isPartOfHoldout = matchedHoldouts !== null && matchedHoldouts.length > 0;
1895
1911
  if ((matchedHoldouts !== null && matchedHoldouts.length > 0) ||
1896
1912
  (notMatchedHoldouts !== null && notMatchedHoldouts.length > 0)) {
@@ -1931,12 +1947,14 @@ var FlagApi = /** @class */ (function () {
1931
1947
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 21];
1932
1948
  return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, holdoutPayloads)];
1933
1949
  case 20:
1934
- _0.sent();
1950
+ _2.sent();
1935
1951
  return [3 /*break*/, 22];
1936
1952
  case 21:
1937
1953
  (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, holdoutPayloads);
1938
- _0.label = 22;
1954
+ _2.label = 22;
1939
1955
  case 22:
1956
+ // Holdout variationShown(variation=1) was fired above — server handles usage tracking.
1957
+ // No explicit usage tracking call needed here.
1940
1958
  deferredObject.resolve(new Flag(false, context.getSessionId(), context.getUuid(), new VariationModel_1.VariationModel()));
1941
1959
  return [2 /*return*/, deferredObject.promise];
1942
1960
  case 23:
@@ -1961,51 +1979,60 @@ var FlagApi = /** @class */ (function () {
1961
1979
  else {
1962
1980
  batchPayload.push.apply(batchPayload, holdoutPayloads);
1963
1981
  }
1982
+ // Usage tracking optimization: holdout variationShown(variation=2) was dispatched above.
1983
+ // server will handle usage tracking from that event. Mark flag so Point 4 skips our usage tracking call
1984
+ // to avoid an unnecessary duplicate network round trip.
1985
+ if (holdoutPayloads.length > 0) {
1986
+ isVariationShownFired = true;
1987
+ }
1964
1988
  }
1965
- _0.label = 24;
1989
+ _2.label = 24;
1966
1990
  case 24:
1967
1991
  rollOutRules = (0, FunctionUtil_1.getSpecificRulesBasedOnType)(feature, CampaignTypeEnum_1.CampaignTypeEnum.ROLLOUT);
1968
1992
  if (!(rollOutRules.length > 0 && !isEnabled)) return [3 /*break*/, 40];
1969
1993
  rolloutRulesToEvaluate = [];
1970
1994
  _j = 0, rollOutRules_1 = rollOutRules;
1971
- _0.label = 25;
1995
+ _2.label = 25;
1972
1996
  case 25:
1973
1997
  if (!(_j < rollOutRules_1.length)) return [3 /*break*/, 34];
1974
1998
  rule = rollOutRules_1[_j];
1975
1999
  return [4 /*yield*/, (0, RuleEvaluationUtil_1.evaluateRule)(serviceContainer, feature, rule, context, evaluatedFeatureMap, null, storageService, decision)];
1976
2000
  case 26:
1977
- _k = _0.sent(), preSegmentationResult = _k.preSegmentationResult, updatedDecision = _k.updatedDecision, payload = _k.payload;
2001
+ _k = _2.sent(), preSegmentationResult = _k.preSegmentationResult, updatedDecision = _k.updatedDecision, payload = _k.payload;
1978
2002
  Object.assign(decision, updatedDecision);
2003
+ if (payload) {
2004
+ isVariationShownFired = true;
2005
+ }
1979
2006
  if (!preSegmentationResult) return [3 /*break*/, 32];
1980
2007
  // if pre segment passed, then break the loop and check the traffic allocation
1981
2008
  rolloutRulesToEvaluate.push(rule);
1982
2009
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 30];
1983
2010
  if (!(serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null)) return [3 /*break*/, 28];
1984
- return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, rule.getId(), (_t = rule.getVariations()[0]) === null || _t === void 0 ? void 0 : _t.getId(), context, featureKey, payload)];
2011
+ return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, rule.getId(), (_v = rule.getVariations()[0]) === null || _v === void 0 ? void 0 : _v.getId(), context, featureKey, payload)];
1985
2012
  case 27:
1986
- _0.sent();
2013
+ _2.sent();
1987
2014
  return [3 /*break*/, 29];
1988
2015
  case 28:
1989
2016
  if (payload != null) {
1990
2017
  batchPayload.push(payload);
1991
2018
  }
1992
- _0.label = 29;
2019
+ _2.label = 29;
1993
2020
  case 29: return [3 /*break*/, 31];
1994
2021
  case 30:
1995
2022
  if (serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null) {
1996
- (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, rule.getId(), (_u = rule.getVariations()[0]) === null || _u === void 0 ? void 0 : _u.getId(), context, featureKey, payload);
2023
+ (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, rule.getId(), (_w = rule.getVariations()[0]) === null || _w === void 0 ? void 0 : _w.getId(), context, featureKey, payload);
1997
2024
  }
1998
2025
  else {
1999
2026
  if (payload != null) {
2000
2027
  batchPayload.push(payload);
2001
2028
  }
2002
2029
  }
2003
- _0.label = 31;
2030
+ _2.label = 31;
2004
2031
  case 31:
2005
2032
  evaluatedFeatureMap.set(featureKey, {
2006
2033
  rolloutId: rule.getId(),
2007
2034
  rolloutKey: rule.getKey(),
2008
- rolloutVariationId: (_v = rule.getVariations()[0]) === null || _v === void 0 ? void 0 : _v.getId(),
2035
+ rolloutVariationId: (_x = rule.getVariations()[0]) === null || _x === void 0 ? void 0 : _x.getId(),
2009
2036
  });
2010
2037
  return [3 /*break*/, 34];
2011
2038
  case 32: return [3 /*break*/, 33]; // if rule does not satisfy, then check for other ROLLOUT rules
@@ -2024,17 +2051,20 @@ var FlagApi = /** @class */ (function () {
2024
2051
  _updateIntegrationsDecisionObject(passedRolloutCampaign, variation, passedRulesInformation, decision);
2025
2052
  if (!!isDevModeForUser) return [3 /*break*/, 39];
2026
2053
  payload = (0, NetworkUtil_1.getTrackUserPayloadData)(serviceContainer, EventEnum_1.EventEnum.VARIATION_SHOWN, passedRolloutCampaign.getId(), variation.getId(), context);
2054
+ if (payload) {
2055
+ isVariationShownFired = true;
2056
+ }
2027
2057
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 38];
2028
2058
  if (!(serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null)) return [3 /*break*/, 36];
2029
2059
  return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, passedRolloutCampaign.getId(), variation.getId(), context, featureKey, payload)];
2030
2060
  case 35:
2031
- _0.sent();
2061
+ _2.sent();
2032
2062
  return [3 /*break*/, 37];
2033
2063
  case 36:
2034
2064
  if (payload != null) {
2035
2065
  batchPayload.push(payload);
2036
2066
  }
2037
- _0.label = 37;
2067
+ _2.label = 37;
2038
2068
  case 37: return [3 /*break*/, 39];
2039
2069
  case 38:
2040
2070
  if (serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null) {
@@ -2045,7 +2075,7 @@ var FlagApi = /** @class */ (function () {
2045
2075
  batchPayload.push(payload);
2046
2076
  }
2047
2077
  }
2048
- _0.label = 39;
2078
+ _2.label = 39;
2049
2079
  case 39: return [3 /*break*/, 41];
2050
2080
  case 40:
2051
2081
  if (rollOutRules.length === 0) {
@@ -2054,21 +2084,24 @@ var FlagApi = /** @class */ (function () {
2054
2084
  .debug((0, LogMessageUtil_1.buildMessage)(log_messages_1.DebugLogMessagesEnum.EXPERIMENTS_EVALUATION_WHEN_NO_ROLLOUT_PRESENT));
2055
2085
  shouldCheckForExperimentsRules = true;
2056
2086
  }
2057
- _0.label = 41;
2087
+ _2.label = 41;
2058
2088
  case 41:
2059
2089
  if (!shouldCheckForExperimentsRules) return [3 /*break*/, 57];
2060
2090
  experimentRulesToEvaluate = [];
2061
2091
  experimentRules = (0, FunctionUtil_1.getAllExperimentRules)(feature);
2062
2092
  megGroupWinnerCampaigns = new Map();
2063
2093
  _l = 0, experimentRules_1 = experimentRules;
2064
- _0.label = 42;
2094
+ _2.label = 42;
2065
2095
  case 42:
2066
2096
  if (!(_l < experimentRules_1.length)) return [3 /*break*/, 52];
2067
2097
  rule = experimentRules_1[_l];
2068
2098
  return [4 /*yield*/, (0, RuleEvaluationUtil_1.evaluateRule)(serviceContainer, feature, rule, context, evaluatedFeatureMap, megGroupWinnerCampaigns, storageService, decision)];
2069
2099
  case 43:
2070
- _m = _0.sent(), preSegmentationResult = _m.preSegmentationResult, whitelistedObject = _m.whitelistedObject, updatedDecision = _m.updatedDecision, payload = _m.payload;
2100
+ _m = _2.sent(), preSegmentationResult = _m.preSegmentationResult, whitelistedObject = _m.whitelistedObject, updatedDecision = _m.updatedDecision, payload = _m.payload;
2071
2101
  Object.assign(decision, updatedDecision);
2102
+ if (payload) {
2103
+ isVariationShownFired = true;
2104
+ }
2072
2105
  if (!preSegmentationResult) return [3 /*break*/, 50];
2073
2106
  if (!(whitelistedObject === null)) return [3 /*break*/, 44];
2074
2107
  // whitelistedObject will be null if pre segment passed but whitelisting failed
@@ -2088,13 +2121,13 @@ var FlagApi = /** @class */ (function () {
2088
2121
  if (!(serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null)) return [3 /*break*/, 46];
2089
2122
  return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, rule.getId(), whitelistedObject.variationId, context, featureKey, payload)];
2090
2123
  case 45:
2091
- _0.sent();
2124
+ _2.sent();
2092
2125
  return [3 /*break*/, 47];
2093
2126
  case 46:
2094
2127
  if (payload != null) {
2095
2128
  batchPayload.push(payload);
2096
2129
  }
2097
- _0.label = 47;
2130
+ _2.label = 47;
2098
2131
  case 47: return [3 /*break*/, 49];
2099
2132
  case 48:
2100
2133
  if (serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null) {
@@ -2105,7 +2138,7 @@ var FlagApi = /** @class */ (function () {
2105
2138
  batchPayload.push(payload);
2106
2139
  }
2107
2140
  }
2108
- _0.label = 49;
2141
+ _2.label = 49;
2109
2142
  case 49: return [3 /*break*/, 52];
2110
2143
  case 50: return [3 /*break*/, 51];
2111
2144
  case 51:
@@ -2122,17 +2155,20 @@ var FlagApi = /** @class */ (function () {
2122
2155
  _updateIntegrationsDecisionObject(campaign, variation, passedRulesInformation, decision);
2123
2156
  if (!!isDevModeForUser) return [3 /*break*/, 57];
2124
2157
  payload = (0, NetworkUtil_1.getTrackUserPayloadData)(serviceContainer, EventEnum_1.EventEnum.VARIATION_SHOWN, campaign.getId(), variation.getId(), context);
2158
+ if (payload) {
2159
+ isVariationShownFired = true;
2160
+ }
2125
2161
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 56];
2126
2162
  if (!(serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null)) return [3 /*break*/, 54];
2127
2163
  return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, campaign.getId(), variation.getId(), context, featureKey, payload)];
2128
2164
  case 53:
2129
- _0.sent();
2165
+ _2.sent();
2130
2166
  return [3 /*break*/, 55];
2131
2167
  case 54:
2132
2168
  if (payload != null) {
2133
2169
  batchPayload.push(payload);
2134
2170
  }
2135
- _0.label = 55;
2171
+ _2.label = 55;
2136
2172
  case 55: return [3 /*break*/, 57];
2137
2173
  case 56:
2138
2174
  if (serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null) {
@@ -2143,7 +2179,7 @@ var FlagApi = /** @class */ (function () {
2143
2179
  batchPayload.push(payload);
2144
2180
  }
2145
2181
  }
2146
- _0.label = 57;
2182
+ _2.label = 57;
2147
2183
  case 57:
2148
2184
  // If flag is enabled, store it in data
2149
2185
  if (isEnabled) {
@@ -2170,49 +2206,62 @@ var FlagApi = /** @class */ (function () {
2170
2206
  // send debug event
2171
2207
  (0, DebuggerServiceUtil_1.sendDebugEventToWingify)(serviceContainer, debugEventProps);
2172
2208
  }
2173
- if (!((_w = feature.getImpactCampaign()) === null || _w === void 0 ? void 0 : _w.getCampaignId())) return [3 /*break*/, 62];
2209
+ if (!((_y = feature.getImpactCampaign()) === null || _y === void 0 ? void 0 : _y.getCampaignId())) return [3 /*break*/, 62];
2174
2210
  serviceContainer.getLogManager().info((0, LogMessageUtil_1.buildMessage)(log_messages_1.InfoLogMessagesEnum.IMPACT_ANALYSIS, {
2175
2211
  userId: context.getId(),
2176
2212
  featureKey: featureKey,
2177
2213
  status: isEnabled ? 'enabled' : 'disabled',
2178
2214
  }));
2179
2215
  if (!!isDevModeForUser) return [3 /*break*/, 62];
2180
- payload = (0, NetworkUtil_1.getTrackUserPayloadData)(serviceContainer, EventEnum_1.EventEnum.VARIATION_SHOWN, (_x = feature.getImpactCampaign()) === null || _x === void 0 ? void 0 : _x.getCampaignId(), isEnabled ? 2 : 1, context);
2216
+ payload = (0, NetworkUtil_1.getTrackUserPayloadData)(serviceContainer, EventEnum_1.EventEnum.VARIATION_SHOWN, (_z = feature.getImpactCampaign()) === null || _z === void 0 ? void 0 : _z.getCampaignId(), isEnabled ? 2 : 1, context);
2217
+ if (payload) {
2218
+ isVariationShownFired = true;
2219
+ }
2181
2220
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 61];
2182
2221
  if (!(serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null)) return [3 /*break*/, 59];
2183
- return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, (_y = feature.getImpactCampaign()) === null || _y === void 0 ? void 0 : _y.getCampaignId(), isEnabled ? 2 : 1, context, featureKey, payload)];
2222
+ return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, (_0 = feature.getImpactCampaign()) === null || _0 === void 0 ? void 0 : _0.getCampaignId(), isEnabled ? 2 : 1, context, featureKey, payload)];
2184
2223
  case 58:
2185
- _0.sent();
2224
+ _2.sent();
2186
2225
  return [3 /*break*/, 60];
2187
2226
  case 59:
2188
2227
  if (payload != null) {
2189
2228
  batchPayload.push(payload);
2190
2229
  }
2191
- _0.label = 60;
2230
+ _2.label = 60;
2192
2231
  case 60: return [3 /*break*/, 62];
2193
2232
  case 61:
2194
2233
  if (serviceContainer.getSettingsService().isGatewayServiceProvided && payload != null) {
2195
- (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, (_z = feature.getImpactCampaign()) === null || _z === void 0 ? void 0 : _z.getCampaignId(), isEnabled ? 2 : 1, context, featureKey, payload);
2234
+ (0, ImpressionUtil_1.sendImpressionForVariationShown)(serviceContainer, (_1 = feature.getImpactCampaign()) === null || _1 === void 0 ? void 0 : _1.getCampaignId(), isEnabled ? 2 : 1, context, featureKey, payload);
2196
2235
  }
2197
2236
  else {
2198
2237
  if (payload != null) {
2199
2238
  batchPayload.push(payload);
2200
2239
  }
2201
2240
  }
2202
- _0.label = 62;
2241
+ _2.label = 62;
2203
2242
  case 62:
2204
- deferredObject.resolve(new Flag(isEnabled, context.getSessionId(), context.getUuid(), new VariationModel_1.VariationModel().modelFromDictionary(experimentVariationToReturn !== null && experimentVariationToReturn !== void 0 ? experimentVariationToReturn : rolloutVariationToReturn)));
2205
- if (!(!serviceContainer.getSettingsService().isGatewayServiceProvided && batchPayload.length > 0)) return [3 /*break*/, 65];
2206
- if (!!isDevModeForUser) return [3 /*break*/, 65];
2243
+ if (!!isVariationShownFired) return [3 /*break*/, 65];
2207
2244
  if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 64];
2208
- return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, batchPayload)];
2245
+ return [4 /*yield*/, sendTrackingUsage(serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey, true)];
2209
2246
  case 63:
2210
- _0.sent();
2247
+ _2.sent();
2211
2248
  return [3 /*break*/, 65];
2212
2249
  case 64:
2250
+ sendTrackingUsage(serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey); // fire-and-forget
2251
+ _2.label = 65;
2252
+ case 65:
2253
+ deferredObject.resolve(new Flag(isEnabled, context.getSessionId(), context.getUuid(), new VariationModel_1.VariationModel().modelFromDictionary(experimentVariationToReturn !== null && experimentVariationToReturn !== void 0 ? experimentVariationToReturn : rolloutVariationToReturn)));
2254
+ if (!(!serviceContainer.getSettingsService().isGatewayServiceProvided && batchPayload.length > 0)) return [3 /*break*/, 68];
2255
+ if (!!isDevModeForUser) return [3 /*break*/, 68];
2256
+ if (!serviceContainer.getShouldWaitForTrackingCalls()) return [3 /*break*/, 67];
2257
+ return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, batchPayload)];
2258
+ case 66:
2259
+ _2.sent();
2260
+ return [3 /*break*/, 68];
2261
+ case 67:
2213
2262
  (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, batchPayload);
2214
- _0.label = 65;
2215
- case 65: return [2 /*return*/, deferredObject.promise];
2263
+ _2.label = 68;
2264
+ case 68: return [2 /*return*/, deferredObject.promise];
2216
2265
  }
2217
2266
  });
2218
2267
  });
@@ -2255,6 +2304,64 @@ function _updateDebugEventProps(debugEventProps, decision) {
2255
2304
  debugEventProps.msg = message;
2256
2305
  Object.assign(debugEventProps, decisionKeys);
2257
2306
  }
2307
+ /**
2308
+ * Sends the usage tracking payload to server.
2309
+ * Called whenever a user is evaluated via getFlag() but no variationShown event is
2310
+ * dispatched by the SDK for that evaluation (decision from storage cache, flag=false, etc.).
2311
+ *
2312
+ * Routes through BatchEventsQueue when configured, otherwise fire-and-forget
2313
+ * (or awaited when shouldAwait is true).
2314
+ *
2315
+ * @param serviceContainer - The service container instance.
2316
+ * @param context - The user context model.
2317
+ * @param isTrackingUsageEnabled - Whether usage tracking is active for this account.
2318
+ * @param isDevModeForUser - Whether dev mode is active (suppresses all tracking).
2319
+ * @param shouldAwait - When true, awaits the network call (for shouldWaitForTrackingCalls flows).
2320
+ */
2321
+ function sendTrackingUsage(serviceContainer_1, context_1, isTrackingUsageEnabled_1, isDevModeForUser_1, featureKey_1) {
2322
+ return __awaiter(this, arguments, void 0, function (serviceContainer, context, isTrackingUsageEnabled, isDevModeForUser, featureKey, shouldAwait) {
2323
+ var trackingPayload, properties;
2324
+ if (shouldAwait === void 0) { shouldAwait = false; }
2325
+ return __generator(this, function (_a) {
2326
+ switch (_a.label) {
2327
+ case 0:
2328
+ if (!isTrackingUsageEnabled || isDevModeForUser)
2329
+ return [2 /*return*/];
2330
+ trackingPayload = (0, NetworkUtil_1.getTrackingUsagePayloadData)(serviceContainer, context);
2331
+ serviceContainer.getLogManager().info((0, LogMessageUtil_1.buildMessage)(log_messages_1.InfoLogMessagesEnum.USAGE_TRACKING_CALL_SENT, {
2332
+ accountId: serviceContainer.getSettingsService().accountId.toString(),
2333
+ userId: context.getId(),
2334
+ featureKey: featureKey,
2335
+ }));
2336
+ if (!serviceContainer.getBatchEventsQueue()) return [3 /*break*/, 1];
2337
+ serviceContainer.getBatchEventsQueue().enqueue(trackingPayload);
2338
+ return [3 /*break*/, 8];
2339
+ case 1:
2340
+ if (!serviceContainer.getSettingsService().isGatewayServiceProvided) return [3 /*break*/, 5];
2341
+ properties = (0, NetworkUtil_1.getEventsBaseProperties)(serviceContainer.getSettingsService(), EventEnum_1.EventEnum.USER_EVALUATED, encodeURIComponent(context.getUserAgent()), context.getIpAddress());
2342
+ if (!shouldAwait) return [3 /*break*/, 3];
2343
+ return [4 /*yield*/, (0, NetworkUtil_1.sendPostApiRequest)(serviceContainer, properties, trackingPayload, context.getId())];
2344
+ case 2:
2345
+ _a.sent();
2346
+ return [3 /*break*/, 4];
2347
+ case 3:
2348
+ (0, NetworkUtil_1.sendPostApiRequest)(serviceContainer, properties, trackingPayload, context.getId()); // fire-and-forget
2349
+ _a.label = 4;
2350
+ case 4: return [3 /*break*/, 8];
2351
+ case 5:
2352
+ if (!shouldAwait) return [3 /*break*/, 7];
2353
+ return [4 /*yield*/, (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, [trackingPayload])];
2354
+ case 6:
2355
+ _a.sent();
2356
+ return [3 /*break*/, 8];
2357
+ case 7:
2358
+ (0, ImpressionUtil_1.sendImpressionForVariationShownInBatch)(serviceContainer, [trackingPayload]); // fire-and-forget
2359
+ _a.label = 8;
2360
+ case 8: return [2 /*return*/];
2361
+ }
2362
+ });
2363
+ });
2364
+ }
2258
2365
 
2259
2366
 
2260
2367
  /***/ }),
@@ -3005,6 +3112,7 @@ var EventEnum;
3005
3112
  EventEnum["USAGE_STATS"] = "vwo_sdkUsageStats";
3006
3113
  EventEnum["HOLDOUT"] = "vwo_holdout";
3007
3114
  EventEnum["DEBUGGER_EVENT"] = "vwo_sdkDebug";
3115
+ EventEnum["USER_EVALUATED"] = "vwo_feTrackUsage";
3008
3116
  })(EventEnum || (exports.EventEnum = EventEnum = {}));
3009
3117
 
3010
3118
 
@@ -4214,6 +4322,9 @@ var SettingsModel = /** @class */ (function () {
4214
4322
  if (settings.isWebConnectivityEnabled) {
4215
4323
  this.isWebConnectivityEnabled = settings.isWebConnectivityEnabled;
4216
4324
  }
4325
+ if (settings.isMAU !== undefined) {
4326
+ this.isMAU = settings.isMAU;
4327
+ }
4217
4328
  if (Array.isArray(settings.holdouts)) {
4218
4329
  var holdoutsArray = settings.holdouts;
4219
4330
  holdoutsArray.forEach(function (holdout) {
@@ -4264,6 +4375,9 @@ var SettingsModel = /** @class */ (function () {
4264
4375
  SettingsModel.prototype.getDevMode = function () {
4265
4376
  return this.devMode === true;
4266
4377
  };
4378
+ SettingsModel.prototype.getIsTrackingUsageEnabled = function () {
4379
+ return this.isMAU === true;
4380
+ };
4267
4381
  return SettingsModel;
4268
4382
  }());
4269
4383
  exports.SettingsModel = SettingsModel;
@@ -12721,6 +12835,7 @@ exports._getEventBasePayload = _getEventBasePayload;
12721
12835
  exports.getTrackUserPayloadData = getTrackUserPayloadData;
12722
12836
  exports.getTrackGoalPayloadData = getTrackGoalPayloadData;
12723
12837
  exports.getAttributePayloadData = getAttributePayloadData;
12838
+ exports.getTrackingUsagePayloadData = getTrackingUsagePayloadData;
12724
12839
  exports.sendPostApiRequest = sendPostApiRequest;
12725
12840
  exports.getMessagingEventPayload = getMessagingEventPayload;
12726
12841
  exports.getSDKInitEventPayload = getSDKInitEventPayload;
@@ -13019,6 +13134,36 @@ function getAttributePayloadData(serviceContainer, eventName, attributes, contex
13019
13134
  }));
13020
13135
  return properties;
13021
13136
  }
13137
+ /**
13138
+ * Constructs the payload data for usage tracking call.
13139
+ * Sent to server when a user is evaluated via getFlag() but no variationShown
13140
+ * event is dispatched by the SDK (i.e., decision served from storage cache or
13141
+ * flag evaluation returned false with no holdout impression already fired).
13142
+ *
13143
+ * Payload contains only user identity + session + SDK metadata.
13144
+ * There is NO campaignId or variationId — this is a pure user-evaluation signal.
13145
+ *
13146
+ * @param {ServiceContainer} serviceContainer - The service container instance.
13147
+ * @param {ContextModel} context - The context model instance.
13148
+ * @returns {Record<string, any>} - The usage tracking payload.
13149
+ */
13150
+ function getTrackingUsagePayloadData(serviceContainer, context) {
13151
+ var userId = context.getId();
13152
+ var properties = _getEventBasePayload(serviceContainer.getSettingsService(), userId, EventEnum_1.EventEnum.USER_EVALUATED, context.getUserAgent(), context.getIpAddress());
13153
+ if (context.getSessionId() !== 0) {
13154
+ properties.d.sessionId = context.getSessionId();
13155
+ }
13156
+ // if uuid is present in the context, use it, otherwise generate a new one
13157
+ if (context.getUuid()) {
13158
+ properties.d.msgId = "".concat(context.getUuid(), "-").concat((0, FunctionUtil_1.getCurrentUnixTimestampInMillis)());
13159
+ properties.d.visId = context.getUuid();
13160
+ }
13161
+ serviceContainer.getLogManager().debug((0, LogMessageUtil_1.buildMessage)(log_messages_1.DebugLogMessagesEnum.IMPRESSION_FOR_TRACKING_USAGE, {
13162
+ accountId: serviceContainer.getSettingsService().accountId.toString(),
13163
+ userId: userId,
13164
+ }));
13165
+ return properties;
13166
+ }
13022
13167
  /**
13023
13168
  * Sends a POST API request with the specified properties and payload.
13024
13169
  * @param {ServiceContainer} serviceContainer - The service container instance.