@splitsoftware/splitio-commons 2.12.0 → 3.0.0-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 +14 -1
- package/cjs/evaluator/condition/engineUtils.js +2 -2
- package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
- package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
- package/cjs/evaluator/index.js +67 -42
- package/cjs/evaluator/matchers/whitelist.js +1 -1
- package/cjs/integrations/pluggable.js +1 -1
- package/cjs/listeners/browser.js +4 -3
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +14 -20
- package/cjs/logger/index.js +1 -1
- package/cjs/logger/messages/debug.js +6 -7
- package/cjs/logger/messages/error.js +4 -4
- package/cjs/logger/messages/info.js +2 -4
- package/cjs/logger/messages/warn.js +9 -9
- package/cjs/platform/browser.js +15 -0
- package/cjs/platform/getEventSource/browser.js +8 -0
- package/cjs/platform/getEventSource/eventsource.js +480 -0
- package/cjs/platform/getEventSource/node.js +26 -0
- package/cjs/platform/getFetch/browser.js +9 -0
- package/cjs/platform/getFetch/node.js +27 -0
- package/cjs/platform/getOptions/node.js +25 -0
- package/cjs/platform/node.js +17 -0
- package/cjs/readiness/constants.js +2 -1
- package/cjs/sdkClient/client.js +9 -35
- package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
- package/cjs/sdkClient/clientInputValidation.js +38 -81
- package/cjs/sdkClient/identity.js +1 -1
- package/cjs/sdkClient/sdkClient.js +4 -49
- package/cjs/sdkClient/sdkLifecycle.js +70 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +8 -45
- package/cjs/sdkManager/index.js +3 -3
- package/cjs/services/splitApi.js +18 -13
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/KeyBuilder.js +12 -12
- package/cjs/storages/KeyBuilderCS.js +13 -13
- package/cjs/storages/KeyBuilderSS.js +15 -15
- package/cjs/storages/getRolloutPlan.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -8
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -6
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
- package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +4 -4
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
- package/cjs/storages/pluggable/index.js +3 -3
- package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
- package/cjs/storages/setRolloutPlan.js +1 -1
- package/cjs/storages/utils.js +6 -6
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +23 -14
- package/cjs/sync/polling/pollingManagerCS.js +11 -11
- package/cjs/sync/polling/pollingManagerSS.js +13 -13
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
- package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/cjs/sync/streaming/parseUtils.js +12 -12
- package/cjs/sync/streaming/pushManager.js +2 -2
- package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
- package/cjs/sync/submitters/submitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +5 -2
- package/cjs/trackers/eventTracker.js +10 -12
- package/cjs/trackers/impressionObserver/buildKey.js +1 -1
- package/cjs/trackers/impressionsTracker.js +37 -20
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/EventEmitter.js +391 -0
- package/cjs/utils/filter/bloomFilter.js +37 -0
- package/cjs/utils/inputValidation/apiKey.js +1 -1
- package/cjs/utils/inputValidation/attribute.js +2 -2
- package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
- package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
- package/cjs/utils/inputValidation/definitions.js +25 -0
- package/cjs/utils/inputValidation/eventProperties.js +1 -1
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/target.js +22 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/lang/index.js +1 -1
- package/cjs/utils/promise/timeout.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +4 -4
- package/cjs/utils/settingsValidation/url.js +5 -5
- package/esm/evaluator/condition/engineUtils.js +2 -2
- package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
- package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
- package/esm/evaluator/index.js +66 -42
- package/esm/evaluator/matchers/whitelist.js +1 -1
- package/esm/integrations/pluggable.js +1 -1
- package/esm/listeners/browser.js +4 -3
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +11 -17
- package/esm/logger/index.js +1 -1
- package/esm/logger/messages/debug.js +5 -6
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +1 -3
- package/esm/logger/messages/warn.js +8 -8
- package/esm/platform/browser.js +12 -0
- package/esm/platform/getEventSource/browser.js +4 -0
- package/esm/platform/getEventSource/eventsource.js +480 -0
- package/esm/platform/getEventSource/node.js +20 -0
- package/esm/platform/getFetch/browser.js +5 -0
- package/esm/platform/getFetch/node.js +22 -0
- package/esm/platform/getOptions/node.js +20 -0
- package/esm/platform/node.js +14 -0
- package/esm/readiness/constants.js +1 -0
- package/esm/sdkClient/client.js +10 -37
- package/esm/sdkClient/clientAttributesDecoration.js +3 -3
- package/esm/sdkClient/clientInputValidation.js +40 -83
- package/esm/sdkClient/identity.js +1 -1
- package/esm/sdkClient/sdkClient.js +4 -49
- package/esm/sdkClient/sdkLifecycle.js +66 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +8 -45
- package/esm/sdkManager/index.js +4 -4
- package/esm/services/splitApi.js +18 -13
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/KeyBuilder.js +12 -12
- package/esm/storages/KeyBuilderCS.js +12 -12
- package/esm/storages/KeyBuilderSS.js +14 -14
- package/esm/storages/getRolloutPlan.js +1 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +7 -7
- package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
- package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/pluggable/wrapperAdapter.js +1 -1
- package/esm/storages/setRolloutPlan.js +1 -1
- package/esm/storages/utils.js +6 -6
- package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/esm/sync/polling/pollingManagerCS.js +11 -11
- package/esm/sync/polling/pollingManagerSS.js +13 -13
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
- package/esm/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/esm/sync/streaming/parseUtils.js +10 -10
- package/esm/sync/streaming/pushManager.js +3 -3
- package/esm/sync/submitters/impressionsSubmitter.js +6 -6
- package/esm/sync/submitters/submitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +5 -2
- package/esm/trackers/eventTracker.js +10 -12
- package/esm/trackers/impressionObserver/buildKey.js +1 -1
- package/esm/trackers/impressionsTracker.js +38 -21
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/EventEmitter.js +387 -0
- package/esm/utils/filter/bloomFilter.js +33 -0
- package/esm/utils/inputValidation/apiKey.js +1 -1
- package/esm/utils/inputValidation/attribute.js +2 -2
- package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
- package/esm/utils/inputValidation/definitionExistence.js +15 -0
- package/esm/utils/inputValidation/definitions.js +21 -0
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/target.js +18 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/promise/timeout.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +4 -4
- package/esm/utils/settingsValidation/url.js +5 -5
- package/package.json +15 -6
- package/src/dtos/types.ts +65 -70
- package/src/evaluator/Engine.ts +4 -4
- package/src/evaluator/combiners/and.ts +3 -3
- package/src/evaluator/combiners/ifelseif.ts +2 -2
- package/src/evaluator/condition/engineUtils.ts +2 -2
- package/src/evaluator/condition/index.ts +3 -3
- package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
- package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
- package/src/evaluator/index.ts +80 -45
- package/src/evaluator/matchers/dependency.ts +2 -2
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchers/prerequisites.ts +4 -4
- package/src/evaluator/matchers/rbsegment.ts +2 -2
- package/src/evaluator/matchers/whitelist.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +2 -2
- package/src/evaluator/matchersTransform/whitelist.ts +2 -2
- package/src/evaluator/parser/index.ts +4 -4
- package/src/evaluator/treatments/index.ts +2 -2
- package/src/evaluator/types.ts +6 -6
- package/src/evaluator/value/index.ts +1 -1
- package/src/integrations/pluggable.ts +1 -1
- package/src/listeners/browser.ts +11 -8
- package/src/listeners/node.ts +2 -5
- package/src/logger/constants.ts +11 -17
- package/src/logger/messages/debug.ts +5 -6
- package/src/logger/messages/error.ts +3 -3
- package/src/logger/messages/info.ts +1 -3
- package/src/logger/messages/warn.ts +8 -8
- package/src/platform/browser.ts +14 -0
- package/src/platform/getEventSource/browser.ts +4 -0
- package/src/platform/getEventSource/eventsource.js +519 -0
- package/src/platform/getEventSource/node.ts +23 -0
- package/src/platform/getFetch/browser.ts +5 -0
- package/src/platform/getFetch/node.ts +27 -0
- package/src/platform/getOptions/node.ts +24 -0
- package/src/platform/node.ts +16 -0
- package/src/readiness/constants.ts +1 -0
- package/src/sdkClient/client.ts +11 -41
- package/src/sdkClient/clientInputValidation.ts +44 -84
- package/src/sdkClient/sdkClient.ts +5 -54
- package/src/sdkClient/sdkLifecycle.ts +78 -0
- package/src/sdkClient/trackMethod.ts +59 -0
- package/src/sdkFactory/index.ts +10 -54
- package/src/sdkFactory/types.ts +19 -16
- package/src/sdkManager/index.ts +9 -9
- package/src/services/splitApi.ts +6 -0
- package/src/services/types.ts +3 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +7 -7
- package/src/storages/AbstractSplitsCacheSync.ts +10 -10
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +2 -2
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -6
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/SplitsCacheInMemory.ts +5 -5
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +2 -2
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/SplitsCacheInRedis.ts +9 -9
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/SplitsCachePluggable.ts +9 -9
- package/src/storages/types.ts +21 -16
- package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
- package/src/sync/offline/splitsParser/types.ts +6 -3
- package/src/sync/offline/syncManagerOffline.ts +2 -2
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -6
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +57 -22
- package/src/sync/polling/fetchers/types.ts +5 -3
- package/src/sync/polling/pollingManagerCS.ts +12 -10
- package/src/sync/polling/pollingManagerSS.ts +15 -13
- package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +10 -11
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/{splitChangesUpdater.ts → definitionChangesUpdater.ts} +77 -68
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +6 -6
- package/src/sync/streaming/parseUtils.ts +12 -12
- package/src/sync/streaming/pushManager.ts +3 -3
- package/src/sync/submitters/impressionsSubmitter.ts +9 -9
- package/src/sync/submitters/types.ts +3 -0
- package/src/sync/syncManagerOnline.ts +6 -2
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +42 -26
- package/src/trackers/types.ts +3 -1
- package/src/utils/EventEmitter.js +444 -0
- package/src/utils/filter/bloomFilter.ts +38 -0
- package/src/utils/inputValidation/definition.ts +27 -0
- package/src/utils/inputValidation/definitionExistence.ts +19 -0
- package/src/utils/inputValidation/definitions.ts +21 -0
- package/src/utils/inputValidation/index.ts +3 -3
- package/src/utils/inputValidation/isOperational.ts +4 -4
- package/src/utils/inputValidation/target.ts +21 -0
- package/src/utils/labels/index.ts +2 -2
- package/src/utils/settingsValidation/splitFilters.ts +3 -3
- package/types/splitio.d.ts +202 -9
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/utils/inputValidation/split.ts +0 -27
- package/src/utils/inputValidation/splitExistence.ts +0 -19
- package/src/utils/inputValidation/splits.ts +0 -21
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
|
-
import { SDK_SPLITS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
3
|
-
import {
|
|
2
|
+
import { SDK_SPLITS_ARRIVED, FLAGS_UPDATE, SEGMENTS_UPDATE, CONFIGS_UPDATE } from '../../../readiness/constants';
|
|
3
|
+
import { SYNC_FETCH, SYNC_UPDATE, SYNC_FETCH_FAILS, SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
4
|
import { startsWith } from '../../../utils/lang';
|
|
5
5
|
import { IN_RULE_BASED_SEGMENT, IN_SEGMENT, RULE_BASED_SEGMENT, STANDARD_SEGMENT } from '../../../utils/constants';
|
|
6
6
|
import { setToArray } from '../../../utils/lang/sets';
|
|
@@ -21,7 +21,7 @@ function checkAllSegmentsExist(segments) {
|
|
|
21
21
|
*/
|
|
22
22
|
export function parseSegments(ruleEntity, matcherType) {
|
|
23
23
|
if (matcherType === void 0) { matcherType = IN_SEGMENT; }
|
|
24
|
-
var _a = ruleEntity,
|
|
24
|
+
var _a = ruleEntity, conditions = _a.conditions, excluded = _a.excluded;
|
|
25
25
|
var segments = new Set();
|
|
26
26
|
if (excluded && excluded.segments) {
|
|
27
27
|
excluded.segments.forEach(function (_a) {
|
|
@@ -31,120 +31,128 @@ export function parseSegments(ruleEntity, matcherType) {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
var
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
if (conditions) {
|
|
35
|
+
for (var i = 0; i < conditions.length; i++) {
|
|
36
|
+
var matchers = conditions[i].matcherGroup.matchers;
|
|
37
|
+
matchers.forEach(function (matcher) {
|
|
38
|
+
if (matcher.matcherType === matcherType)
|
|
39
|
+
segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
43
|
return segments;
|
|
42
44
|
}
|
|
43
45
|
/**
|
|
44
|
-
* If there are defined filters and one
|
|
46
|
+
* If there are defined filters and one definition doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
|
|
45
47
|
* If there is `bySet` filter, `byName` and `byPrefix` filters are ignored
|
|
46
48
|
*
|
|
47
|
-
* @param
|
|
49
|
+
* @param definition - definition to be evaluated
|
|
48
50
|
* @param filters - splitFiltersValidation bySet | byName
|
|
49
51
|
*/
|
|
50
|
-
function matchFilters(
|
|
52
|
+
function matchFilters(definition, filters) {
|
|
51
53
|
var _a = filters.groupedFilters, setsFilter = _a.bySet, namesFilter = _a.byName, prefixFilter = _a.byPrefix;
|
|
52
54
|
if (setsFilter.length > 0)
|
|
53
|
-
return
|
|
55
|
+
return definition.sets && definition.sets.some(function (definitionSet) { return setsFilter.indexOf(definitionSet) > -1; });
|
|
54
56
|
var namesFilterConfigured = namesFilter.length > 0;
|
|
55
57
|
var prefixFilterConfigured = prefixFilter.length > 0;
|
|
56
58
|
if (!namesFilterConfigured && !prefixFilterConfigured)
|
|
57
59
|
return true;
|
|
58
|
-
var matchNames = namesFilterConfigured && namesFilter.indexOf(
|
|
59
|
-
var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return startsWith(
|
|
60
|
+
var matchNames = namesFilterConfigured && namesFilter.indexOf(definition.name) > -1;
|
|
61
|
+
var matchPrefix = prefixFilterConfigured && prefixFilter.some(function (prefix) { return startsWith(definition.name, prefix); });
|
|
60
62
|
return matchNames || matchPrefix;
|
|
61
63
|
}
|
|
62
64
|
/**
|
|
63
|
-
* Given the list of
|
|
64
|
-
* i.e., an object with added
|
|
65
|
+
* Given the list of definitions from /splitChanges or /configs endpoint, it returns the mutations,
|
|
66
|
+
* i.e., an object with added definitions, removed definitions, and used segments.
|
|
65
67
|
* Exported for testing purposes.
|
|
66
68
|
*/
|
|
67
|
-
export function computeMutation(
|
|
68
|
-
return
|
|
69
|
-
if (
|
|
69
|
+
export function computeMutation(update, segments, filters) {
|
|
70
|
+
return update.updated.reduce(function (accum, ruleEntity) {
|
|
71
|
+
if (!filters || matchFilters(ruleEntity, filters)) {
|
|
70
72
|
accum.added.push(ruleEntity);
|
|
71
73
|
parseSegments(ruleEntity).forEach(function (segmentName) {
|
|
72
74
|
segments.add(segmentName);
|
|
73
75
|
});
|
|
74
76
|
}
|
|
75
77
|
else {
|
|
76
|
-
accum.removed.push(ruleEntity);
|
|
78
|
+
accum.removed.push(ruleEntity.name);
|
|
77
79
|
}
|
|
78
80
|
accum.names.push(ruleEntity.name);
|
|
79
81
|
return accum;
|
|
80
|
-
}, { added: [], removed:
|
|
82
|
+
}, { added: [], removed: update.removed, names: update.removed.slice() });
|
|
83
|
+
}
|
|
84
|
+
function convertInstantUpdateToDefinitionChanges(instantUpdate) {
|
|
85
|
+
var payload = instantUpdate.payload, changeNumber = instantUpdate.changeNumber;
|
|
86
|
+
return payload.status === 'ARCHIVED' ?
|
|
87
|
+
{ till: changeNumber, updated: [], removed: [payload.name] } :
|
|
88
|
+
{ till: changeNumber, updated: [payload], removed: [] };
|
|
81
89
|
}
|
|
82
90
|
/**
|
|
83
|
-
*
|
|
84
|
-
* - fetches
|
|
85
|
-
* - updates
|
|
86
|
-
* - uses `
|
|
91
|
+
* Factory of DefinitionChanges updater, a task that:
|
|
92
|
+
* - fetches definition changes using `definitionChangesFetcher`
|
|
93
|
+
* - updates definitions storage
|
|
94
|
+
* - uses `definitionsEventEmitter` to emit events related to definition data updates
|
|
87
95
|
*
|
|
88
96
|
* @param log - Logger instance
|
|
89
|
-
* @param
|
|
90
|
-
* @param
|
|
97
|
+
* @param definitionChangesFetcher - Fetcher of `/splitChanges` or `/configs`
|
|
98
|
+
* @param definitions - Definitions storage, with sync or async methods
|
|
91
99
|
* @param segments - Segments storage, with sync or async methods
|
|
92
|
-
* @param
|
|
100
|
+
* @param definitionsEventEmitter - Optional readiness manager. Not required for synchronizer or producer mode.
|
|
93
101
|
* @param requestTimeoutBeforeReady - How long the updater will wait for the request to timeout. Default 0, i.e., never timeout.
|
|
94
|
-
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
|
|
102
|
+
* @param retriesOnFailureBeforeReady - How many retries on `/splitChanges` or `/configs` we the updater do in case of failure or timeout. Default 0, i.e., no retries.
|
|
95
103
|
*/
|
|
96
|
-
export function
|
|
104
|
+
export function definitionChangesUpdaterFactory(log, definitionChangesFetcher, storage, splitFiltersValidation, splitsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, isClientSide) {
|
|
97
105
|
if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
|
|
98
106
|
if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
|
|
99
107
|
var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments;
|
|
100
108
|
var startingUp = true;
|
|
101
|
-
/** timeout decorator for `
|
|
109
|
+
/** timeout decorator for `definitionChangesFetcher` promise */
|
|
102
110
|
function _promiseDecorator(promise) {
|
|
103
111
|
if (startingUp && requestTimeoutBeforeReady)
|
|
104
112
|
promise = timeout(requestTimeoutBeforeReady, promise);
|
|
105
113
|
return promise;
|
|
106
114
|
}
|
|
107
115
|
/**
|
|
108
|
-
*
|
|
116
|
+
* DefinitionChanges updater returns a promise that resolves with a `false` boolean value if it fails to fetch definitions or synchronize them with the storage.
|
|
109
117
|
* Returned promise will not be rejected.
|
|
110
118
|
*
|
|
111
119
|
* @param noCache - true to revalidate data to fetch
|
|
112
120
|
* @param till - query param to bypass CDN requests
|
|
113
121
|
*/
|
|
114
|
-
return function
|
|
122
|
+
return function definitionChangesUpdater(noCache, till, instantUpdate) {
|
|
115
123
|
/**
|
|
116
|
-
* @param since - current changeNumber at
|
|
124
|
+
* @param since - current changeNumber at definitionsCache
|
|
117
125
|
* @param retry - current number of retry attempts
|
|
118
126
|
*/
|
|
119
|
-
function
|
|
127
|
+
function _definitionChangesUpdater(sinces, retry) {
|
|
120
128
|
if (retry === void 0) { retry = 0; }
|
|
121
129
|
var since = sinces[0], rbSince = sinces[1];
|
|
122
|
-
log.debug(
|
|
130
|
+
log.debug(SYNC_FETCH, [definitionChangesFetcher.type, since, rbSince]);
|
|
123
131
|
return Promise.resolve(instantUpdate ?
|
|
124
132
|
instantUpdate.type === SPLIT_UPDATE ?
|
|
125
|
-
// IFFU edge case: a change to
|
|
133
|
+
// IFFU edge case: a change to definition that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
|
|
126
134
|
Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, IN_RULE_BASED_SEGMENT))).then(function (contains) {
|
|
127
135
|
return contains ?
|
|
128
|
-
{
|
|
129
|
-
|
|
136
|
+
{ d: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
137
|
+
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
|
|
130
138
|
}) :
|
|
131
|
-
{ rbs:
|
|
132
|
-
|
|
133
|
-
.then(function (
|
|
139
|
+
{ rbs: convertInstantUpdateToDefinitionChanges(instantUpdate) } :
|
|
140
|
+
definitionChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
|
|
141
|
+
.then(function (definitionChanges) {
|
|
134
142
|
var usedSegments = new Set();
|
|
135
|
-
var
|
|
143
|
+
var updatedDefinitions = [];
|
|
136
144
|
var ffUpdate = false;
|
|
137
|
-
if (
|
|
138
|
-
var _a = computeMutation(
|
|
139
|
-
|
|
140
|
-
log.debug(
|
|
141
|
-
ffUpdate = splits.update(added, removed,
|
|
145
|
+
if (definitionChanges.d) {
|
|
146
|
+
var _a = computeMutation(definitionChanges.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed, names = _a.names;
|
|
147
|
+
updatedDefinitions = names;
|
|
148
|
+
log.debug(SYNC_UPDATE, [definitionChangesFetcher.type, added.length, removed.length]);
|
|
149
|
+
ffUpdate = splits.update(added, removed, definitionChanges.d.till);
|
|
142
150
|
}
|
|
143
151
|
var rbsUpdate = false;
|
|
144
|
-
if (
|
|
145
|
-
var _b = computeMutation(
|
|
146
|
-
log.debug(
|
|
147
|
-
rbsUpdate = rbSegments.update(added, removed,
|
|
152
|
+
if (definitionChanges.rbs) {
|
|
153
|
+
var _b = computeMutation(definitionChanges.rbs, usedSegments), added = _b.added, removed = _b.removed;
|
|
154
|
+
log.debug(SYNC_UPDATE, ['rule-based segments', added.length, removed.length]);
|
|
155
|
+
rbsUpdate = rbSegments.update(added, removed, definitionChanges.rbs.till);
|
|
148
156
|
}
|
|
149
157
|
return Promise.all([ffUpdate, rbsUpdate,
|
|
150
158
|
// @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
|
|
@@ -162,8 +170,8 @@ export function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, sp
|
|
|
162
170
|
// emit SDK events
|
|
163
171
|
if (emitSplitsArrivedEvent) {
|
|
164
172
|
var metadata = {
|
|
165
|
-
type:
|
|
166
|
-
names:
|
|
173
|
+
type: updatedDefinitions.length > 0 ? definitionChangesFetcher.type === 'configs' ? CONFIGS_UPDATE : FLAGS_UPDATE : SEGMENTS_UPDATE,
|
|
174
|
+
names: updatedDefinitions.length > 0 ? updatedDefinitions : []
|
|
167
175
|
};
|
|
168
176
|
splitsEventEmitter.emit(SDK_SPLITS_ARRIVED, metadata);
|
|
169
177
|
}
|
|
@@ -176,17 +184,17 @@ export function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, sp
|
|
|
176
184
|
.catch(function (error) {
|
|
177
185
|
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
178
186
|
retry += 1;
|
|
179
|
-
log.warn(
|
|
180
|
-
return
|
|
187
|
+
log.warn(SYNC_FETCH_RETRY, [definitionChangesFetcher.type, retry, error]);
|
|
188
|
+
return _definitionChangesUpdater(sinces, retry);
|
|
181
189
|
}
|
|
182
190
|
else {
|
|
183
191
|
startingUp = false;
|
|
184
|
-
log.warn(
|
|
192
|
+
log.warn(SYNC_FETCH_FAILS, [definitionChangesFetcher.type, error]);
|
|
185
193
|
}
|
|
186
194
|
return false;
|
|
187
195
|
});
|
|
188
196
|
}
|
|
189
197
|
// `getChangeNumber` never rejects or throws error
|
|
190
|
-
return Promise.all([splits.getChangeNumber(), rbSegments.getChangeNumber()]).then(
|
|
198
|
+
return Promise.all([splits.getChangeNumber(), rbSegments.getChangeNumber()]).then(_definitionChangesUpdater);
|
|
191
199
|
};
|
|
192
200
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
2
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
3
|
-
import {
|
|
3
|
+
import { SYNC_FETCH_RETRY } from '../../../logger/constants';
|
|
4
4
|
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
5
5
|
import { usesSegmentsSync } from '../../../storages/AbstractSplitsCacheSync';
|
|
6
6
|
/**
|
|
@@ -53,7 +53,7 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, storage, segmen
|
|
|
53
53
|
return updaterPromise.catch(function (error) {
|
|
54
54
|
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
55
55
|
retry += 1;
|
|
56
|
-
log.warn(
|
|
56
|
+
log.warn(SYNC_FETCH_RETRY, ['memberships', retry, error]);
|
|
57
57
|
return _mySegmentsUpdater(retry); // no need to forward `segmentList` and `noCache` params
|
|
58
58
|
}
|
|
59
59
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SDK_SEGMENTS_ARRIVED, SEGMENTS_UPDATE } from '../../../readiness/constants';
|
|
2
|
-
import { LOG_PREFIX_INSTANTIATION,
|
|
2
|
+
import { LOG_PREFIX_INSTANTIATION, LOG_PREFIX_SYNC } from '../../../logger/constants';
|
|
3
3
|
import { timeout } from '../../../utils/promise/timeout';
|
|
4
4
|
/**
|
|
5
5
|
* Factory of SegmentChanges updater, a task that:
|
|
@@ -20,7 +20,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
20
20
|
return promise;
|
|
21
21
|
}
|
|
22
22
|
function updateSegment(segmentName, noCache, till, fetchOnlyNew, retries) {
|
|
23
|
-
log.debug(
|
|
23
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing segment ").concat(segmentName));
|
|
24
24
|
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
25
25
|
return sincePromise.then(function (since) {
|
|
26
26
|
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
@@ -28,14 +28,14 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
28
28
|
false :
|
|
29
29
|
segmentChangesFetcher(since || -1, segmentName, noCache, till, _promiseDecorator).then(function (changes) {
|
|
30
30
|
return Promise.all(changes.map(function (x) {
|
|
31
|
-
log.debug(
|
|
31
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Processing ").concat(segmentName, " with till = ").concat(x.till, ". Added: ").concat(x.added.length, ". Removed: ").concat(x.removed.length));
|
|
32
32
|
return segments.update(segmentName, x.added, x.removed, x.till);
|
|
33
33
|
})).then(function (updates) {
|
|
34
34
|
return updates.some(function (update) { return update; });
|
|
35
35
|
});
|
|
36
36
|
}).catch(function (error) {
|
|
37
37
|
if (retries) {
|
|
38
|
-
log.warn(
|
|
38
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Retrying fetch of segment ").concat(segmentName, " (attempt #").concat(retries, "). Reason: ").concat(error));
|
|
39
39
|
return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
|
|
40
40
|
}
|
|
41
41
|
throw error;
|
|
@@ -54,7 +54,7 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
54
54
|
* @param till - till target for the provided segmentName, for CDN bypass.
|
|
55
55
|
*/
|
|
56
56
|
return function segmentChangesUpdater(fetchOnlyNew, segmentName, noCache, till) {
|
|
57
|
-
log.debug(
|
|
57
|
+
log.debug("".concat(LOG_PREFIX_SYNC, "Started segments update"));
|
|
58
58
|
// If not a segment name provided, read list of available segments names to be updated.
|
|
59
59
|
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
|
|
60
60
|
return segmentsPromise.then(function (segmentNames) {
|
|
@@ -81,10 +81,10 @@ export function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segment
|
|
|
81
81
|
// @TODO although factory status is destroyed, synchronization is not stopped
|
|
82
82
|
if (readiness)
|
|
83
83
|
readiness.setDestroyed();
|
|
84
|
-
log.error(LOG_PREFIX_INSTANTIATION
|
|
84
|
+
log.error("".concat(LOG_PREFIX_INSTANTIATION, ": you passed a client-side type authorizationKey, please grab an SDK Key from Harness UI that is of type server-side."));
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
log.warn(
|
|
87
|
+
log.warn("".concat(LOG_PREFIX_SYNC, "Error while doing fetch of segments. ").concat(error));
|
|
88
88
|
}
|
|
89
89
|
return false;
|
|
90
90
|
});
|
|
@@ -57,11 +57,11 @@ var SSEClient = /** @class */ (function () {
|
|
|
57
57
|
var params = CONTROL_CHANNEL_REGEX.test(channel) ? '[?occupancy=metrics.publishers]' : '';
|
|
58
58
|
return encodeURIComponent(params + channel);
|
|
59
59
|
}).join(',');
|
|
60
|
-
var url = this.settings.urls.streaming
|
|
60
|
+
var url = "".concat(this.settings.urls.streaming, "/sse?channels=").concat(channelsQueryParam, "&accessToken=").concat(authToken.token, "&v=").concat(ABLY_API_VERSION, "&heartbeats=true"); // same results using `&heartbeats=false`
|
|
61
61
|
var isServerSide = checkIfServerSide(this.settings);
|
|
62
62
|
this.connection = new this.eventSource(
|
|
63
63
|
// For client-side SDKs, metadata is passed as query param to avoid CORS issues and because native EventSource implementations in browsers do not support headers
|
|
64
|
-
isServerSide ? url : url +
|
|
64
|
+
isServerSide ? url : url + "&SplitSDKVersion=".concat(this.headers.SplitSDKVersion, "&SplitSDKClientKey=").concat(this.headers.SplitSDKClientKey),
|
|
65
65
|
// For server-side SDKs, metadata is passed via headers
|
|
66
66
|
objectAssign(isServerSide ?
|
|
67
67
|
{ headers: decorateHeaders(this.settings, this.headers) } :
|
|
@@ -48,7 +48,7 @@ export function MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemet
|
|
|
48
48
|
telemetryTracker.trackUpdatesFromSSE(MEMBERSHIPS);
|
|
49
49
|
var attempts = backoff.attempts + 1;
|
|
50
50
|
if (maxChangeNumber <= currentChangeNumber) {
|
|
51
|
-
log.debug("Refresh completed"
|
|
51
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
52
52
|
isHandlingEvent = false;
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
@@ -57,7 +57,7 @@ export function MySegmentsUpdateWorker(log, storage, mySegmentsSyncTask, telemet
|
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
if (cdnBypass) {
|
|
60
|
-
log.debug("No changes fetched after "
|
|
60
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
61
61
|
isHandlingEvent = false;
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
@@ -25,7 +25,7 @@ export function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
|
|
|
25
25
|
else {
|
|
26
26
|
var attempts = backoff.attempts + 1;
|
|
27
27
|
if (maxChangeNumber <= (segmentsCache.getChangeNumber(segment) || -1)) {
|
|
28
|
-
log.debug("Refresh completed"
|
|
28
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
29
29
|
isHandlingEvent = false;
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
@@ -34,7 +34,7 @@ export function SegmentsUpdateWorker(log, segmentsSyncTask, segmentsCache) {
|
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
36
|
if (cdnBypass) {
|
|
37
|
-
log.debug("No changes fetched after "
|
|
37
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
38
38
|
isHandlingEvent = false;
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
@@ -8,7 +8,7 @@ import { FETCH_BACKOFF_BASE, FETCH_BACKOFF_MAX_WAIT, FETCH_BACKOFF_MAX_RETRIES }
|
|
|
8
8
|
/**
|
|
9
9
|
* SplitsUpdateWorker factory
|
|
10
10
|
*/
|
|
11
|
-
export function SplitsUpdateWorker(log, storage,
|
|
11
|
+
export function SplitsUpdateWorker(log, storage, definitionsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) {
|
|
12
12
|
var ff = SplitsUpdateWorker(storage.splits);
|
|
13
13
|
var rbs = SplitsUpdateWorker(storage.rbSegments);
|
|
14
14
|
function SplitsUpdateWorker(cache) {
|
|
@@ -23,7 +23,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
23
23
|
if (maxChangeNumber > cache.getChangeNumber()) {
|
|
24
24
|
handleNewEvent = false;
|
|
25
25
|
// fetch splits revalidating data if cached
|
|
26
|
-
|
|
26
|
+
definitionsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
|
|
27
27
|
if (!isHandlingEvent)
|
|
28
28
|
return; // halt if `stop` has been called
|
|
29
29
|
if (handleNewEvent) {
|
|
@@ -37,7 +37,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
37
37
|
segmentsSyncTask.execute(true);
|
|
38
38
|
var attempts = backoff.attempts + 1;
|
|
39
39
|
if (ff.isSync() && rbs.isSync()) {
|
|
40
|
-
log.debug("Refresh completed"
|
|
40
|
+
log.debug("Refresh completed".concat(cdnBypass ? ' bypassing the CDN' : '', " in ").concat(attempts, " attempts."));
|
|
41
41
|
isHandlingEvent = false;
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
@@ -46,7 +46,7 @@ export function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmit
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
if (cdnBypass) {
|
|
49
|
-
log.debug("No changes fetched after "
|
|
49
|
+
log.debug("No changes fetched after ".concat(attempts, " attempts with CDN bypassed."));
|
|
50
50
|
isHandlingEvent = false;
|
|
51
51
|
}
|
|
52
52
|
else {
|
|
@@ -27,25 +27,25 @@ function decompress(data, compression) {
|
|
|
27
27
|
return algorithms.gunzipSync(binData);
|
|
28
28
|
if (compression === ZLIB)
|
|
29
29
|
return algorithms.unzlibSync(binData);
|
|
30
|
-
throw new Error("Invalid compression algorithm #"
|
|
30
|
+
throw new Error("Invalid compression algorithm #".concat(compression));
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Decode, decompress and parse the provided 'data' into
|
|
33
|
+
* Decode, decompress and parse the provided 'data' into an object of type T
|
|
34
34
|
*
|
|
35
35
|
* @param data - base64 encoded string
|
|
36
36
|
* @param compression - 1 GZIP, 2 ZLIB
|
|
37
37
|
* @param avoidPrecisionLoss - true as default, set it as false if dont need to avoid precission loss
|
|
38
|
-
* @returns
|
|
38
|
+
* @returns parsed object
|
|
39
39
|
* @throws if data string cannot be decoded, decompressed or parsed
|
|
40
40
|
*/
|
|
41
|
-
export function
|
|
41
|
+
export function parseCompressedData(data, compression, avoidPrecisionLoss) {
|
|
42
42
|
if (avoidPrecisionLoss === void 0) { avoidPrecisionLoss = true; }
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
// replace numbers to strings, to avoid losing precision
|
|
43
|
+
var binData = decompress(data, compression);
|
|
44
|
+
var str = Uint8ArrayToString(binData);
|
|
45
|
+
// replace numbers to strings, to avoid losing precision (e.g., 64-bit IDs in KeyList)
|
|
46
46
|
if (avoidPrecisionLoss)
|
|
47
|
-
|
|
48
|
-
return JSON.parse(
|
|
47
|
+
str = str.replace(/\d+/g, '"$&"');
|
|
48
|
+
return JSON.parse(str);
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
51
|
* Decode, decompress and parse the provided 'data' into a Bitmap object
|
|
@@ -77,7 +77,7 @@ export function isInBitmap(bitmap, hash64hex) {
|
|
|
77
77
|
*/
|
|
78
78
|
export function parseFFUpdatePayload(compression, data) {
|
|
79
79
|
return compression > 0 ?
|
|
80
|
-
|
|
80
|
+
parseCompressedData(data, compression, false) :
|
|
81
81
|
JSON.parse(decodeFromBase64(data));
|
|
82
82
|
}
|
|
83
83
|
var DEFAULT_MAX_INTERVAL = 60000;
|
|
@@ -11,7 +11,7 @@ import { checkIfServerSide, getMatching } from '../../utils/key';
|
|
|
11
11
|
import { MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, RB_SEGMENT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType } from './constants';
|
|
12
12
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MEMBERSHIPS_UPDATE } from '../../logger/constants';
|
|
13
13
|
import { UpdateStrategy } from './SSEHandler/types';
|
|
14
|
-
import { getDelay, isInBitmap, parseBitmap,
|
|
14
|
+
import { getDelay, isInBitmap, parseBitmap, parseCompressedData } from './parseUtils';
|
|
15
15
|
import { hash64 } from '../../utils/murmur3/murmur3_64';
|
|
16
16
|
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
17
17
|
/**
|
|
@@ -43,7 +43,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
43
43
|
// MySegmentsUpdateWorker (client-side) are initiated in `add` method
|
|
44
44
|
var segmentsUpdateWorker = userKey ? undefined : SegmentsUpdateWorker(log, pollingManager.segmentsSyncTask, storage.segments);
|
|
45
45
|
// For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
46
|
-
var splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.
|
|
46
|
+
var splitsUpdateWorker = SplitsUpdateWorker(log, storage, pollingManager.definitionsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
|
|
47
47
|
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
48
48
|
var userKeyHashes = {};
|
|
49
49
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
@@ -203,7 +203,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
203
203
|
case UpdateStrategy.KeyList: {
|
|
204
204
|
var keyList = void 0, added_1, removed_1;
|
|
205
205
|
try {
|
|
206
|
-
keyList =
|
|
206
|
+
keyList = parseCompressedData(parsedData.d, parsedData.c);
|
|
207
207
|
added_1 = new Set(keyList.a);
|
|
208
208
|
removed_1 = new Set(keyList.r);
|
|
209
209
|
}
|
|
@@ -4,14 +4,14 @@ import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
|
4
4
|
/**
|
|
5
5
|
* Converts `impressions` data from cache into request payload.
|
|
6
6
|
*/
|
|
7
|
-
export function fromImpressionsCollector(sendLabels, data) {
|
|
7
|
+
export function fromImpressionsCollector(sendLabels, entityType, data) {
|
|
8
8
|
var groupedByFeature = groupBy(data, 'feature');
|
|
9
9
|
var dto = [];
|
|
10
10
|
forOwn(groupedByFeature, function (value, name) {
|
|
11
11
|
dto.push({
|
|
12
12
|
f: name,
|
|
13
13
|
i: value.map(function (entry) {
|
|
14
|
-
|
|
14
|
+
return {
|
|
15
15
|
k: entry.keyName,
|
|
16
16
|
t: entry.treatment,
|
|
17
17
|
m: entry.time,
|
|
@@ -19,9 +19,9 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
19
19
|
r: sendLabels ? entry.label : undefined,
|
|
20
20
|
b: entry.bucketingKey,
|
|
21
21
|
pt: entry.pt,
|
|
22
|
-
properties: entry.properties
|
|
22
|
+
properties: entry.properties,
|
|
23
|
+
et: entityType, // Definition type
|
|
23
24
|
};
|
|
24
|
-
return keyImpression;
|
|
25
25
|
})
|
|
26
26
|
});
|
|
27
27
|
});
|
|
@@ -31,9 +31,9 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
31
31
|
* Submitter that periodically posts impressions data
|
|
32
32
|
*/
|
|
33
33
|
export function impressionsSubmitterFactory(params) {
|
|
34
|
-
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.splitApi.postTestImpressionsBulk, impressions = params.storage.impressions;
|
|
34
|
+
var _a = params.settings, log = _a.log, impressionsRefreshRate = _a.scheduler.impressionsRefreshRate, labelsEnabled = _a.core.labelsEnabled, postTestImpressionsBulk = params.splitApi.postTestImpressionsBulk, impressions = params.storage.impressions, entityType = params.entityType;
|
|
35
35
|
// retry impressions only once.
|
|
36
|
-
var syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled), 1);
|
|
36
|
+
var syncTask = submitterFactory(log, postTestImpressionsBulk, impressions, impressionsRefreshRate, fromImpressionsCollector.bind(undefined, labelsEnabled, entityType), 1);
|
|
37
37
|
// register impressions submitter to be executed when impressions cache is full
|
|
38
38
|
impressions.setOnFullQueueCb(function () {
|
|
39
39
|
if (syncTask.isRunning()) {
|
|
@@ -13,7 +13,7 @@ export function submitterFactory(log, postClient, sourceCache, postRate, fromCac
|
|
|
13
13
|
if (sourceCache.isEmpty() && !data)
|
|
14
14
|
return Promise.resolve();
|
|
15
15
|
data = sourceCache.pop(data);
|
|
16
|
-
var dataCountMessage = typeof data.length === 'number' ? data.length
|
|
16
|
+
var dataCountMessage = typeof data.length === 'number' ? "".concat(data.length, " ").concat(dataName) : dataName;
|
|
17
17
|
log[debugLogs ? 'debug' : 'info'](SUBMITTERS_PUSH, [dataCountMessage]);
|
|
18
18
|
var jsonPayload = JSON.stringify(fromCacheToPayload ? fromCacheToPayload(data) : data);
|
|
19
19
|
if (!maxRetries)
|
|
@@ -5,6 +5,7 @@ import { isConsentGranted } from '../consent';
|
|
|
5
5
|
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
6
6
|
import { SDK_SPLITS_CACHE_LOADED } from '../readiness/constants';
|
|
7
7
|
import { usesSegmentsSync } from '../storages/AbstractSplitsCacheSync';
|
|
8
|
+
import { splitChangesFetcherFactory } from './polling/fetchers/splitChangesFetcher';
|
|
8
9
|
/**
|
|
9
10
|
* Online SyncManager factory.
|
|
10
11
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -12,15 +13,17 @@ import { usesSegmentsSync } from '../storages/AbstractSplitsCacheSync';
|
|
|
12
13
|
* @param pollingManagerFactory - allows to specialize the SyncManager for server-side or client-side API by passing
|
|
13
14
|
* `pollingManagerSSFactory` or `pollingManagerCSFactory` respectively.
|
|
14
15
|
* @param pushManagerFactory - optional to build a SyncManager with or without streaming support
|
|
16
|
+
* @param definitionChangesFetcherFactory - optional to replace the default split changes fetcher
|
|
15
17
|
*/
|
|
16
|
-
export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
|
|
18
|
+
export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory, definitionChangesFetcherFactory) {
|
|
19
|
+
if (definitionChangesFetcherFactory === void 0) { definitionChangesFetcherFactory = splitChangesFetcherFactory; }
|
|
17
20
|
/**
|
|
18
21
|
* SyncManager factory for modular SDK
|
|
19
22
|
*/
|
|
20
23
|
return function (params) {
|
|
21
24
|
var settings = params.settings, _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled, syncEnabled = _a.sync.enabled, telemetryTracker = params.telemetryTracker, storage = params.storage, readiness = params.readiness;
|
|
22
25
|
/** Polling Manager */
|
|
23
|
-
var pollingManager = pollingManagerFactory && pollingManagerFactory(params);
|
|
26
|
+
var pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionChangesFetcherFactory(params));
|
|
24
27
|
/** Push Manager */
|
|
25
28
|
var pushManager = syncEnabled && streamingEnabled && pollingManager && pushManagerFactory ?
|
|
26
29
|
pushManagerFactory(params, pollingManager) :
|
|
@@ -9,26 +9,24 @@ import { isConsumerMode } from '../utils/settingsValidation/mode';
|
|
|
9
9
|
* @param eventsCache - cache to save events
|
|
10
10
|
* @param integrationsManager - optional event handler used for integrations
|
|
11
11
|
*/
|
|
12
|
-
export function eventTrackerFactory(settings, eventsCache,
|
|
12
|
+
export function eventTrackerFactory(settings, eventsCache, integrationsManager, telemetryCache) {
|
|
13
13
|
var log = settings.log, mode = settings.mode;
|
|
14
14
|
var isAsync = isConsumerMode(mode);
|
|
15
15
|
function queueEventsCallback(eventData, tracked) {
|
|
16
16
|
var eventTypeId = eventData.eventTypeId, trafficTypeName = eventData.trafficTypeName, key = eventData.key, value = eventData.value, timestamp = eventData.timestamp, properties = eventData.properties;
|
|
17
17
|
// Logging every prop would be too much.
|
|
18
|
-
var msg = "event of type \""
|
|
18
|
+
var msg = "event of type \"".concat(eventTypeId, "\" for traffic type \"").concat(trafficTypeName, "\". Key: ").concat(key, ". Value: ").concat(value, ". Timestamp: ").concat(timestamp, ". ").concat(properties ? 'With properties.' : 'With no properties.');
|
|
19
19
|
if (tracked) {
|
|
20
20
|
log.info(EVENTS_TRACKER_SUCCESS, [msg]);
|
|
21
21
|
if (integrationsManager) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
integrationsManager.handleEvent(eventDataCopy);
|
|
31
|
-
});
|
|
22
|
+
// Wrap in a timeout because we don't want it to be blocking.
|
|
23
|
+
setTimeout(function () {
|
|
24
|
+
// copy of event, to avoid unexpected behavior if modified by integrations
|
|
25
|
+
var eventDataCopy = objectAssign({}, eventData);
|
|
26
|
+
if (properties)
|
|
27
|
+
eventDataCopy.properties = objectAssign({}, properties);
|
|
28
|
+
// integrationsManager does not throw errors (they are internally handled by each integration module)
|
|
29
|
+
integrationsManager.handleEvent(eventDataCopy);
|
|
32
30
|
});
|
|
33
31
|
}
|
|
34
32
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export function buildKey(impression) {
|
|
2
|
-
return impression.keyName
|
|
2
|
+
return "".concat(impression.keyName, ":").concat(impression.feature, ":").concat(impression.treatment, ":").concat(impression.label, ":").concat(impression.changeNumber);
|
|
3
3
|
}
|