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.
- package/package.json +1 -1
- 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
|
+
"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
|
|
962
|
-
invalidJson: 'Sigma warning
|
|
963
|
-
invalidType: 'Sigma warning
|
|
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(
|
|
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.
|
|
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
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
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
|
-
|
|
1735
|
-
|
|
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
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
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 (
|
|
1824
|
-
|
|
1825
|
-
|
|
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) {
|