@splitsoftware/splitio-commons 3.1.1-rc.0 → 3.1.1-rc.10
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 +10 -1
- package/cjs/evaluator/condition/index.js +1 -1
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/cjs/evaluator/index.js +69 -81
- package/cjs/listeners/browser.js +1 -2
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +20 -15
- package/cjs/logger/messages/debug.js +6 -5
- package/cjs/logger/messages/error.js +3 -3
- package/cjs/logger/messages/info.js +4 -3
- package/cjs/logger/messages/warn.js +7 -6
- package/cjs/presets/serverSide.js +2 -2
- package/cjs/readiness/constants.js +4 -5
- package/cjs/readiness/readinessManager.js +23 -23
- package/cjs/readiness/sdkReadinessManager.js +17 -1
- package/cjs/sdkClient/client.js +34 -9
- package/cjs/sdkClient/clientInputValidation.js +17 -6
- package/cjs/sdkClient/sdkClient.js +60 -3
- package/cjs/sdkFactory/index.js +15 -11
- package/cjs/sdkManager/index.js +5 -5
- package/cjs/services/decorateHeaders.js +1 -2
- package/cjs/services/splitApi.js +1 -14
- package/cjs/services/splitHttpClient.js +5 -3
- package/cjs/storages/AbstractSplitsCacheAsync.js +51 -0
- package/cjs/storages/AbstractSplitsCacheSync.js +76 -0
- package/cjs/storages/KeyBuilder.js +6 -6
- package/cjs/storages/KeyBuilderCS.js +5 -5
- package/cjs/storages/KeyBuilderSS.js +2 -2
- package/cjs/storages/getRolloutPlan.js +3 -3
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +194 -0
- package/cjs/storages/inLocalStorage/index.js +6 -6
- package/cjs/storages/inLocalStorage/validateCache.js +3 -3
- package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +121 -0
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -5
- package/cjs/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +77 -77
- package/cjs/storages/inRedis/index.js +2 -2
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +212 -0
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/storages/setRolloutPlan.js +4 -4
- package/cjs/storages/utils.js +0 -1
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +15 -24
- package/cjs/sync/polling/pollingManagerCS.js +20 -20
- package/cjs/sync/polling/pollingManagerSS.js +15 -15
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +13 -0
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +19 -16
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +11 -11
- package/cjs/sync/streaming/pushManager.js +16 -16
- package/cjs/sync/submitters/eventsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/cjs/sync/submitters/impressionsSubmitter.js +4 -5
- package/cjs/sync/submitters/telemetrySubmitter.js +4 -3
- package/cjs/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +7 -12
- package/cjs/utils/Backoff.js +0 -20
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/{definition.js → split.js} +10 -10
- package/cjs/utils/inputValidation/{definitionExistence.js → splitExistence.js} +6 -6
- package/cjs/utils/inputValidation/splits.js +25 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/settingsValidation/index.js +0 -2
- package/cjs/utils/settingsValidation/splitFilters.js +3 -3
- package/cjs/utils/settingsValidation/url.js +2 -6
- package/esm/evaluator/condition/index.js +1 -1
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +8 -5
- package/esm/evaluator/index.js +69 -80
- package/esm/listeners/browser.js +1 -2
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +17 -12
- package/esm/logger/messages/debug.js +6 -5
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +4 -3
- package/esm/logger/messages/warn.js +7 -6
- package/esm/presets/serverSide.js +2 -2
- package/esm/readiness/constants.js +3 -4
- package/esm/readiness/readinessManager.js +24 -24
- package/esm/readiness/sdkReadinessManager.js +18 -2
- package/esm/sdkClient/client.js +35 -9
- package/esm/sdkClient/clientInputValidation.js +19 -8
- package/esm/sdkClient/sdkClient.js +60 -3
- package/esm/sdkFactory/index.js +16 -12
- package/esm/sdkManager/index.js +6 -6
- package/esm/services/decorateHeaders.js +1 -2
- package/esm/services/splitApi.js +1 -14
- package/esm/services/splitHttpClient.js +5 -3
- package/esm/storages/AbstractSplitsCacheAsync.js +48 -0
- package/esm/storages/AbstractSplitsCacheSync.js +71 -0
- package/esm/storages/KeyBuilder.js +6 -6
- package/esm/storages/KeyBuilderCS.js +5 -5
- package/esm/storages/KeyBuilderSS.js +2 -2
- package/esm/storages/getRolloutPlan.js +3 -3
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +2 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +191 -0
- package/esm/storages/inLocalStorage/index.js +6 -6
- package/esm/storages/inLocalStorage/validateCache.js +3 -3
- package/esm/storages/inMemory/InMemoryStorage.js +4 -4
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/SplitsCacheInMemory.js +118 -0
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +8 -5
- package/esm/storages/inRedis/{DefinitionsCacheInRedis.js → SplitsCacheInRedis.js} +76 -76
- package/esm/storages/inRedis/index.js +2 -2
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +209 -0
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/setRolloutPlan.js +4 -4
- package/esm/storages/utils.js +0 -1
- package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +16 -25
- package/esm/sync/polling/pollingManagerCS.js +17 -17
- package/esm/sync/polling/pollingManagerSS.js +15 -15
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +3 -2
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +9 -0
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/polling/updaters/{definitionChangesUpdater.js → splitChangesUpdater.js} +68 -65
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/{DefinitionsUpdateWorker.js → SplitsUpdateWorker.js} +18 -15
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +9 -9
- package/esm/sync/streaming/pushManager.js +18 -18
- package/esm/sync/submitters/eventsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionCountsSubmitter.js +1 -1
- package/esm/sync/submitters/impressionsSubmitter.js +4 -5
- package/esm/sync/submitters/telemetrySubmitter.js +4 -3
- package/esm/sync/submitters/uniqueKeysSubmitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +6 -11
- package/esm/utils/Backoff.js +0 -20
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/{definition.js → split.js} +8 -8
- package/esm/utils/inputValidation/splitExistence.js +15 -0
- package/esm/utils/inputValidation/splits.js +21 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/settingsValidation/index.js +0 -2
- package/esm/utils/settingsValidation/splitFilters.js +3 -3
- package/esm/utils/settingsValidation/url.js +2 -6
- package/package.json +6 -7
- package/src/dtos/types.ts +1 -1
- package/src/evaluator/Engine.ts +3 -3
- package/src/evaluator/condition/index.ts +2 -2
- package/src/evaluator/index.ts +27 -35
- package/src/evaluator/types.ts +2 -6
- package/src/presets/serverSide.ts +3 -3
- package/src/sdkClient/client.ts +22 -24
- package/src/sdkClient/sdkLifecycle.ts +3 -0
- package/src/services/authProvider.ts +41 -19
- package/src/services/secureSplitHttpClient.ts +10 -18
- package/src/services/serviceApi.ts +27 -24
- package/src/services/splitApi.ts +10 -9
- package/src/services/types.ts +5 -4
- package/src/storages/inRedis/RedisAdapter.ts +8 -5
- package/src/sync/polling/pollingManagerCS.ts +80 -78
- package/src/sync/polling/pollingManagerSS.ts +49 -45
- package/src/sync/polling/updaters/definitionChangesUpdater.ts +3 -3
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/streaming/AuthClient/index.ts +14 -15
- package/src/sync/streaming/AuthClient/types.ts +9 -13
- package/src/sync/streaming/SSEClient/index.ts +2 -2
- package/src/sync/streaming/SSEClient/types.ts +2 -2
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +2 -2
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +32 -42
- package/src/sync/streaming/types.ts +3 -2
- package/src/sync/submitters/impressionsSubmitter.ts +3 -3
- package/src/sync/submitters/types.ts +2 -2
- package/src/sync/syncManagerOnline.ts +2 -8
- package/src/utils/Backoff.ts +16 -4
- package/types/splitio.d.ts +5 -4
- package/cjs/platform/browser.js +0 -15
- package/cjs/platform/getEventSource/browser.js +0 -8
- package/cjs/platform/getEventSource/eventsource.js +0 -480
- package/cjs/platform/getEventSource/node.js +0 -26
- package/cjs/platform/getFetch/browser.js +0 -9
- package/cjs/platform/getFetch/node.js +0 -27
- package/cjs/platform/getOptions/node.js +0 -25
- package/cjs/platform/node.js +0 -17
- package/cjs/sdkClient/sdkLifecycle.js +0 -72
- package/cjs/sdkClient/trackMethod.js +0 -56
- package/cjs/services/authProvider.js +0 -67
- package/cjs/services/secureSplitHttpClient.js +0 -39
- package/cjs/services/serviceApi.js +0 -145
- package/cjs/storages/AbstractDefinitionsCacheAsync.js +0 -51
- package/cjs/storages/AbstractDefinitionsCacheSync.js +0 -76
- package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -194
- package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +0 -121
- package/cjs/storages/pluggable/DefinitionsCachePluggable.js +0 -212
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +0 -13
- package/cjs/utils/EventEmitter.js +0 -391
- package/cjs/utils/filter/bloomFilter.js +0 -37
- package/cjs/utils/inputValidation/definitions.js +0 -25
- package/cjs/utils/inputValidation/target.js +0 -22
- package/esm/platform/browser.js +0 -12
- package/esm/platform/getEventSource/browser.js +0 -4
- package/esm/platform/getEventSource/eventsource.js +0 -480
- package/esm/platform/getEventSource/node.js +0 -20
- package/esm/platform/getFetch/browser.js +0 -5
- package/esm/platform/getFetch/node.js +0 -22
- package/esm/platform/getOptions/node.js +0 -20
- package/esm/platform/node.js +0 -14
- package/esm/sdkClient/sdkLifecycle.js +0 -68
- package/esm/sdkClient/trackMethod.js +0 -52
- package/esm/services/authProvider.js +0 -63
- package/esm/services/secureSplitHttpClient.js +0 -35
- package/esm/services/serviceApi.js +0 -141
- package/esm/storages/AbstractDefinitionsCacheAsync.js +0 -48
- package/esm/storages/AbstractDefinitionsCacheSync.js +0 -71
- package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +0 -191
- package/esm/storages/inMemory/DefinitionsCacheInMemory.js +0 -118
- package/esm/storages/pluggable/DefinitionsCachePluggable.js +0 -209
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +0 -9
- package/esm/utils/EventEmitter.js +0 -387
- package/esm/utils/filter/bloomFilter.js +0 -33
- package/esm/utils/inputValidation/definitionExistence.js +0 -15
- package/esm/utils/inputValidation/definitions.js +0 -21
- package/esm/utils/inputValidation/target.js +0 -18
|
@@ -3,20 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.readinessManagerFactory = void 0;
|
|
4
4
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
5
|
var constants_1 = require("./constants");
|
|
6
|
-
function
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
function splitsEventEmitterFactory(EventEmitter) {
|
|
7
|
+
var splitsEventEmitter = (0, objectAssign_1.objectAssign)(new EventEmitter(), {
|
|
8
|
+
splitsArrived: false,
|
|
9
|
+
splitsCacheLoaded: false,
|
|
10
10
|
hasInit: false,
|
|
11
11
|
initCallbacks: []
|
|
12
12
|
});
|
|
13
13
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
14
14
|
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
15
15
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return
|
|
16
|
+
splitsEventEmitter.on(constants_1.SDK_SPLITS_ARRIVED, function (metadata, isSplitKill) { if (!isSplitKill)
|
|
17
|
+
splitsEventEmitter.splitsArrived = true; });
|
|
18
|
+
splitsEventEmitter.once(constants_1.SDK_SPLITS_CACHE_LOADED, function () { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
19
|
+
return splitsEventEmitter;
|
|
20
20
|
}
|
|
21
21
|
function segmentsEventEmitterFactory(EventEmitter) {
|
|
22
22
|
var segmentsEventEmitter = (0, objectAssign_1.objectAssign)(new EventEmitter(), {
|
|
@@ -28,8 +28,8 @@ function segmentsEventEmitterFactory(EventEmitter) {
|
|
|
28
28
|
/**
|
|
29
29
|
* Factory of readiness manager, which handles the ready / update event propagation.
|
|
30
30
|
*/
|
|
31
|
-
function readinessManagerFactory(EventEmitter, settings,
|
|
32
|
-
if (
|
|
31
|
+
function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
32
|
+
if (splits === void 0) { splits = splitsEventEmitterFactory(EventEmitter); }
|
|
33
33
|
var readyTimeout = settings.startup.readyTimeout;
|
|
34
34
|
var segments = segmentsEventEmitterFactory(EventEmitter);
|
|
35
35
|
var gate = new EventEmitter();
|
|
@@ -44,10 +44,10 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
44
44
|
};
|
|
45
45
|
// emit SDK_READY_FROM_CACHE
|
|
46
46
|
var isReadyFromCache = false;
|
|
47
|
-
if (
|
|
47
|
+
if (splits.splitsCacheLoaded)
|
|
48
48
|
isReadyFromCache = true; // ready from cache, but doesn't emit SDK_READY_FROM_CACHE
|
|
49
49
|
else
|
|
50
|
-
|
|
50
|
+
splits.once(constants_1.SDK_SPLITS_CACHE_LOADED, checkIsReadyFromCache);
|
|
51
51
|
// emit SDK_READY_TIMED_OUT
|
|
52
52
|
var hasTimedout = false;
|
|
53
53
|
function timeout() {
|
|
@@ -55,11 +55,11 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
55
55
|
return;
|
|
56
56
|
hasTimedout = true;
|
|
57
57
|
syncLastUpdate();
|
|
58
|
-
gate.emit(constants_1.SDK_READY_TIMED_OUT, 'SDK
|
|
58
|
+
gate.emit(constants_1.SDK_READY_TIMED_OUT, 'Split SDK emitted SDK_READY_TIMED_OUT event.');
|
|
59
59
|
}
|
|
60
60
|
// emit SDK_READY and SDK_UPDATE
|
|
61
61
|
var isReady = false;
|
|
62
|
-
|
|
62
|
+
splits.on(constants_1.SDK_SPLITS_ARRIVED, checkIsReadyOrUpdate);
|
|
63
63
|
segments.on(constants_1.SDK_SEGMENTS_ARRIVED, checkIsReadyOrUpdate);
|
|
64
64
|
var isDestroyed = false;
|
|
65
65
|
var readyTimeoutId;
|
|
@@ -68,8 +68,8 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
68
68
|
if (readyTimeout > 0 && !isReady)
|
|
69
69
|
readyTimeoutId = setTimeout(timeout, readyTimeout);
|
|
70
70
|
}
|
|
71
|
-
|
|
72
|
-
if (
|
|
71
|
+
splits.initCallbacks.push(__init);
|
|
72
|
+
if (splits.hasInit)
|
|
73
73
|
__init();
|
|
74
74
|
function checkIsReadyFromCache(cacheMetadata) {
|
|
75
75
|
metadataReady = cacheMetadata;
|
|
@@ -100,7 +100,7 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
if (
|
|
103
|
+
if (splits.splitsArrived && segments.segmentsArrived) {
|
|
104
104
|
clearTimeout(readyTimeoutId);
|
|
105
105
|
isReady = true;
|
|
106
106
|
try {
|
|
@@ -123,11 +123,11 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
return {
|
|
126
|
-
|
|
126
|
+
splits: splits,
|
|
127
127
|
segments: segments,
|
|
128
128
|
gate: gate,
|
|
129
129
|
shared: function () {
|
|
130
|
-
return readinessManagerFactory(EventEmitter, settings,
|
|
130
|
+
return readinessManagerFactory(EventEmitter, settings, splits, true);
|
|
131
131
|
},
|
|
132
132
|
// @TODO review/remove next methods when non-recoverable errors are reworked
|
|
133
133
|
// Called on consumer mode, when storage fails to connect
|
|
@@ -136,17 +136,17 @@ function readinessManagerFactory(EventEmitter, settings, definitions, isShared)
|
|
|
136
136
|
// tracking and evaluations, while keeping event listeners to emit SDK_READY_TIMED_OUT event
|
|
137
137
|
setDestroyed: function () { isDestroyed = true; },
|
|
138
138
|
init: function () {
|
|
139
|
-
if (
|
|
139
|
+
if (splits.hasInit)
|
|
140
140
|
return;
|
|
141
|
-
|
|
142
|
-
|
|
141
|
+
splits.hasInit = true;
|
|
142
|
+
splits.initCallbacks.forEach(function (cb) { return cb(); });
|
|
143
143
|
},
|
|
144
144
|
destroy: function () {
|
|
145
145
|
isDestroyed = true;
|
|
146
146
|
syncLastUpdate();
|
|
147
147
|
clearTimeout(readyTimeoutId);
|
|
148
148
|
if (!isShared)
|
|
149
|
-
|
|
149
|
+
splits.hasInit = false;
|
|
150
150
|
},
|
|
151
151
|
isReady: function () { return isReady; },
|
|
152
152
|
isReadyFromCache: function () { return isReadyFromCache; },
|
|
@@ -7,6 +7,7 @@ var readinessManager_1 = require("./readinessManager");
|
|
|
7
7
|
var constants_1 = require("./constants");
|
|
8
8
|
var constants_2 = require("../logger/constants");
|
|
9
9
|
var NEW_LISTENER_EVENT = 'newListener';
|
|
10
|
+
var REMOVE_LISTENER_EVENT = 'removeListener';
|
|
10
11
|
var TIMEOUT_ERROR = new Error(constants_1.SDK_READY_TIMED_OUT);
|
|
11
12
|
/**
|
|
12
13
|
* SdkReadinessManager factory, which provides the public status API of SDK clients and manager: ready promise, readiness event emitter and constants (SDK_READY, etc).
|
|
@@ -18,11 +19,21 @@ var TIMEOUT_ERROR = new Error(constants_1.SDK_READY_TIMED_OUT);
|
|
|
18
19
|
function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
19
20
|
if (readinessManager === void 0) { readinessManager = (0, readinessManager_1.readinessManagerFactory)(EventEmitter, settings); }
|
|
20
21
|
var log = settings.log;
|
|
22
|
+
/** Ready callback warning */
|
|
23
|
+
var internalReadyCbCount = 0;
|
|
24
|
+
var readyCbCount = 0;
|
|
25
|
+
readinessManager.gate.on(REMOVE_LISTENER_EVENT, function (event) {
|
|
26
|
+
if (event === constants_1.SDK_READY)
|
|
27
|
+
readyCbCount--;
|
|
28
|
+
});
|
|
21
29
|
readinessManager.gate.on(NEW_LISTENER_EVENT, function (event) {
|
|
22
30
|
if (event === constants_1.SDK_READY || event === constants_1.SDK_READY_TIMED_OUT) {
|
|
23
31
|
if (readinessManager.isReady()) {
|
|
24
32
|
log.error(constants_2.ERROR_CLIENT_LISTENER, [event === constants_1.SDK_READY ? 'SDK_READY' : 'SDK_READY_TIMED_OUT']);
|
|
25
33
|
}
|
|
34
|
+
else if (event === constants_1.SDK_READY) {
|
|
35
|
+
readyCbCount++;
|
|
36
|
+
}
|
|
26
37
|
}
|
|
27
38
|
else if (event === constants_1.SDK_READY_FROM_CACHE && readinessManager.isReadyFromCache()) {
|
|
28
39
|
log.error(constants_2.ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);
|
|
@@ -41,6 +52,8 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
41
52
|
var promise = (0, wrapper_1.promiseWrapper)(new Promise(function (resolve, reject) {
|
|
42
53
|
readinessManager.gate.once(constants_1.SDK_READY, function () {
|
|
43
54
|
log.info(constants_2.CLIENT_READY);
|
|
55
|
+
if (readyCbCount === internalReadyCbCount && !promise.hasOnFulfilled())
|
|
56
|
+
log.warn(constants_2.CLIENT_NO_LISTENER);
|
|
44
57
|
resolve();
|
|
45
58
|
});
|
|
46
59
|
readinessManager.gate.once(constants_1.SDK_READY_TIMED_OUT, function (message) {
|
|
@@ -65,6 +78,9 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
65
78
|
shared: function () {
|
|
66
79
|
return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
|
|
67
80
|
},
|
|
81
|
+
incInternalReadyCbCount: function () {
|
|
82
|
+
internalReadyCbCount++;
|
|
83
|
+
},
|
|
68
84
|
sdkStatus: (0, objectAssign_1.objectAssign)(
|
|
69
85
|
// Expose Event Emitter functionality
|
|
70
86
|
Object.create(readinessManager.gate), {
|
|
@@ -79,7 +95,7 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
79
95
|
ready: function () {
|
|
80
96
|
if (readinessManager.hasTimedout()) {
|
|
81
97
|
if (!readinessManager.isReady()) {
|
|
82
|
-
return (0, wrapper_1.promiseWrapper)(Promise.reject(new Error('SDK
|
|
98
|
+
return (0, wrapper_1.promiseWrapper)(Promise.reject(new Error('Split SDK has emitted SDK_READY_TIMED_OUT event.')), defaultOnRejected);
|
|
83
99
|
}
|
|
84
100
|
else {
|
|
85
101
|
return Promise.resolve();
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.clientFactory =
|
|
3
|
+
exports.clientFactory = void 0;
|
|
4
4
|
var evaluator_1 = require("../evaluator");
|
|
5
5
|
var thenable_1 = require("../utils/promise/thenable");
|
|
6
6
|
var key_1 = require("../utils/key");
|
|
7
|
-
var
|
|
7
|
+
var splitExistence_1 = require("../utils/inputValidation/splitExistence");
|
|
8
|
+
var trafficTypeExistence_1 = require("../utils/inputValidation/trafficTypeExistence");
|
|
8
9
|
var labels_1 = require("../utils/labels");
|
|
9
10
|
var constants_1 = require("../utils/constants");
|
|
10
11
|
var constants_2 = require("../logger/constants");
|
|
11
12
|
var mode_1 = require("../utils/settingsValidation/mode");
|
|
12
|
-
var trackMethod_1 = require("./trackMethod");
|
|
13
13
|
var treatmentNotReady = { treatment: constants_1.CONTROL, label: labels_1.SDK_NOT_READY };
|
|
14
14
|
function treatmentsNotReady(featureFlagNames) {
|
|
15
15
|
var evaluations = {};
|
|
@@ -26,12 +26,11 @@ function stringify(options) {
|
|
|
26
26
|
catch ( /* JSON.stringify should never throw with validated options, but handling just in case */_a) { /* JSON.stringify should never throw with validated options, but handling just in case */ }
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
exports.stringify = stringify;
|
|
30
29
|
/**
|
|
31
30
|
* Creator of base client with getTreatments and track methods.
|
|
32
31
|
*/
|
|
33
32
|
function clientFactory(params) {
|
|
34
|
-
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, telemetryTracker = params.telemetryTracker,
|
|
33
|
+
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker, telemetryTracker = params.telemetryTracker, fallbackTreatmentsCalculator = params.fallbackTreatmentsCalculator;
|
|
35
34
|
var log = settings.log, mode = settings.mode;
|
|
36
35
|
var isAsync = (0, mode_1.isConsumerMode)(mode);
|
|
37
36
|
function getTreatment(key, featureFlagName, attributes, options, withConfig, methodName) {
|
|
@@ -119,13 +118,13 @@ function clientFactory(params) {
|
|
|
119
118
|
var changeNumber = evaluation.changeNumber, impressionsDisabled = evaluation.impressionsDisabled;
|
|
120
119
|
var treatment = evaluation.treatment, label = evaluation.label, _a = evaluation.config, config = _a === void 0 ? null : _a;
|
|
121
120
|
if (treatment === constants_1.CONTROL) {
|
|
122
|
-
var fallbackTreatment =
|
|
121
|
+
var fallbackTreatment = fallbackTreatmentsCalculator(featureFlagName, label);
|
|
123
122
|
treatment = fallbackTreatment.treatment;
|
|
124
123
|
label = fallbackTreatment.label;
|
|
125
124
|
config = fallbackTreatment.config;
|
|
126
125
|
}
|
|
127
|
-
if ((0,
|
|
128
|
-
log.info(constants_2.IMPRESSION_QUEUEING, [
|
|
126
|
+
if ((0, splitExistence_1.validateSplitExistence)(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
127
|
+
log.info(constants_2.IMPRESSION_QUEUEING, [featureFlagName, matchingKey, treatment, label]);
|
|
129
128
|
queue.push({
|
|
130
129
|
imp: {
|
|
131
130
|
feature: featureFlagName,
|
|
@@ -148,7 +147,33 @@ function clientFactory(params) {
|
|
|
148
147
|
}
|
|
149
148
|
return treatment;
|
|
150
149
|
}
|
|
151
|
-
|
|
150
|
+
function track(key, trafficTypeName, eventTypeId, value, properties, size) {
|
|
151
|
+
if (size === void 0) { size = 1024; }
|
|
152
|
+
var stopTelemetryTracker = telemetryTracker.trackEval(constants_1.TRACK);
|
|
153
|
+
var matchingKey = (0, key_1.getMatching)(key);
|
|
154
|
+
var timestamp = Date.now();
|
|
155
|
+
var eventData = {
|
|
156
|
+
eventTypeId: eventTypeId,
|
|
157
|
+
trafficTypeName: trafficTypeName,
|
|
158
|
+
value: value,
|
|
159
|
+
timestamp: timestamp,
|
|
160
|
+
key: matchingKey,
|
|
161
|
+
properties: properties
|
|
162
|
+
};
|
|
163
|
+
// This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
|
|
164
|
+
(0, trafficTypeExistence_1.validateTrafficTypeExistence)(log, readinessManager, storage.splits, mode, trafficTypeName, constants_1.TRACK_FN_LABEL);
|
|
165
|
+
var result = eventTracker.track(eventData, size);
|
|
166
|
+
if ((0, thenable_1.thenable)(result)) {
|
|
167
|
+
return result.then(function (result) {
|
|
168
|
+
stopTelemetryTracker();
|
|
169
|
+
return result;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
stopTelemetryTracker();
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
152
177
|
return {
|
|
153
178
|
getTreatment: getTreatment,
|
|
154
179
|
getTreatmentWithConfig: getTreatmentWithConfig,
|
|
@@ -10,7 +10,7 @@ var splitFilters_1 = require("../utils/settingsValidation/splitFilters");
|
|
|
10
10
|
* Decorator that validates the input before actually executing the client methods.
|
|
11
11
|
* We should "guard" the client here, while not polluting the "real" implementation of those methods.
|
|
12
12
|
*/
|
|
13
|
-
function clientInputValidationDecorator(settings, client, readinessManager,
|
|
13
|
+
function clientInputValidationDecorator(settings, client, readinessManager, fallbackTreatmentsCalculator) {
|
|
14
14
|
var log = settings.log, mode = settings.mode;
|
|
15
15
|
var isAsync = (0, mode_1.isConsumerMode)(mode);
|
|
16
16
|
/**
|
|
@@ -21,12 +21,12 @@ function clientInputValidationDecorator(settings, client, readinessManager, fall
|
|
|
21
21
|
var nameOrNames = methodName.indexOf('ByFlagSet') > -1 ?
|
|
22
22
|
(0, splitFilters_1.validateFlagSets)(log, methodName, maybeNameOrNames, settings.sync.__splitFiltersValidation.groupedFilters.bySet) :
|
|
23
23
|
(0, lang_1.startsWith)(methodName, constants_1.GET_TREATMENTS) ?
|
|
24
|
-
(0, inputValidation_1.
|
|
25
|
-
(0, inputValidation_1.
|
|
24
|
+
(0, inputValidation_1.validateSplits)(log, maybeNameOrNames, methodName) :
|
|
25
|
+
(0, inputValidation_1.validateSplit)(log, maybeNameOrNames, methodName);
|
|
26
26
|
var attributes = (0, inputValidation_1.validateAttributes)(log, maybeAttributes, methodName);
|
|
27
27
|
var isNotDestroyed = (0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, methodName);
|
|
28
28
|
var options = (0, inputValidation_1.validateEvaluationOptions)(log, maybeOptions, methodName);
|
|
29
|
-
(0, inputValidation_1.validateIfReadyFromCache)(log, readinessManager, methodName);
|
|
29
|
+
(0, inputValidation_1.validateIfReadyFromCache)(log, readinessManager, methodName, nameOrNames);
|
|
30
30
|
var valid = isNotDestroyed && key && nameOrNames && attributes !== false;
|
|
31
31
|
return {
|
|
32
32
|
valid: valid,
|
|
@@ -42,7 +42,7 @@ function clientInputValidationDecorator(settings, client, readinessManager, fall
|
|
|
42
42
|
featureFlagName.forEach(function (split) { return res_1[split] = evaluateFallBackTreatment(split, withConfig); });
|
|
43
43
|
return res_1;
|
|
44
44
|
}
|
|
45
|
-
var _a =
|
|
45
|
+
var _a = fallbackTreatmentsCalculator(featureFlagName), treatment = _a.treatment, config = _a.config;
|
|
46
46
|
return withConfig ?
|
|
47
47
|
{
|
|
48
48
|
treatment: treatment,
|
|
@@ -100,6 +100,17 @@ function clientInputValidationDecorator(settings, client, readinessManager, fall
|
|
|
100
100
|
client.getTreatmentsWithConfigByFlagSet(params.key, params.nameOrNames[0], params.attributes, params.options) :
|
|
101
101
|
wrapResult({});
|
|
102
102
|
}
|
|
103
|
+
function track(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties) {
|
|
104
|
+
var key = (0, inputValidation_1.validateKey)(log, maybeKey, constants_1.TRACK_FN_LABEL);
|
|
105
|
+
var tt = (0, inputValidation_1.validateTrafficType)(log, maybeTT, constants_1.TRACK_FN_LABEL);
|
|
106
|
+
var event = (0, inputValidation_1.validateEvent)(log, maybeEvent, constants_1.TRACK_FN_LABEL);
|
|
107
|
+
var eventValue = (0, inputValidation_1.validateEventValue)(log, maybeEventValue, constants_1.TRACK_FN_LABEL);
|
|
108
|
+
var _a = (0, inputValidation_1.validateEventProperties)(log, maybeProperties, constants_1.TRACK_FN_LABEL), properties = _a.properties, size = _a.size;
|
|
109
|
+
var isNotDestroyed = (0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, constants_1.TRACK_FN_LABEL);
|
|
110
|
+
return isNotDestroyed && key && tt && event && eventValue !== false && properties !== false ? // @ts-expect-error
|
|
111
|
+
client.track(key, tt, event, eventValue, properties, size) :
|
|
112
|
+
wrapResult(false);
|
|
113
|
+
}
|
|
103
114
|
return {
|
|
104
115
|
getTreatment: getTreatment,
|
|
105
116
|
getTreatmentWithConfig: getTreatmentWithConfig,
|
|
@@ -109,7 +120,7 @@ function clientInputValidationDecorator(settings, client, readinessManager, fall
|
|
|
109
120
|
getTreatmentsWithConfigByFlagSets: getTreatmentsWithConfigByFlagSets,
|
|
110
121
|
getTreatmentsByFlagSet: getTreatmentsByFlagSet,
|
|
111
122
|
getTreatmentsWithConfigByFlagSet: getTreatmentsWithConfigByFlagSet,
|
|
112
|
-
track:
|
|
123
|
+
track: track
|
|
113
124
|
};
|
|
114
125
|
}
|
|
115
126
|
exports.clientInputValidationDecorator = clientInputValidationDecorator;
|
|
@@ -2,18 +2,75 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.sdkClientFactory = void 0;
|
|
4
4
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
|
+
var apiKey_1 = require("../utils/inputValidation/apiKey");
|
|
5
6
|
var client_1 = require("./client");
|
|
6
7
|
var clientInputValidation_1 = require("./clientInputValidation");
|
|
7
|
-
var
|
|
8
|
+
var COOLDOWN_TIME_IN_MILLIS = 1000;
|
|
8
9
|
/**
|
|
9
10
|
* Creates an Sdk client, i.e., a base client with status, init, flush and destroy interface
|
|
10
11
|
*/
|
|
11
12
|
function sdkClientFactory(params, isSharedClient) {
|
|
12
|
-
var sdkReadinessManager = params.sdkReadinessManager, settings = params.settings;
|
|
13
|
+
var sdkReadinessManager = params.sdkReadinessManager, syncManager = params.syncManager, storage = params.storage, signalListener = params.signalListener, settings = params.settings, telemetryTracker = params.telemetryTracker, impressionsTracker = params.impressionsTracker;
|
|
14
|
+
var hasInit = false;
|
|
15
|
+
var lastActionTime = 0;
|
|
16
|
+
function __cooldown(func, time) {
|
|
17
|
+
var now = Date.now();
|
|
18
|
+
//get the actual time elapsed in ms
|
|
19
|
+
var timeElapsed = now - lastActionTime;
|
|
20
|
+
//check if the time elapsed is less than desired cooldown
|
|
21
|
+
if (timeElapsed < time) {
|
|
22
|
+
//if yes, return message with remaining time in seconds
|
|
23
|
+
settings.log.warn("Flush cooldown, remaining time ".concat((time - timeElapsed) / 1000, " seconds"));
|
|
24
|
+
return Promise.resolve();
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
//Do the requested action and re-assign the lastActionTime
|
|
28
|
+
lastActionTime = now;
|
|
29
|
+
return func();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function __flush() {
|
|
33
|
+
return syncManager ? syncManager.flush() : Promise.resolve();
|
|
34
|
+
}
|
|
13
35
|
return (0, objectAssign_1.objectAssign)(
|
|
14
36
|
// Proto-linkage of the readiness Event Emitter
|
|
15
37
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
16
38
|
// Client API (getTreatment* & track methods)
|
|
17
|
-
(0, clientInputValidation_1.clientInputValidationDecorator)(settings, (0, client_1.clientFactory)(params), sdkReadinessManager.readinessManager, params.
|
|
39
|
+
(0, clientInputValidation_1.clientInputValidationDecorator)(settings, (0, client_1.clientFactory)(params), sdkReadinessManager.readinessManager, params.fallbackTreatmentsCalculator), {
|
|
40
|
+
init: function () {
|
|
41
|
+
if (hasInit)
|
|
42
|
+
return;
|
|
43
|
+
hasInit = true;
|
|
44
|
+
if (!isSharedClient) {
|
|
45
|
+
(0, apiKey_1.validateAndTrackApiKey)(settings.log, settings.core.authorizationKey);
|
|
46
|
+
sdkReadinessManager.readinessManager.init();
|
|
47
|
+
impressionsTracker.start();
|
|
48
|
+
syncManager && syncManager.start();
|
|
49
|
+
signalListener && signalListener.start();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
flush: function () {
|
|
53
|
+
// @TODO define cooldown time
|
|
54
|
+
return __cooldown(__flush, COOLDOWN_TIME_IN_MILLIS);
|
|
55
|
+
},
|
|
56
|
+
destroy: function () {
|
|
57
|
+
hasInit = false;
|
|
58
|
+
// Mark the SDK as destroyed immediately
|
|
59
|
+
sdkReadinessManager.readinessManager.destroy();
|
|
60
|
+
// For main client, cleanup the SDK Key, listeners and scheduled jobs, and record stat before flushing data
|
|
61
|
+
if (!isSharedClient) {
|
|
62
|
+
(0, apiKey_1.releaseApiKey)(settings.core.authorizationKey);
|
|
63
|
+
telemetryTracker.sessionLength();
|
|
64
|
+
signalListener && signalListener.stop();
|
|
65
|
+
impressionsTracker.stop();
|
|
66
|
+
}
|
|
67
|
+
// Stop background jobs
|
|
68
|
+
syncManager && syncManager.stop();
|
|
69
|
+
return __flush().then(function () {
|
|
70
|
+
// Cleanup storage
|
|
71
|
+
return storage.destroy();
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
18
75
|
}
|
|
19
76
|
exports.sdkClientFactory = sdkClientFactory;
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -16,7 +16,7 @@ var fallbackTreatmentsCalculator_1 = require("../evaluator/fallbackTreatmentsCal
|
|
|
16
16
|
* Modular SDK factory
|
|
17
17
|
*/
|
|
18
18
|
function sdkFactory(params) {
|
|
19
|
-
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory,
|
|
19
|
+
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory, lazyInit = params.lazyInit;
|
|
20
20
|
var log = settings.log, initialRolloutPlan = settings.initialRolloutPlan, key = settings.core.key;
|
|
21
21
|
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
|
|
22
22
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
@@ -30,31 +30,35 @@ function sdkFactory(params) {
|
|
|
30
30
|
readiness.timeout();
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
readiness.
|
|
33
|
+
readiness.splits.emit(constants_2.SDK_SPLITS_ARRIVED);
|
|
34
34
|
readiness.segments.emit(constants_2.SDK_SEGMENTS_ARRIVED);
|
|
35
35
|
},
|
|
36
36
|
onReadyFromCacheCb: function () {
|
|
37
|
-
readiness.
|
|
37
|
+
readiness.splits.emit(constants_2.SDK_SPLITS_CACHE_LOADED);
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
|
-
var
|
|
40
|
+
var fallbackTreatmentsCalculator = (0, fallbackTreatmentsCalculator_1.FallbackTreatmentsCalculator)(settings.fallbackTreatments);
|
|
41
41
|
if (initialRolloutPlan) {
|
|
42
42
|
(0, setRolloutPlan_1.setRolloutPlan)(log, initialRolloutPlan, storage, key && (0, key_1.getMatching)(key));
|
|
43
|
-
if (storage.
|
|
44
|
-
readiness.
|
|
43
|
+
if (storage.splits.getChangeNumber() > -1)
|
|
44
|
+
readiness.splits.emit(constants_2.SDK_SPLITS_CACHE_LOADED, { initialCacheLoad: false /* Not an initial load, cache exists */ });
|
|
45
45
|
}
|
|
46
46
|
var clients = {};
|
|
47
47
|
var telemetryTracker = (0, telemetryTracker_1.telemetryTrackerFactory)(storage.telemetry, platform.now);
|
|
48
48
|
var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage, telemetryTracker: telemetryTracker });
|
|
49
49
|
var impressionsTracker = (0, impressionsTracker_1.impressionsTrackerFactory)(params, storage, integrationsManager);
|
|
50
50
|
var eventTracker = (0, eventTracker_1.eventTrackerFactory)(settings, storage.events, integrationsManager, storage.telemetry);
|
|
51
|
-
//
|
|
52
|
-
var
|
|
53
|
-
var ctx = { clients: clients,
|
|
54
|
-
|
|
51
|
+
// splitApi is used by SyncManager and Browser signal listener
|
|
52
|
+
var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
|
|
53
|
+
var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackTreatmentsCalculator: fallbackTreatmentsCalculator };
|
|
54
|
+
var syncManager = syncManagerFactory && syncManagerFactory(ctx);
|
|
55
|
+
ctx.syncManager = syncManager;
|
|
56
|
+
// @TODO: move into platform, and call inside sdkClientFactory (if it's used only there)
|
|
57
|
+
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
58
|
+
ctx.signalListener = signalListener;
|
|
55
59
|
// SDK client and manager
|
|
56
60
|
var clientMethod = sdkClientMethodFactory(ctx);
|
|
57
|
-
var managerInstance = sdkManagerFactory(settings, storage.
|
|
61
|
+
var managerInstance = sdkManagerFactory(settings, storage.splits, sdkReadinessManager);
|
|
58
62
|
function init() {
|
|
59
63
|
Object.keys(clients).map(function (key) { return clients[key].init(); });
|
|
60
64
|
}
|
package/cjs/sdkManager/index.js
CHANGED
|
@@ -53,18 +53,18 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
53
53
|
* Get the feature flag object corresponding to the given feature flag name if valid
|
|
54
54
|
*/
|
|
55
55
|
split: function (featureFlagName) {
|
|
56
|
-
var splitName = (0, inputValidation_1.
|
|
56
|
+
var splitName = (0, inputValidation_1.validateSplit)(log, featureFlagName, constants_1.SPLIT_FN_LABEL);
|
|
57
57
|
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.SPLIT_FN_LABEL) || !splitName) {
|
|
58
58
|
return isAsync ? Promise.resolve(null) : null;
|
|
59
59
|
}
|
|
60
|
-
var split = splits.
|
|
60
|
+
var split = splits.getSplit(splitName);
|
|
61
61
|
if ((0, thenable_1.thenable)(split)) {
|
|
62
62
|
return split.catch(function () { return null; }).then(function (result) {
|
|
63
|
-
(0, inputValidation_1.
|
|
63
|
+
(0, inputValidation_1.validateSplitExistence)(log, readinessManager, splitName, result, constants_1.SPLIT_FN_LABEL);
|
|
64
64
|
return objectToView(result);
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
|
-
(0, inputValidation_1.
|
|
67
|
+
(0, inputValidation_1.validateSplitExistence)(log, readinessManager, splitName, split, constants_1.SPLIT_FN_LABEL);
|
|
68
68
|
return objectToView(split);
|
|
69
69
|
},
|
|
70
70
|
/**
|
|
@@ -86,7 +86,7 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
86
86
|
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.NAMES_FN_LABEL)) {
|
|
87
87
|
return isAsync ? Promise.resolve([]) : [];
|
|
88
88
|
}
|
|
89
|
-
var splitNames = splits.
|
|
89
|
+
var splitNames = splits.getSplitNames();
|
|
90
90
|
return (0, thenable_1.thenable)(splitNames) ?
|
|
91
91
|
splitNames.catch(function () { return []; }) : // handle possible rejections when using pluggable storage
|
|
92
92
|
splitNames;
|
package/cjs/services/splitApi.js
CHANGED
|
@@ -9,9 +9,8 @@ var noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
|
9
9
|
function userKeyToQueryParam(userKey) {
|
|
10
10
|
return 'users=' + encodeURIComponent(userKey); // no need to check availability of `encodeURIComponent`, since it is a global highly supported.
|
|
11
11
|
}
|
|
12
|
-
// @TODO remove when migrating to the new `urls` defaults.
|
|
13
12
|
/**
|
|
14
|
-
* Factory of
|
|
13
|
+
* Factory of SplitApi objects, which group the collection of Split HTTP endpoints used by the SDK
|
|
15
14
|
*
|
|
16
15
|
* @param settings - validated settings object
|
|
17
16
|
* @param platform - object containing environment-specific dependencies
|
|
@@ -126,18 +125,6 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
126
125
|
postMetricsUsage: function (body, headers) {
|
|
127
126
|
var url = "".concat(urls.telemetry, "/v1/metrics/usage");
|
|
128
127
|
return splitHttpClient(url, { method: 'POST', body: body, headers: headers }, telemetryTracker.trackHttp(constants_1.TELEMETRY), true);
|
|
129
|
-
},
|
|
130
|
-
// Not used. Just here to satisfy the IServiceApi interface.
|
|
131
|
-
fetchConfigs: function (since, noCache, till, rbSince) {
|
|
132
|
-
var url = "".concat(urls.configs, "/v1/configs?since=").concat(since).concat(rbSince ? '&rbSince=' + rbSince : '').concat(filterQueryString || '').concat(till ? '&till=' + till : '');
|
|
133
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
|
|
134
|
-
},
|
|
135
|
-
fetchConfigsSegmentChanges: function (since, segmentName, noCache, till) {
|
|
136
|
-
var url = "".concat(urls.configs, "/v1/segmentChanges/").concat(segmentName, "?since=").concat(since).concat(till ? '&till=' + till : '');
|
|
137
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined);
|
|
138
|
-
},
|
|
139
|
-
stop: function () {
|
|
140
|
-
// no-op
|
|
141
128
|
}
|
|
142
129
|
};
|
|
143
130
|
}
|
|
@@ -24,17 +24,19 @@ function splitHttpClientFactory(settings, _a) {
|
|
|
24
24
|
var commonHeaders = {
|
|
25
25
|
'Accept': 'application/json',
|
|
26
26
|
'Content-Type': 'application/json',
|
|
27
|
-
'Authorization': "Bearer ".concat(authorizationKey)
|
|
27
|
+
'Authorization': "Bearer ".concat(authorizationKey),
|
|
28
|
+
'SplitSDKVersion': version
|
|
28
29
|
};
|
|
29
30
|
if (ip)
|
|
30
31
|
commonHeaders['SplitSDKMachineIP'] = ip;
|
|
31
32
|
if (hostname)
|
|
32
33
|
commonHeaders['SplitSDKMachineName'] = (0, decorateHeaders_1.removeNonISO88591)(hostname);
|
|
33
|
-
return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo
|
|
34
|
+
return function httpClient(url, reqOpts, latencyTracker, logErrorsAsInfo) {
|
|
34
35
|
if (reqOpts === void 0) { reqOpts = {}; }
|
|
35
36
|
if (latencyTracker === void 0) { latencyTracker = function () { }; }
|
|
37
|
+
if (logErrorsAsInfo === void 0) { logErrorsAsInfo = false; }
|
|
36
38
|
var request = (0, objectAssign_1.objectAssign)({
|
|
37
|
-
headers: (0, decorateHeaders_1.decorateHeaders)(settings, (0, objectAssign_1.objectAssign)(
|
|
39
|
+
headers: (0, decorateHeaders_1.decorateHeaders)(settings, (0, objectAssign_1.objectAssign)({}, commonHeaders, reqOpts.headers || {})),
|
|
38
40
|
method: reqOpts.method || 'GET',
|
|
39
41
|
body: reqOpts.body
|
|
40
42
|
}, options);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractSplitsCacheAsync = void 0;
|
|
4
|
+
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
|
+
/**
|
|
6
|
+
* This class provides a skeletal implementation of the ISplitsCacheAsync interface
|
|
7
|
+
* to minimize the effort required to implement this interface.
|
|
8
|
+
*/
|
|
9
|
+
var AbstractSplitsCacheAsync = /** @class */ (function () {
|
|
10
|
+
function AbstractSplitsCacheAsync() {
|
|
11
|
+
}
|
|
12
|
+
AbstractSplitsCacheAsync.prototype.update = function (toAdd, toRemove, changeNumber) {
|
|
13
|
+
var _this = this;
|
|
14
|
+
return Promise.all([
|
|
15
|
+
this.setChangeNumber(changeNumber),
|
|
16
|
+
Promise.all(toAdd.map(function (addedFF) { return _this.addSplit(addedFF); })),
|
|
17
|
+
Promise.all(toRemove.map(function (removedFF) { return _this.removeSplit(removedFF.name); }))
|
|
18
|
+
]).then(function (_a) {
|
|
19
|
+
var added = _a[1], removed = _a[2];
|
|
20
|
+
return added.some(function (result) { return result; }) || removed.some(function (result) { return result; });
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
// @TODO revisit segment-related methods ('usesSegments', 'getRegisteredSegments', 'registerSegments')
|
|
24
|
+
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
|
|
25
|
+
AbstractSplitsCacheAsync.prototype.usesSegments = function () {
|
|
26
|
+
return Promise.resolve(true);
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Kill `name` split and set `defaultTreatment` and `changeNumber`.
|
|
30
|
+
* Used for SPLIT_KILL push notifications.
|
|
31
|
+
*
|
|
32
|
+
* @returns a promise that is resolved once the split kill operation is performed. The fulfillment value is a boolean: `true` if the operation successed updating the split or `false` if no split is updated,
|
|
33
|
+
* for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
34
|
+
* The promise will never be rejected.
|
|
35
|
+
*/
|
|
36
|
+
AbstractSplitsCacheAsync.prototype.killLocally = function (name, defaultTreatment, changeNumber) {
|
|
37
|
+
var _this = this;
|
|
38
|
+
return this.getSplit(name).then(function (split) {
|
|
39
|
+
if (split && (!split.changeNumber || split.changeNumber < changeNumber)) {
|
|
40
|
+
var newSplit = (0, objectAssign_1.objectAssign)({}, split);
|
|
41
|
+
newSplit.killed = true;
|
|
42
|
+
newSplit.defaultTreatment = defaultTreatment;
|
|
43
|
+
newSplit.changeNumber = changeNumber;
|
|
44
|
+
return _this.addSplit(newSplit);
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}).catch(function () { return false; });
|
|
48
|
+
};
|
|
49
|
+
return AbstractSplitsCacheAsync;
|
|
50
|
+
}());
|
|
51
|
+
exports.AbstractSplitsCacheAsync = AbstractSplitsCacheAsync;
|