@splitsoftware/splitio-commons 1.11.0 → 1.12.1-rc.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 (79) hide show
  1. package/CHANGES.txt +4 -0
  2. package/cjs/evaluator/index.js +19 -3
  3. package/cjs/logger/constants.js +4 -2
  4. package/cjs/logger/messages/warn.js +3 -1
  5. package/cjs/sdkClient/client.js +1 -1
  6. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +2 -7
  7. package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -10
  8. package/cjs/storages/pluggable/SplitsCachePluggable.js +25 -8
  9. package/cjs/storages/pluggable/index.js +1 -1
  10. package/cjs/utils/lang/sets.js +11 -1
  11. package/cjs/utils/settingsValidation/index.js +1 -1
  12. package/cjs/utils/settingsValidation/splitFilters.js +17 -10
  13. package/esm/evaluator/index.js +20 -4
  14. package/esm/logger/constants.js +2 -0
  15. package/esm/logger/messages/warn.js +3 -1
  16. package/esm/sdkClient/client.js +1 -1
  17. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +3 -8
  18. package/esm/storages/inMemory/SplitsCacheInMemory.js +3 -11
  19. package/esm/storages/pluggable/SplitsCachePluggable.js +26 -9
  20. package/esm/storages/pluggable/index.js +1 -1
  21. package/esm/utils/lang/sets.js +9 -0
  22. package/esm/utils/settingsValidation/index.js +1 -1
  23. package/esm/utils/settingsValidation/splitFilters.js +9 -2
  24. package/package.json +2 -2
  25. package/src/evaluator/index.ts +24 -4
  26. package/src/logger/constants.ts +2 -0
  27. package/src/logger/messages/warn.ts +9 -7
  28. package/src/sdkClient/client.ts +1 -1
  29. package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
  30. package/src/storages/AbstractSplitsCacheSync.ts +1 -1
  31. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +4 -10
  32. package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
  33. package/src/storages/inRedis/SplitsCacheInRedis.ts +1 -1
  34. package/src/storages/pluggable/SplitsCachePluggable.ts +32 -10
  35. package/src/storages/pluggable/index.ts +1 -1
  36. package/src/storages/types.ts +5 -5
  37. package/src/types.ts +0 -2
  38. package/src/utils/lang/sets.ts +9 -1
  39. package/src/utils/settingsValidation/index.ts +1 -1
  40. package/src/utils/settingsValidation/splitFilters.ts +13 -6
  41. package/types/evaluator/index.d.ts +1 -1
  42. package/types/logger/constants.d.ts +2 -0
  43. package/types/sdkClient/identity.d.ts +6 -0
  44. package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
  45. package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
  46. package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
  47. package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
  48. package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -1
  49. package/types/storages/pluggable/SplitsCachePluggable.d.ts +7 -6
  50. package/types/storages/types.d.ts +5 -5
  51. package/types/types.d.ts +0 -2
  52. package/types/utils/inputValidation/sdkKey.d.ts +7 -0
  53. package/types/utils/lang/sets.d.ts +1 -0
  54. package/types/utils/settingsValidation/splitFilters.d.ts +2 -1
  55. package/types/myLogger.d.ts +0 -5
  56. package/types/sdkClient/types.d.ts +0 -18
  57. package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
  58. package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
  59. package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
  60. package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
  61. package/types/storages/metadataBuilder.d.ts +0 -3
  62. package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
  63. package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
  64. package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
  65. package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
  66. package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
  67. package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
  68. package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
  69. package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
  70. package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
  71. package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
  72. package/types/sync/syncTaskComposite.d.ts +0 -5
  73. package/types/trackers/filter/bloomFilter.d.ts +0 -10
  74. package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
  75. package/types/trackers/filter/types.d.ts +0 -5
  76. package/types/utils/timeTracker/index.d.ts +0 -70
  77. /package/types/storages/inMemory/{uniqueKeysCacheInMemory.d.ts → UniqueKeysCacheInMemory.d.ts} +0 -0
  78. /package/types/storages/inMemory/{uniqueKeysCacheInMemoryCS.d.ts → UniqueKeysCacheInMemoryCS.d.ts} +0 -0
  79. /package/types/storages/inRedis/{uniqueKeysCacheInRedis.d.ts → UniqueKeysCacheInRedis.d.ts} +0 -0
package/CHANGES.txt CHANGED
@@ -1,3 +1,7 @@
1
+ 1.12.0 (December XX, 2023)
2
+ - Added support for Flag Sets in "consumer" and "partial consumer" modes for pluggable storage.
3
+ - Updated evaluation flow to log a warning when using flag sets that don't contain cached feature flags.
4
+
1
5
  1.11.0 (November 3, 2023)
2
6
  - Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation):
3
7
  - Added new variations of the get treatment methods to support evaluating flags in given flag set/s.
@@ -7,6 +7,7 @@ var thenable_1 = require("../utils/promise/thenable");
7
7
  var LabelsConstants = (0, tslib_1.__importStar)(require("../utils/labels"));
8
8
  var constants_1 = require("../utils/constants");
9
9
  var sets_1 = require("../utils/lang/sets");
10
+ var constants_2 = require("../logger/constants");
10
11
  var treatmentException = {
11
12
  treatment: constants_1.CONTROL,
12
13
  label: LabelsConstants.EXCEPTION,
@@ -56,8 +57,23 @@ function evaluateFeatures(log, key, splitNames, attributes, storage) {
56
57
  getEvaluations(log, splitNames, parsedSplits, key, attributes, storage);
57
58
  }
58
59
  exports.evaluateFeatures = evaluateFeatures;
59
- function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage) {
60
+ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
60
61
  var storedFlagNames;
62
+ function evaluate(featureFlagsByFlagSets) {
63
+ var featureFlags = new sets_1._Set();
64
+ for (var i = 0; i < flagSets.length; i++) {
65
+ var featureFlagByFlagSet = featureFlagsByFlagSets[i];
66
+ if (featureFlagByFlagSet.size) {
67
+ featureFlags = (0, sets_1.returnSetsUnion)(featureFlags, featureFlagByFlagSet);
68
+ }
69
+ else {
70
+ log.warn(constants_2.WARN_FLAGSET_WITHOUT_FLAGS, [method, flagSets[i]]);
71
+ }
72
+ }
73
+ return featureFlags.size ?
74
+ evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage) :
75
+ {};
76
+ }
61
77
  // get features by flag sets
62
78
  try {
63
79
  storedFlagNames = storage.splits.getNamesByFlagSets(flagSets);
@@ -68,11 +84,11 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage) {
68
84
  }
69
85
  // evaluate related features
70
86
  return (0, thenable_1.thenable)(storedFlagNames) ?
71
- storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, (0, sets_1.setToArray)(splitNames), attributes, storage); })
87
+ storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
72
88
  .catch(function () {
73
89
  return {};
74
90
  }) :
75
- evaluateFeatures(log, key, (0, sets_1.setToArray)(storedFlagNames), attributes, storage);
91
+ evaluate(storedFlagNames);
76
92
  }
77
93
  exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
78
94
  function getEvaluation(log, splitJSON, key, attributes, storage) {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SYNC_SPLITS_FETCH_RETRY = exports.POLLING_STOP = exports.POLLING_START = exports.POLLING_SMART_PAUSING = exports.NEW_FACTORY = exports.NEW_SHARED_CLIENT = exports.IMPRESSION_QUEUEING = exports.IMPRESSION = exports.CLIENT_READY = exports.CLIENT_READY_FROM_CACHE = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_SPLITS_SEGMENTS = exports.SYNC_SPLITS_REMOVED = exports.SYNC_SPLITS_NEW = exports.SYNC_SPLITS_FETCH = exports.SYNC_OFFLINE_DATA = exports.RETRIEVE_MANAGER = exports.RETRIEVE_CLIENT_EXISTING = exports.RETRIEVE_CLIENT_DEFAULT = exports.CLEANUP_DEREGISTERING = exports.CLEANUP_REGISTERING = exports.ENGINE_SANITIZE = exports.ENGINE_VALUE = exports.ENGINE_MATCHER_WHITELIST = exports.ENGINE_MATCHER_STARTS_WITH = exports.ENGINE_MATCHER_STRING_INVALID = exports.ENGINE_MATCHER_STRING = exports.ENGINE_MATCHER_SEGMENT = exports.ENGINE_MATCHER_PART_OF = exports.ENGINE_MATCHER_LESS = exports.ENGINE_MATCHER_GREATER = exports.ENGINE_MATCHER_ENDS_WITH = exports.ENGINE_MATCHER_EQUAL_TO_SET = exports.ENGINE_MATCHER_EQUAL = exports.ENGINE_MATCHER_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_MATCHER_CONTAINS_STRING = exports.ENGINE_MATCHER_CONTAINS_ANY = exports.ENGINE_MATCHER_CONTAINS_ALL = exports.ENGINE_MATCHER_BOOLEAN = exports.ENGINE_MATCHER_BETWEEN = exports.ENGINE_MATCHER_ALL = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
4
- exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.WARN_FLAGSET_NOT_CONFIGURED = exports.WARN_SPLITS_FILTER_LOWERCASE_SET = exports.WARN_SPLITS_FILTER_INVALID_SET = exports.STREAMING_PARSING_SPLIT_UPDATE = exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = exports.WARN_SDK_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = void 0;
5
- exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_SETS_FILTER_EXCLUSIVE = exports.ERROR_TOO_MANY_SETS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = void 0;
4
+ exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.WARN_FLAGSET_WITHOUT_FLAGS = exports.WARN_FLAGSET_NOT_CONFIGURED = exports.WARN_SPLITS_FILTER_LOWERCASE_SET = exports.WARN_SPLITS_FILTER_INVALID_SET = exports.STREAMING_PARSING_SPLIT_UPDATE = exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = exports.WARN_SDK_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_SPLITS_FILTER_IGNORED = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = void 0;
5
+ exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_SETS_FILTER_EXCLUSIVE = exports.ERROR_TOO_MANY_SETS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = void 0;
6
6
  /**
7
7
  * Message codes used to trim string log messages from commons and client-side API modules,
8
8
  * in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
@@ -94,6 +94,7 @@ exports.WARN_NOT_EXISTENT_SPLIT = 215;
94
94
  exports.WARN_LOWERCASE_TRAFFIC_TYPE = 216;
95
95
  exports.WARN_NOT_EXISTENT_TT = 217;
96
96
  exports.WARN_INTEGRATION_INVALID = 218;
97
+ exports.WARN_SPLITS_FILTER_IGNORED = 219;
97
98
  exports.WARN_SPLITS_FILTER_INVALID = 220;
98
99
  exports.WARN_SPLITS_FILTER_EMPTY = 221;
99
100
  exports.WARN_SDK_KEY = 222;
@@ -102,6 +103,7 @@ exports.STREAMING_PARSING_SPLIT_UPDATE = 224;
102
103
  exports.WARN_SPLITS_FILTER_INVALID_SET = 225;
103
104
  exports.WARN_SPLITS_FILTER_LOWERCASE_SET = 226;
104
105
  exports.WARN_FLAGSET_NOT_CONFIGURED = 227;
106
+ exports.WARN_FLAGSET_WITHOUT_FLAGS = 228;
105
107
  exports.ERROR_ENGINE_COMBINER_IFELSEIF = 300;
106
108
  exports.ERROR_LOGLEVEL_INVALID = 301;
107
109
  exports.ERROR_CLIENT_LISTENER = 302;
@@ -27,9 +27,10 @@ exports.codesWarn = error_1.codesError.concat([
27
27
  [c.WARN_NOT_EXISTENT_SPLIT, '%s: feature flag "%s" does not exist in this environment. Please double check what feature flags exist in the Split user interface.'],
28
28
  [c.WARN_LOWERCASE_TRAFFIC_TYPE, '%s: traffic_type_name should be all lowercase - converting string to lowercase.'],
29
29
  [c.WARN_NOT_EXISTENT_TT, '%s: traffic type "%s" does not have any corresponding feature flag in this environment, make sure you\'re tracking your events to a valid traffic type defined in the Split user interface.'],
30
- [c.WARN_FLAGSET_NOT_CONFIGURED, '%s: : you passed %s wich is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
30
+ [c.WARN_FLAGSET_NOT_CONFIGURED, '%s: you passed %s which is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
31
31
  // initialization / settings validation
32
32
  [c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS + ': %s integration item(s) at settings is invalid. %s'],
33
+ [c.WARN_SPLITS_FILTER_IGNORED, c.LOG_PREFIX_SETTINGS + ': feature flag filters are not applicable for Consumer modes where the SDK does not keep rollout data in sync. Filters were discarded'],
33
34
  [c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ': feature flag filter at position %s is invalid. It must be an object with a valid filter type ("bySet", "byName" or "byPrefix") and a list of "values".'],
34
35
  [c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
35
36
  [c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
@@ -37,4 +38,5 @@ exports.codesWarn = error_1.codesError.concat([
37
38
  [c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
38
39
  [c.WARN_SPLITS_FILTER_INVALID_SET, c.LOG_PREFIX_SETTINGS + ': you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
39
40
  [c.WARN_SPLITS_FILTER_LOWERCASE_SET, c.LOG_PREFIX_SETTINGS + ': flag set %s should be all lowercase - converting string to lowercase.'],
41
+ [c.WARN_FLAGSET_WITHOUT_FLAGS, '%s: you passed %s flag set that does not contain cached feature flag names. Please double check what flag sets are in use in the Split user interface.'],
40
42
  ]);
@@ -83,7 +83,7 @@ function clientFactory(params) {
83
83
  return treatments;
84
84
  };
85
85
  var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
86
- (0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage) :
86
+ (0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, method) :
87
87
  (0, utils_1.isStorageSync)(settings) ? {} : Promise.resolve({}); // Promisify if async
88
88
  return (0, thenable_1.thenable)(evaluations) ? evaluations.then(function (res) { return wrapUp(res); }) : wrapUp(evaluations);
89
89
  }
@@ -231,16 +231,11 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
231
231
  };
232
232
  SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
233
233
  var _this = this;
234
- var toReturn = new sets_1._Set([]);
235
- flagSets.forEach(function (flagSet) {
234
+ return flagSets.map(function (flagSet) {
236
235
  var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
237
236
  var flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
238
- if (flagSetFromLocalStorage) {
239
- var flagSetCache = new sets_1._Set(JSON.parse(flagSetFromLocalStorage));
240
- toReturn = (0, sets_1.returnSetsUnion)(toReturn, flagSetCache);
241
- }
237
+ return new sets_1._Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
242
238
  });
243
- return toReturn;
244
239
  };
245
240
  SplitsCacheInLocal.prototype.addToFlagSets = function (featureFlag) {
246
241
  var _this = this;
@@ -12,14 +12,13 @@ var sets_1 = require("../../utils/lang/sets");
12
12
  var SplitsCacheInMemory = /** @class */ (function (_super) {
13
13
  (0, tslib_1.__extends)(SplitsCacheInMemory, _super);
14
14
  function SplitsCacheInMemory(splitFiltersValidation) {
15
- if (splitFiltersValidation === void 0) { splitFiltersValidation = { queryString: null, groupedFilters: { bySet: [], byName: [], byPrefix: [] }, validFilters: [] }; }
16
15
  var _this = _super.call(this) || this;
17
16
  _this.splitsCache = {};
18
17
  _this.ttCache = {};
19
18
  _this.changeNumber = -1;
20
19
  _this.splitsWithSegmentsCount = 0;
21
20
  _this.flagSetsCache = {};
22
- _this.flagSetsFilter = splitFiltersValidation.groupedFilters.bySet;
21
+ _this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
23
22
  return _this;
24
23
  }
25
24
  SplitsCacheInMemory.prototype.clear = function () {
@@ -96,14 +95,7 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
96
95
  };
97
96
  SplitsCacheInMemory.prototype.getNamesByFlagSets = function (flagSets) {
98
97
  var _this = this;
99
- var toReturn = new sets_1._Set([]);
100
- flagSets.forEach(function (flagSet) {
101
- var featureFlagNames = _this.flagSetsCache[flagSet];
102
- if (featureFlagNames) {
103
- toReturn = (0, sets_1.returnSetsUnion)(toReturn, featureFlagNames);
104
- }
105
- });
106
- return toReturn;
98
+ return flagSets.map(function (flagSet) { return _this.flagSetsCache[flagSet] || new sets_1._Set(); });
107
99
  };
108
100
  SplitsCacheInMemory.prototype.addToFlagSets = function (featureFlag) {
109
101
  var _this = this;
@@ -5,6 +5,7 @@ var tslib_1 = require("tslib");
5
5
  var lang_1 = require("../../utils/lang");
6
6
  var constants_1 = require("./constants");
7
7
  var AbstractSplitsCacheAsync_1 = require("../AbstractSplitsCacheAsync");
8
+ var sets_1 = require("../../utils/lang/sets");
8
9
  /**
9
10
  * ISplitsCacheAsync implementation for pluggable storages.
10
11
  */
@@ -16,11 +17,12 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
16
17
  * @param keys Key builder.
17
18
  * @param wrapper Adapted wrapper storage.
18
19
  */
19
- function SplitsCachePluggable(log, keys, wrapper) {
20
+ function SplitsCachePluggable(log, keys, wrapper, splitFiltersValidation) {
20
21
  var _this = _super.call(this) || this;
21
22
  _this.log = log;
22
23
  _this.keys = keys;
23
24
  _this.wrapper = wrapper;
25
+ _this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
24
26
  return _this;
25
27
  }
26
28
  SplitsCachePluggable.prototype._decrementCounts = function (split) {
@@ -35,6 +37,18 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
35
37
  var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
36
38
  return this.wrapper.incr(ttKey);
37
39
  };
40
+ SplitsCachePluggable.prototype._updateFlagSets = function (featureFlagName, flagSetsOfRemovedFlag, flagSetsOfAddedFlag) {
41
+ var _this = this;
42
+ var removeFromFlagSets = (0, sets_1.returnListDifference)(flagSetsOfRemovedFlag, flagSetsOfAddedFlag);
43
+ var addToFlagSets = (0, sets_1.returnListDifference)(flagSetsOfAddedFlag, flagSetsOfRemovedFlag);
44
+ if (this.flagSetsFilter.length > 0) {
45
+ addToFlagSets = addToFlagSets.filter(function (flagSet) {
46
+ return _this.flagSetsFilter.some(function (filterFlagSet) { return filterFlagSet === flagSet; });
47
+ });
48
+ }
49
+ var items = [featureFlagName];
50
+ return Promise.all((0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], removeFromFlagSets.map(function (flagSetName) { return _this.wrapper.removeItems(_this.keys.buildFlagSetKey(flagSetName), items); }), true), addToFlagSets.map(function (flagSetName) { return _this.wrapper.addItems(_this.keys.buildFlagSetKey(flagSetName), items); }), true));
51
+ };
38
52
  /**
39
53
  * Add a given split.
40
54
  * The returned promise is resolved when the operation success
@@ -62,7 +76,7 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
62
76
  if (parsedPreviousSplit)
63
77
  return _this._decrementCounts(parsedPreviousSplit);
64
78
  });
65
- });
79
+ }).then(function () { return _this._updateFlagSets(name, parsedPreviousSplit && parsedPreviousSplit.sets, split.sets); });
66
80
  }).then(function () { return true; });
67
81
  };
68
82
  /**
@@ -83,8 +97,9 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
83
97
  var _this = this;
84
98
  return this.getSplit(name).then(function (split) {
85
99
  if (split) {
86
- _this._decrementCounts(split);
100
+ return _this._decrementCounts(split).then(function () { return _this._updateFlagSets(name, split.sets); });
87
101
  }
102
+ }).then(function () {
88
103
  return _this.wrapper.del(_this.keys.buildSplitKey(name));
89
104
  });
90
105
  };
@@ -148,12 +163,14 @@ var SplitsCachePluggable = /** @class */ (function (_super) {
148
163
  /**
149
164
  * Get list of split names related to a given flag set names list.
150
165
  * The returned promise is resolved with the list of split names,
151
- * or rejected if wrapper operation fails.
152
- * @todo this is a no-op method to be implemented
166
+ * or rejected if any wrapper operation fails.
153
167
  */
154
- SplitsCachePluggable.prototype.getNamesByFlagSets = function () {
155
- this.log.error(constants_1.LOG_PREFIX + 'ByFlagSet/s evaluations are not supported with pluggable storage yet.');
156
- return Promise.reject();
168
+ SplitsCachePluggable.prototype.getNamesByFlagSets = function (flagSets) {
169
+ var _this = this;
170
+ return Promise.all(flagSets.map(function (flagSet) {
171
+ var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
172
+ return _this.wrapper.getItems(flagSetKey);
173
+ })).then(function (namesByFlagSets) { return namesByFlagSets.map(function (namesByFlagSet) { return new sets_1._Set(namesByFlagSet); }); });
157
174
  };
158
175
  /**
159
176
  * Check traffic type existence.
@@ -92,7 +92,7 @@ function PluggableStorage(options) {
92
92
  return e; // Propagate error for shared clients
93
93
  });
94
94
  return {
95
- splits: new SplitsCachePluggable_1.SplitsCachePluggable(log, keys, wrapper),
95
+ splits: new SplitsCachePluggable_1.SplitsCachePluggable(log, keys, wrapper, settings.sync.__splitFiltersValidation),
96
96
  segments: new SegmentsCachePluggable_1.SegmentsCachePluggable(log, keys, wrapper),
97
97
  impressions: isPartialConsumer ? new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable_1.ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
98
98
  impressionCounts: impressionCountsCache,
@@ -24,7 +24,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
24
  THE SOFTWARE.
25
25
  **/
26
26
  Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.returnSetsUnion = exports._Set = exports.__getSetConstructor = exports.setToArray = exports.SetPoly = void 0;
27
+ exports.returnListDifference = exports.returnSetsUnion = exports._Set = exports.__getSetConstructor = exports.setToArray = exports.SetPoly = void 0;
28
28
  var SetPoly = /** @class */ (function () {
29
29
  // unlike ES6 `Set`, it only accepts an array as first argument iterable
30
30
  function SetPoly(values) {
@@ -108,3 +108,13 @@ function returnSetsUnion(set, set2) {
108
108
  return result;
109
109
  }
110
110
  exports.returnSetsUnion = returnSetsUnion;
111
+ function returnListDifference(list, list2) {
112
+ if (list === void 0) { list = []; }
113
+ if (list2 === void 0) { list2 = []; }
114
+ var result = new exports._Set(list);
115
+ list2.forEach(function (item) {
116
+ result.delete(item);
117
+ });
118
+ return setToArray(result);
119
+ }
120
+ exports.returnListDifference = returnListDifference;
@@ -179,7 +179,7 @@ function settingsValidation(config, validationParams) {
179
179
  withDefaults.sync.enabled = true;
180
180
  }
181
181
  // validate the `splitFilters` settings and parse splits query
182
- var splitFiltersValidation = (0, splitFilters_1.validateSplitFilters)(log, withDefaults.sync.splitFilters);
182
+ var splitFiltersValidation = (0, splitFilters_1.validateSplitFilters)(log, withDefaults.sync.splitFilters, withDefaults.mode);
183
183
  withDefaults.sync.splitFilters = splitFiltersValidation.validFilters;
184
184
  withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
185
185
  // ensure a valid user consent value
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.flagSetsAreValid = exports.validateSplitFilters = void 0;
4
+ var constants_1 = require("../constants");
4
5
  var splits_1 = require("../inputValidation/splits");
5
- var constants_1 = require("../../logger/constants");
6
+ var constants_2 = require("../../logger/constants");
6
7
  var objectAssign_1 = require("../lang/objectAssign");
7
8
  var lang_1 = require("../lang");
8
9
  // Split filters metadata.
@@ -44,7 +45,7 @@ function validateFilterType(maybeFilterType) {
44
45
  */
45
46
  function validateSplitFilter(log, type, values, maxLength) {
46
47
  // validate and remove invalid and duplicated values
47
- var result = (0, splits_1.validateSplits)(log, values, constants_1.LOG_PREFIX_SETTINGS, type + " filter", type + " filter value");
48
+ var result = (0, splits_1.validateSplits)(log, values, constants_2.LOG_PREFIX_SETTINGS, type + " filter", type + " filter value");
48
49
  if (result) {
49
50
  if (type === 'bySet') {
50
51
  result = sanitizeFlagSets(log, result);
@@ -96,14 +97,14 @@ function sanitizeFlagSets(log, flagSets) {
96
97
  var sanitizedSets = flagSets
97
98
  .map(function (flagSet) {
98
99
  if (CAPITAL_LETTERS_REGEX.test(flagSet)) {
99
- log.warn(constants_1.WARN_SPLITS_FILTER_LOWERCASE_SET, [flagSet]);
100
+ log.warn(constants_2.WARN_SPLITS_FILTER_LOWERCASE_SET, [flagSet]);
100
101
  flagSet = flagSet.toLowerCase();
101
102
  }
102
103
  return flagSet;
103
104
  })
104
105
  .filter(function (flagSet) {
105
106
  if (!VALID_FLAGSET_REGEX.test(flagSet)) {
106
- log.warn(constants_1.WARN_SPLITS_FILTER_INVALID_SET, [flagSet, VALID_FLAGSET_REGEX, flagSet]);
107
+ log.warn(constants_2.WARN_SPLITS_FILTER_INVALID_SET, [flagSet, VALID_FLAGSET_REGEX, flagSet]);
107
108
  return false;
108
109
  }
109
110
  if (typeof flagSet !== 'string')
@@ -120,6 +121,7 @@ function configuredFilter(validFilters, filterType) {
120
121
  *
121
122
  * @param {ILogger} log logger
122
123
  * @param {any} maybeSplitFilters split filters configuration param provided by the user
124
+ * @param {string} mode settings mode
123
125
  * @returns it returns an object with the following properties:
124
126
  * - `validFilters`: the validated `splitFilters` configuration object defined by the user.
125
127
  * - `queryString`: the parsed split filter query. it is null if all filters are invalid or all values in filters are invalid.
@@ -127,7 +129,7 @@ function configuredFilter(validFilters, filterType) {
127
129
  *
128
130
  * @throws Error if the some of the grouped list of values per filter exceeds the max allowed length
129
131
  */
130
- function validateSplitFilters(log, maybeSplitFilters) {
132
+ function validateSplitFilters(log, maybeSplitFilters, mode) {
131
133
  // Validation result schema
132
134
  var res = {
133
135
  validFilters: [],
@@ -137,9 +139,14 @@ function validateSplitFilters(log, maybeSplitFilters) {
137
139
  // do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
138
140
  if (!maybeSplitFilters)
139
141
  return res;
142
+ // Warn depending on the mode
143
+ if (mode === constants_1.CONSUMER_MODE || mode === constants_1.CONSUMER_PARTIAL_MODE) {
144
+ log.warn(constants_2.WARN_SPLITS_FILTER_IGNORED);
145
+ return res;
146
+ }
140
147
  // Check collection type
141
148
  if (!Array.isArray(maybeSplitFilters) || maybeSplitFilters.length === 0) {
142
- log.warn(constants_1.WARN_SPLITS_FILTER_EMPTY);
149
+ log.warn(constants_2.WARN_SPLITS_FILTER_EMPTY);
143
150
  return res;
144
151
  }
145
152
  // Validate filters and group their values by filter type inside `groupedFilters` object
@@ -149,7 +156,7 @@ function validateSplitFilters(log, maybeSplitFilters) {
149
156
  return true;
150
157
  }
151
158
  else {
152
- log.warn(constants_1.WARN_SPLITS_FILTER_INVALID, [index]);
159
+ log.warn(constants_2.WARN_SPLITS_FILTER_INVALID, [index]);
153
160
  }
154
161
  return false;
155
162
  });
@@ -163,12 +170,12 @@ function validateSplitFilters(log, maybeSplitFilters) {
163
170
  // Clean all filters if set filter is present
164
171
  if (setFilter) {
165
172
  if (configuredFilter(res.validFilters, 'byName') || configuredFilter(res.validFilters, 'byPrefix'))
166
- log.error(constants_1.ERROR_SETS_FILTER_EXCLUSIVE);
173
+ log.error(constants_2.ERROR_SETS_FILTER_EXCLUSIVE);
167
174
  (0, objectAssign_1.objectAssign)(res.groupedFilters, { byName: [], byPrefix: [] });
168
175
  }
169
176
  // build query string
170
177
  res.queryString = queryStringBuilder(res.groupedFilters);
171
- log.debug(constants_1.SETTINGS_SPLITS_FILTER, [res.queryString]);
178
+ log.debug(constants_2.SETTINGS_SPLITS_FILTER, [res.queryString]);
172
179
  return res;
173
180
  }
174
181
  exports.validateSplitFilters = validateSplitFilters;
@@ -180,7 +187,7 @@ function flagSetsAreValid(log, method, flagSets, flagSetsInConfig) {
180
187
  if (flagSetsInConfig.indexOf(flagSet) > -1) {
181
188
  return true;
182
189
  }
183
- log.warn(constants_1.WARN_FLAGSET_NOT_CONFIGURED, [method, flagSet]);
190
+ log.warn(constants_2.WARN_FLAGSET_NOT_CONFIGURED, [method, flagSet]);
184
191
  return false;
185
192
  });
186
193
  }
@@ -2,7 +2,8 @@ import { Engine } from './Engine';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import * as LabelsConstants from '../utils/labels';
4
4
  import { CONTROL } from '../utils/constants';
5
- import { setToArray } from '../utils/lang/sets';
5
+ import { setToArray, returnSetsUnion, _Set } from '../utils/lang/sets';
6
+ import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
6
7
  var treatmentException = {
7
8
  treatment: CONTROL,
8
9
  label: LabelsConstants.EXCEPTION,
@@ -50,8 +51,23 @@ export function evaluateFeatures(log, key, splitNames, attributes, storage) {
50
51
  }) :
51
52
  getEvaluations(log, splitNames, parsedSplits, key, attributes, storage);
52
53
  }
53
- export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage) {
54
+ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
54
55
  var storedFlagNames;
56
+ function evaluate(featureFlagsByFlagSets) {
57
+ var featureFlags = new _Set();
58
+ for (var i = 0; i < flagSets.length; i++) {
59
+ var featureFlagByFlagSet = featureFlagsByFlagSets[i];
60
+ if (featureFlagByFlagSet.size) {
61
+ featureFlags = returnSetsUnion(featureFlags, featureFlagByFlagSet);
62
+ }
63
+ else {
64
+ log.warn(WARN_FLAGSET_WITHOUT_FLAGS, [method, flagSets[i]]);
65
+ }
66
+ }
67
+ return featureFlags.size ?
68
+ evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
69
+ {};
70
+ }
55
71
  // get features by flag sets
56
72
  try {
57
73
  storedFlagNames = storage.splits.getNamesByFlagSets(flagSets);
@@ -62,11 +78,11 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
62
78
  }
63
79
  // evaluate related features
64
80
  return thenable(storedFlagNames) ?
65
- storedFlagNames.then(function (splitNames) { return evaluateFeatures(log, key, setToArray(splitNames), attributes, storage); })
81
+ storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
66
82
  .catch(function () {
67
83
  return {};
68
84
  }) :
69
- evaluateFeatures(log, key, setToArray(storedFlagNames), attributes, storage);
85
+ evaluate(storedFlagNames);
70
86
  }
71
87
  function getEvaluation(log, splitJSON, key, attributes, storage) {
72
88
  var evaluation = {
@@ -89,6 +89,7 @@ export var WARN_NOT_EXISTENT_SPLIT = 215;
89
89
  export var WARN_LOWERCASE_TRAFFIC_TYPE = 216;
90
90
  export var WARN_NOT_EXISTENT_TT = 217;
91
91
  export var WARN_INTEGRATION_INVALID = 218;
92
+ export var WARN_SPLITS_FILTER_IGNORED = 219;
92
93
  export var WARN_SPLITS_FILTER_INVALID = 220;
93
94
  export var WARN_SPLITS_FILTER_EMPTY = 221;
94
95
  export var WARN_SDK_KEY = 222;
@@ -97,6 +98,7 @@ export var STREAMING_PARSING_SPLIT_UPDATE = 224;
97
98
  export var WARN_SPLITS_FILTER_INVALID_SET = 225;
98
99
  export var WARN_SPLITS_FILTER_LOWERCASE_SET = 226;
99
100
  export var WARN_FLAGSET_NOT_CONFIGURED = 227;
101
+ export var WARN_FLAGSET_WITHOUT_FLAGS = 228;
100
102
  export var ERROR_ENGINE_COMBINER_IFELSEIF = 300;
101
103
  export var ERROR_LOGLEVEL_INVALID = 301;
102
104
  export var ERROR_CLIENT_LISTENER = 302;
@@ -23,9 +23,10 @@ export var codesWarn = codesError.concat([
23
23
  [c.WARN_NOT_EXISTENT_SPLIT, '%s: feature flag "%s" does not exist in this environment. Please double check what feature flags exist in the Split user interface.'],
24
24
  [c.WARN_LOWERCASE_TRAFFIC_TYPE, '%s: traffic_type_name should be all lowercase - converting string to lowercase.'],
25
25
  [c.WARN_NOT_EXISTENT_TT, '%s: traffic type "%s" does not have any corresponding feature flag in this environment, make sure you\'re tracking your events to a valid traffic type defined in the Split user interface.'],
26
- [c.WARN_FLAGSET_NOT_CONFIGURED, '%s: : you passed %s wich is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
26
+ [c.WARN_FLAGSET_NOT_CONFIGURED, '%s: you passed %s which is not part of the configured FlagSetsFilter, ignoring Flag Set.'],
27
27
  // initialization / settings validation
28
28
  [c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS + ': %s integration item(s) at settings is invalid. %s'],
29
+ [c.WARN_SPLITS_FILTER_IGNORED, c.LOG_PREFIX_SETTINGS + ': feature flag filters are not applicable for Consumer modes where the SDK does not keep rollout data in sync. Filters were discarded'],
29
30
  [c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ': feature flag filter at position %s is invalid. It must be an object with a valid filter type ("bySet", "byName" or "byPrefix") and a list of "values".'],
30
31
  [c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
31
32
  [c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
@@ -33,4 +34,5 @@ export var codesWarn = codesError.concat([
33
34
  [c.STREAMING_PARSING_SPLIT_UPDATE, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching SplitChanges due to an error processing SPLIT_UPDATE notification: %s'],
34
35
  [c.WARN_SPLITS_FILTER_INVALID_SET, c.LOG_PREFIX_SETTINGS + ': you passed %s, flag set must adhere to the regular expressions %s. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.'],
35
36
  [c.WARN_SPLITS_FILTER_LOWERCASE_SET, c.LOG_PREFIX_SETTINGS + ': flag set %s should be all lowercase - converting string to lowercase.'],
37
+ [c.WARN_FLAGSET_WITHOUT_FLAGS, '%s: you passed %s flag set that does not contain cached feature flag names. Please double check what flag sets are in use in the Split user interface.'],
36
38
  ]);
@@ -80,7 +80,7 @@ export function clientFactory(params) {
80
80
  return treatments;
81
81
  };
82
82
  var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
83
- evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage) :
83
+ evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, method) :
84
84
  isStorageSync(settings) ? {} : Promise.resolve({}); // Promisify if async
85
85
  return thenable(evaluations) ? evaluations.then(function (res) { return wrapUp(res); }) : wrapUp(evaluations);
86
86
  }
@@ -2,7 +2,7 @@ import { __extends } from "tslib";
2
2
  import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSync';
3
3
  import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
4
4
  import { LOG_PREFIX } from './constants';
5
- import { _Set, returnSetsUnion, setToArray } from '../../utils/lang/sets';
5
+ import { _Set, setToArray } from '../../utils/lang/sets';
6
6
  /**
7
7
  * ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
8
8
  */
@@ -228,16 +228,11 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
228
228
  };
229
229
  SplitsCacheInLocal.prototype.getNamesByFlagSets = function (flagSets) {
230
230
  var _this = this;
231
- var toReturn = new _Set([]);
232
- flagSets.forEach(function (flagSet) {
231
+ return flagSets.map(function (flagSet) {
233
232
  var flagSetKey = _this.keys.buildFlagSetKey(flagSet);
234
233
  var flagSetFromLocalStorage = localStorage.getItem(flagSetKey);
235
- if (flagSetFromLocalStorage) {
236
- var flagSetCache = new _Set(JSON.parse(flagSetFromLocalStorage));
237
- toReturn = returnSetsUnion(toReturn, flagSetCache);
238
- }
234
+ return new _Set(flagSetFromLocalStorage ? JSON.parse(flagSetFromLocalStorage) : []);
239
235
  });
240
- return toReturn;
241
236
  };
242
237
  SplitsCacheInLocal.prototype.addToFlagSets = function (featureFlag) {
243
238
  var _this = this;
@@ -1,7 +1,7 @@
1
1
  import { __extends } from "tslib";
2
2
  import { AbstractSplitsCacheSync, usesSegments } from '../AbstractSplitsCacheSync';
3
3
  import { isFiniteNumber } from '../../utils/lang';
4
- import { _Set, returnSetsUnion } from '../../utils/lang/sets';
4
+ import { _Set } from '../../utils/lang/sets';
5
5
  /**
6
6
  * Default ISplitsCacheSync implementation that stores split definitions in memory.
7
7
  * Supported by all JS runtimes.
@@ -9,14 +9,13 @@ import { _Set, returnSetsUnion } from '../../utils/lang/sets';
9
9
  var SplitsCacheInMemory = /** @class */ (function (_super) {
10
10
  __extends(SplitsCacheInMemory, _super);
11
11
  function SplitsCacheInMemory(splitFiltersValidation) {
12
- if (splitFiltersValidation === void 0) { splitFiltersValidation = { queryString: null, groupedFilters: { bySet: [], byName: [], byPrefix: [] }, validFilters: [] }; }
13
12
  var _this = _super.call(this) || this;
14
13
  _this.splitsCache = {};
15
14
  _this.ttCache = {};
16
15
  _this.changeNumber = -1;
17
16
  _this.splitsWithSegmentsCount = 0;
18
17
  _this.flagSetsCache = {};
19
- _this.flagSetsFilter = splitFiltersValidation.groupedFilters.bySet;
18
+ _this.flagSetsFilter = splitFiltersValidation ? splitFiltersValidation.groupedFilters.bySet : [];
20
19
  return _this;
21
20
  }
22
21
  SplitsCacheInMemory.prototype.clear = function () {
@@ -93,14 +92,7 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
93
92
  };
94
93
  SplitsCacheInMemory.prototype.getNamesByFlagSets = function (flagSets) {
95
94
  var _this = this;
96
- var toReturn = new _Set([]);
97
- flagSets.forEach(function (flagSet) {
98
- var featureFlagNames = _this.flagSetsCache[flagSet];
99
- if (featureFlagNames) {
100
- toReturn = returnSetsUnion(toReturn, featureFlagNames);
101
- }
102
- });
103
- return toReturn;
95
+ return flagSets.map(function (flagSet) { return _this.flagSetsCache[flagSet] || new _Set(); });
104
96
  };
105
97
  SplitsCacheInMemory.prototype.addToFlagSets = function (featureFlag) {
106
98
  var _this = this;