expf-sigma-node.js 3.3.6 → 3.4.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 (2) hide show
  1. package/package.json +1 -1
  2. package/public/sigma.js +151 -41
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expf-sigma-node.js",
3
- "version": "3.3.6",
3
+ "version": "3.4.0",
4
4
  "description": "expf-sigma-node.js lets you manage features flags and remote config across web, server side applications. Deliver true Continuous Integration. Get builds out faster. Control who has access to new features.",
5
5
  "main": "public/sigma.js",
6
6
  "keywords": [
package/public/sigma.js CHANGED
@@ -927,16 +927,24 @@ var sigmaDataFileLastUpdate = "sigmaDataFileLastUpdate";
927
927
  var sigmaExpiration = "sigmaExpiration";
928
928
  var sigmaDataFile = "sigmaDataFile";
929
929
  var sigmaExperiments = "sigmaExperiments";
930
+ var sigmaHoldouts = "sigmaHoldouts";
931
+ var sigmaGeoData = "sigmaGeoData";
930
932
  var max_decimal_64 = 18446744073709552e3;
931
933
  var zeta = 8540717056e4;
932
934
  var SHA256 = new sigmaHashes_default.SHA256();
933
935
  var MD5 = new sigmaHashes_default.MD5();
934
936
  var expirationDate = 24 * 60 * 60 * 1e3;
935
937
  var secondsIn24Hours = 24 * 60 * 60;
936
- var sigmaGeoData = "sigmaGeoData";
937
938
  var defaultGeoCacheTTL = 5 * 60;
938
939
  var cacheStandardTimeToLive = 3600;
939
940
  var cacheCheckPeriod = 600;
941
+ var experimentType = {
942
+ featureFlag: 1,
943
+ param: 2,
944
+ splitUrl: 3,
945
+ webBuilder: 4,
946
+ holdout: 5
947
+ };
940
948
  var errorMessages = {
941
949
  emptyToken: "Please specify a token",
942
950
  APIRequestErrorConfig: {
@@ -958,9 +966,10 @@ var errorMessages = {
958
966
  };
959
967
  var signsForHash = ["equal", "not equal", "any of", "none of"];
960
968
  var prefixGroup = "sigma_group";
961
- var errorTypesInConfig = {
962
- invalidJson: 'Sigma warning. Invalid type json "%value%" in config.',
963
- invalidType: 'Sigma warning. Invalid type "%type%" in config.'
969
+ var warnings = {
970
+ invalidJson: 'Sigma warning: Invalid type json "%value%" in config.',
971
+ invalidType: 'Sigma warning: Invalid type "%type%" in config.',
972
+ emptyHoldoutId: "Sigma warning: Empty holdout id"
964
973
  };
965
974
  var sdkName = "node.js";
966
975
  var statusSuccess = "success";
@@ -1183,7 +1192,7 @@ function doTypeConversion(type, value) {
1183
1192
  return JSON.parse("{}");
1184
1193
  return JSON.parse(value);
1185
1194
  } catch (e) {
1186
- console.error(errorTypesInConfig.invalidJson.replace("%value%", value), e);
1195
+ console.error(warnings.invalidJson.replace("%value%", value), e);
1187
1196
  return null;
1188
1197
  }
1189
1198
  default:
@@ -1262,7 +1271,7 @@ function generateFilteredList(array, name) {
1262
1271
  }
1263
1272
 
1264
1273
  // package.json
1265
- var version = "3.3.6";
1274
+ var version = "3.4.0";
1266
1275
 
1267
1276
  // src/helpers/sdkVersion.js
1268
1277
  var sdkVersion = version;
@@ -1483,11 +1492,10 @@ var Sigma = class {
1483
1492
  if (!this.cache.get(sigmaDataFile) || this.hasExpireCache()) {
1484
1493
  return this.saveToCache();
1485
1494
  }
1486
- return true;
1487
1495
  }
1488
1496
  updateGeoCache() {
1489
1497
  if (!this.geoCache.get(sigmaGeoData)) {
1490
- this.saveToGeoCache();
1498
+ return this.saveToGeoCache();
1491
1499
  }
1492
1500
  }
1493
1501
  async getFlags() {
@@ -1705,20 +1713,31 @@ var Sigma = class {
1705
1713
  let groupIndex = null;
1706
1714
  let forcedUser = false;
1707
1715
  let splitById = null;
1716
+ let userInHoldout = false;
1708
1717
  for (let i = 0; i < sigmaDataLs.experiments.length; i++) {
1709
- if (sigmaDataLs.experiments[i]["name"] === experimentName && checkBoolValue(sigmaDataLs.experiments[i]["layer_id"])) {
1710
- layer = sigmaDataLs.experiments[i]["layer_id"];
1711
- bounds = sigmaDataLs.experiments[i]["layer_bounds"];
1712
- }
1713
- if (sigmaDataLs.experiments[i]["name"] === experimentName && !experiment) {
1714
- splitById = this.getSplitById(sigmaDataLs.experiments[i]);
1715
- forcedUser = checkForcedList(sigmaDataLs.experiments[i].forced_user_list, splitById);
1716
- groupName = this.findUserInForcedGroup(sigmaDataLs.experiments[i]);
1717
- experiment = this.experimentDefinition(sigmaDataLs.experiments[i], groupName, forcedUser);
1718
+ const experimentIndex = sigmaDataLs.experiments[i];
1719
+ if (experimentIndex["name"] === experimentName && checkBoolValue(experimentIndex["layer_id"])) {
1720
+ layer = experimentIndex["layer_id"];
1721
+ bounds = experimentIndex["layer_bounds"];
1722
+ }
1723
+ if (experimentIndex["name"] === experimentName) {
1724
+ splitById = this.getSplitById(experimentIndex);
1725
+ forcedUser = checkForcedList(experimentIndex.forced_user_list, splitById);
1726
+ groupName = this.findUserInForcedGroup(experimentIndex);
1727
+ experiment = this.experimentDefinition(experimentIndex, groupName, forcedUser);
1728
+ if (experimentIndex.holdouts && experimentIndex.holdouts.length) {
1729
+ for (const holdoutName of experimentIndex.holdouts) {
1730
+ userInHoldout = await this.getHoldout(holdoutName);
1731
+ if (userInHoldout)
1732
+ break;
1733
+ }
1734
+ }
1718
1735
  break;
1719
1736
  }
1720
1737
  }
1721
1738
  const localStorageGroupName = `${prefixGroup}_${experimentName}`;
1739
+ if (this.cache.get(localStorageGroupName))
1740
+ this.cache.remove(localStorageGroupName);
1722
1741
  if (experiment) {
1723
1742
  if (!groupName) {
1724
1743
  groupName = this.calcUserInGroup(
@@ -1731,11 +1750,18 @@ var Sigma = class {
1731
1750
  splitById
1732
1751
  );
1733
1752
  }
1734
- this.cache.set(localStorageGroupName, groupName);
1735
- groupIndex = experiment.groups.findIndex((i) => i.name == groupName);
1753
+ if (experiment.type === experimentType.holdout) {
1754
+ if (groupName)
1755
+ this.cache.set(localStorageGroupName, groupName);
1756
+ return groupName;
1757
+ }
1758
+ if (!userInHoldout) {
1759
+ this.cache.set(localStorageGroupName, groupName);
1760
+ groupIndex = experiment.groups.findIndex((i) => i.name == groupName);
1761
+ }
1736
1762
  }
1737
1763
  const getParamValue = (paramName) => {
1738
- if (!paramName || !experiment) {
1764
+ if (!paramName || !experiment || userInHoldout) {
1739
1765
  return null;
1740
1766
  }
1741
1767
  const groupName2 = this.cache.get(localStorageGroupName);
@@ -1758,7 +1784,7 @@ var Sigma = class {
1758
1784
  return paramValue;
1759
1785
  };
1760
1786
  const getFeatureValue = (flagName) => {
1761
- if (!flagName || !experiment) {
1787
+ if (!flagName || !experiment || userInHoldout) {
1762
1788
  return null;
1763
1789
  }
1764
1790
  const groupName2 = this.cache.get(localStorageGroupName);
@@ -1786,10 +1812,11 @@ var Sigma = class {
1786
1812
  return {
1787
1813
  getParamValue,
1788
1814
  getFeatureValue,
1789
- groupIndex: groupIndex < 0 ? null : groupIndex
1815
+ groupIndex: groupIndex < 0 ? null : groupIndex,
1816
+ userInHoldout
1790
1817
  };
1791
1818
  }
1792
- async getAllUserExperiments() {
1819
+ async getAllUserExperiments(estimateHoldouts = true) {
1793
1820
  await this.updateCache();
1794
1821
  await this.updateGeoCache();
1795
1822
  const sigmaDataLs = this.cache.parse(sigmaDataFile);
@@ -1797,33 +1824,70 @@ var Sigma = class {
1797
1824
  return null;
1798
1825
  let result = "";
1799
1826
  for (let i in sigmaDataLs.experiments) {
1827
+ if (!estimateHoldouts && sigmaDataLs.experiments[i].type === experimentType.holdout)
1828
+ continue;
1800
1829
  let layer = null;
1801
1830
  let bounds = [];
1802
1831
  let splitById = this.getSplitById(sigmaDataLs.experiments[i]);
1803
1832
  let forcedUser = checkForcedList(sigmaDataLs.experiments[i].forced_user_list, splitById);
1804
1833
  let userInGroupExperiment = this.findUserInForcedGroup(sigmaDataLs.experiments[i]);
1805
1834
  let experiment = this.experimentDefinition(sigmaDataLs.experiments[i], userInGroupExperiment, forcedUser);
1806
- if (experiment) {
1807
- if (checkBoolValue(experiment["layer_id"]) && !userInGroupExperiment) {
1808
- layer = experiment["layer_id"];
1809
- bounds = experiment["layer_bounds"];
1810
- }
1811
- if (!userInGroupExperiment) {
1812
- userInGroupExperiment = this.calcUserInGroup(
1813
- experiment.salt,
1814
- experiment.allocation,
1815
- experiment.groups,
1816
- forcedUser,
1817
- layer,
1818
- bounds,
1819
- splitById
1835
+ let userInHoldout;
1836
+ if (!experiment)
1837
+ continue;
1838
+ if (checkBoolValue(experiment["layer_id"]) && !userInGroupExperiment) {
1839
+ layer = experiment["layer_id"];
1840
+ bounds = experiment["layer_bounds"];
1841
+ }
1842
+ if (!userInGroupExperiment) {
1843
+ userInGroupExperiment = this.calcUserInGroup(
1844
+ experiment.salt,
1845
+ experiment.allocation,
1846
+ experiment.groups,
1847
+ forcedUser,
1848
+ layer,
1849
+ bounds,
1850
+ splitById
1851
+ );
1852
+ }
1853
+ if (!userInGroupExperiment)
1854
+ continue;
1855
+ if (sigmaDataLs.experiments[i].holdouts && sigmaDataLs.experiments[i].holdouts.length > 0) {
1856
+ for (const holdout of sigmaDataLs.experiments[i].holdouts) {
1857
+ const foundingExperimentHoldout = sigmaDataLs.experiments.find((exp) => exp.name === holdout);
1858
+ if (!foundingExperimentHoldout)
1859
+ break;
1860
+ const splitByHoldoutId = this.getSplitById(foundingExperimentHoldout);
1861
+ if (!splitByHoldoutId)
1862
+ continue;
1863
+ const holdoutForcedUser = checkForcedList(foundingExperimentHoldout.forced_user_list, splitByHoldoutId);
1864
+ let userInGroupHoldout = this.findUserInForcedGroup(foundingExperimentHoldout);
1865
+ if (userInGroupHoldout) {
1866
+ userInHoldout = true;
1867
+ break;
1868
+ }
1869
+ const experimentByHoldout = this.experimentDefinition(foundingExperimentHoldout, userInGroupHoldout, holdoutForcedUser);
1870
+ if (!experimentByHoldout)
1871
+ continue;
1872
+ userInGroupHoldout = this.calcUserInGroup(
1873
+ experimentByHoldout.salt,
1874
+ experimentByHoldout.allocation,
1875
+ experimentByHoldout.groups,
1876
+ holdoutForcedUser,
1877
+ null,
1878
+ [],
1879
+ splitByHoldoutId
1820
1880
  );
1881
+ if (userInGroupHoldout) {
1882
+ userInHoldout = true;
1883
+ break;
1884
+ }
1821
1885
  }
1822
1886
  }
1823
- if (userInGroupExperiment) {
1824
- const groupIndex = experiment.groups.findIndex((i2) => i2.name == userInGroupExperiment);
1825
- result = result.concat(experiment.name).concat(".").concat(groupIndex).concat("|");
1826
- }
1887
+ if (userInHoldout)
1888
+ continue;
1889
+ const groupIndex = experiment.groups.findIndex((i2) => i2.name == userInGroupExperiment);
1890
+ result = result.concat(experiment.name).concat(".").concat(groupIndex).concat("|");
1827
1891
  }
1828
1892
  if (result.length > 0) {
1829
1893
  this.cache.set(sigmaExperiments, result.slice(0, -1));
@@ -1833,6 +1897,52 @@ var Sigma = class {
1833
1897
  }
1834
1898
  return null;
1835
1899
  }
1900
+ async getHoldout(name) {
1901
+ if (!name)
1902
+ return console.log(warnings.emptyHoldoutId);
1903
+ const holdoutGroup = await this.getExperiment(name);
1904
+ if (holdoutGroup && typeof holdoutGroup === "string")
1905
+ return true;
1906
+ return false;
1907
+ }
1908
+ async getAllUserHoldouts() {
1909
+ await this.updateCache();
1910
+ const sigmaDataLs = await this.cache.parse(sigmaDataFile);
1911
+ if (!sigmaDataLs.experiments.length)
1912
+ return null;
1913
+ let result = "";
1914
+ for (const holdout of sigmaDataLs.experiments) {
1915
+ if (holdout.type !== experimentType.holdout)
1916
+ continue;
1917
+ let userInGroupExperiment = false;
1918
+ const layer = null;
1919
+ const bounds = [];
1920
+ const splitById = this.getSplitById(holdout);
1921
+ const forcedUser = checkForcedList(holdout.forced_user_list, splitById);
1922
+ const experiment = this.experimentDefinition(holdout, userInGroupExperiment, forcedUser);
1923
+ if (!experiment)
1924
+ continue;
1925
+ userInGroupExperiment = this.calcUserInGroup(
1926
+ experiment.salt,
1927
+ experiment.allocation,
1928
+ experiment.groups,
1929
+ forcedUser,
1930
+ layer,
1931
+ bounds,
1932
+ splitById
1933
+ );
1934
+ if (!userInGroupExperiment)
1935
+ continue;
1936
+ result = result.concat(holdout.name).concat(".").concat("0").concat("|");
1937
+ }
1938
+ if (result.length > 0) {
1939
+ this.cache.set(sigmaHoldouts, result.slice(0, -1));
1940
+ return result.slice(0, -1);
1941
+ } else {
1942
+ this.cache.remove(sigmaHoldouts);
1943
+ }
1944
+ return null;
1945
+ }
1836
1946
  findUserInForcedGroup(experiment) {
1837
1947
  let groupName = false;
1838
1948
  for (const groupItem in experiment.groups) {