@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.
- package/CHANGES.txt +4 -0
- package/cjs/evaluator/index.js +19 -3
- package/cjs/logger/constants.js +4 -2
- package/cjs/logger/messages/warn.js +3 -1
- package/cjs/sdkClient/client.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +2 -7
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -10
- package/cjs/storages/pluggable/SplitsCachePluggable.js +25 -8
- package/cjs/storages/pluggable/index.js +1 -1
- package/cjs/utils/lang/sets.js +11 -1
- package/cjs/utils/settingsValidation/index.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +17 -10
- package/esm/evaluator/index.js +20 -4
- package/esm/logger/constants.js +2 -0
- package/esm/logger/messages/warn.js +3 -1
- package/esm/sdkClient/client.js +1 -1
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +3 -8
- package/esm/storages/inMemory/SplitsCacheInMemory.js +3 -11
- package/esm/storages/pluggable/SplitsCachePluggable.js +26 -9
- package/esm/storages/pluggable/index.js +1 -1
- package/esm/utils/lang/sets.js +9 -0
- package/esm/utils/settingsValidation/index.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +9 -2
- package/package.json +2 -2
- package/src/evaluator/index.ts +24 -4
- package/src/logger/constants.ts +2 -0
- package/src/logger/messages/warn.ts +9 -7
- package/src/sdkClient/client.ts +1 -1
- package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +4 -10
- package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
- package/src/storages/inRedis/SplitsCacheInRedis.ts +1 -1
- package/src/storages/pluggable/SplitsCachePluggable.ts +32 -10
- package/src/storages/pluggable/index.ts +1 -1
- package/src/storages/types.ts +5 -5
- package/src/types.ts +0 -2
- package/src/utils/lang/sets.ts +9 -1
- package/src/utils/settingsValidation/index.ts +1 -1
- package/src/utils/settingsValidation/splitFilters.ts +13 -6
- package/types/evaluator/index.d.ts +1 -1
- package/types/logger/constants.d.ts +2 -0
- package/types/sdkClient/identity.d.ts +6 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -1
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +7 -6
- package/types/storages/types.d.ts +5 -5
- package/types/types.d.ts +0 -2
- package/types/utils/inputValidation/sdkKey.d.ts +7 -0
- package/types/utils/lang/sets.d.ts +1 -0
- package/types/utils/settingsValidation/splitFilters.d.ts +2 -1
- package/types/myLogger.d.ts +0 -5
- package/types/sdkClient/types.d.ts +0 -18
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +0 -20
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +0 -20
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +0 -9
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +0 -9
- package/types/storages/metadataBuilder.d.ts +0 -3
- package/types/sync/offline/LocalhostFromFile.d.ts +0 -2
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +0 -2
- package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
- package/types/sync/submitters/eventsSyncTask.d.ts +0 -8
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +0 -5
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +0 -13
- package/types/sync/submitters/impressionsSyncTask.d.ts +0 -14
- package/types/sync/submitters/metricsSyncTask.d.ts +0 -12
- package/types/sync/submitters/submitterSyncTask.d.ts +0 -10
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +0 -5
- package/types/sync/syncTaskComposite.d.ts +0 -5
- package/types/trackers/filter/bloomFilter.d.ts +0 -10
- package/types/trackers/filter/dictionaryFilter.d.ts +0 -8
- package/types/trackers/filter/types.d.ts +0 -5
- package/types/utils/timeTracker/index.d.ts +0 -70
- /package/types/storages/inMemory/{uniqueKeysCacheInMemory.d.ts → UniqueKeysCacheInMemory.d.ts} +0 -0
- /package/types/storages/inMemory/{uniqueKeysCacheInMemoryCS.d.ts → UniqueKeysCacheInMemoryCS.d.ts} +0 -0
- /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.
|
package/cjs/evaluator/index.js
CHANGED
|
@@ -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 (
|
|
87
|
+
storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
|
|
72
88
|
.catch(function () {
|
|
73
89
|
return {};
|
|
74
90
|
}) :
|
|
75
|
-
|
|
91
|
+
evaluate(storedFlagNames);
|
|
76
92
|
}
|
|
77
93
|
exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
|
|
78
94
|
function getEvaluation(log, splitJSON, key, attributes, storage) {
|
package/cjs/logger/constants.js
CHANGED
|
@@ -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.
|
|
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:
|
|
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
|
]);
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
156
|
-
return Promise.
|
|
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,
|
package/cjs/utils/lang/sets.js
CHANGED
|
@@ -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
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
190
|
+
log.warn(constants_2.WARN_FLAGSET_NOT_CONFIGURED, [method, flagSet]);
|
|
184
191
|
return false;
|
|
185
192
|
});
|
|
186
193
|
}
|
package/esm/evaluator/index.js
CHANGED
|
@@ -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 (
|
|
81
|
+
storedFlagNames.then(function (storedFlagNames) { return evaluate(storedFlagNames); })
|
|
66
82
|
.catch(function () {
|
|
67
83
|
return {};
|
|
68
84
|
}) :
|
|
69
|
-
|
|
85
|
+
evaluate(storedFlagNames);
|
|
70
86
|
}
|
|
71
87
|
function getEvaluation(log, splitJSON, key, attributes, storage) {
|
|
72
88
|
var evaluation = {
|
package/esm/logger/constants.js
CHANGED
|
@@ -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:
|
|
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
|
]);
|
package/esm/sdkClient/client.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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;
|